Skip to content
Merged

Next #525

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
d91e3b4
Bump motion from 12.23.12 to 12.23.24
dependabot[bot] Oct 20, 2025
b49a868
Bump es-toolkit from 1.39.10 to 1.40.0
dependabot[bot] Oct 20, 2025
8818f9b
Bump prettier-plugin-tailwindcss from 0.6.14 to 0.7.1
dependabot[bot] Oct 20, 2025
aeb7fe0
Bump jsdom from 27.0.0 to 27.0.1
dependabot[bot] Oct 20, 2025
6f0ed76
Merge pull request #508 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 20, 2025
c3b37b3
Merge pull request #506 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 20, 2025
457924d
Merge pull request #505 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 20, 2025
ba302db
Merge pull request #504 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 20, 2025
f407266
Bump knip from 5.63.1 to 5.66.1
dependabot[bot] Oct 20, 2025
def71a9
Merge pull request #507 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 21, 2025
ad70db2
wip network col on table
buckhalt Apr 17, 2025
a33fe36
fix progress sort
buckhalt Apr 17, 2025
eaf0089
sort network by total nodes+edges
buckhalt Apr 17, 2025
df105af
dont redirect to finished if there is a session
buckhalt Apr 17, 2025
7b66db5
handle no nodes or edges
buckhalt Apr 17, 2025
16856d4
increase table width
buckhalt Apr 17, 2025
0d6ec90
manually create node circle, use links svg
buckhalt Apr 17, 2025
e7bf239
add color vars, hard code them
buckhalt Apr 17, 2025
7f518fc
correctly getting css vars as strings
buckhalt Apr 21, 2025
225322e
fix getCSSVariableAsString called before DOM is ready
buckhalt Apr 21, 2025
62721ae
use $ anchor for removing .netcanvas suffix
buckhalt Apr 21, 2025
dee1325
add classNames prop to TimeAgo, remove wrapping it with classes
buckhalt Apr 28, 2025
f920087
NetworkSummary component with correct implementation of dynamic color…
buckhalt Apr 28, 2025
0f45e92
min width for NetworkSummary component
buckhalt Apr 28, 2025
2019c62
use TimeHTMLAttributes for TimeAgo props
buckhalt Apr 30, 2025
d4f1a27
add colors from seq 1 to base classes
buckhalt Apr 30, 2025
87edadc
assert non null for nodeInfo and edgeInfo
buckhalt Apr 30, 2025
865d971
update interviews table skeleton props
buckhalt Apr 30, 2025
4060aa7
fix filterableColumnCount
buckhalt Apr 30, 2025
ff548b7
Merge pull request #510 from complexdatacollective/feature/interview-…
jthrilly Oct 22, 2025
9ba5abd
Bump @typescript-eslint/parser from 8.46.1 to 8.46.2
dependabot[bot] Oct 27, 2025
79c3c21
Bump @paralleldrive/cuid2 from 2.2.2 to 3.1.0
dependabot[bot] Oct 27, 2025
8e285a0
Bump prisma from 6.17.1 to 6.18.0
dependabot[bot] Oct 27, 2025
f4d3ca4
Merge pull request #516 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 28, 2025
2017536
Merge pull request #515 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 28, 2025
e87fecc
Merge pull request #513 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 28, 2025
0bb6d2e
Bump @vitejs/plugin-react from 5.0.4 to 5.1.0
dependabot[bot] Oct 28, 2025
0803381
Merge pull request #512 from complexdatacollective/dependabot/npm_and…
jthrilly Oct 30, 2025
a4e46ac
Bump dotenv from 17.2.2 to 17.2.3
dependabot[bot] Nov 3, 2025
9388163
Bump react-resize-aware from 4.0.0 to 4.1.0
dependabot[bot] Nov 3, 2025
3d60318
Bump react-hook-form from 7.62.0 to 7.66.0
dependabot[bot] Nov 3, 2025
2e26833
Bump @tailwindcss/typography from 0.5.16 to 0.5.19
dependabot[bot] Nov 3, 2025
b5ffbf3
Bump @types/archiver from 6.0.3 to 7.0.0
dependabot[bot] Nov 3, 2025
5eb84bc
Merge pull request #522 from complexdatacollective/dependabot/npm_and…
jthrilly Nov 13, 2025
75cbec6
Merge pull request #521 from complexdatacollective/dependabot/npm_and…
jthrilly Nov 13, 2025
c4178c3
Merge pull request #520 from complexdatacollective/dependabot/npm_and…
jthrilly Nov 13, 2025
118cd39
Merge pull request #519 from complexdatacollective/dependabot/npm_and…
jthrilly Nov 13, 2025
610bdf0
Merge pull request #518 from complexdatacollective/dependabot/npm_and…
jthrilly Nov 13, 2025
4779563
merge package lock
jthrilly Nov 17, 2025
a2334c5
Update build.yml
jthrilly Nov 17, 2025
64a8a45
Merge remote-tracking branch 'origin/next' into claude/fix-knip-typec…
claude Nov 17, 2025
9bcc385
Fix knip and typecheck errors
claude Nov 17, 2025
044aaa5
Remove deprecated ts-lint scripts
claude Nov 17, 2025
41058f2
Merge pull request #526 from complexdatacollective/claude/fix-knip-ty…
jthrilly Nov 17, 2025
73f1b76
version bump
jthrilly Nov 17, 2025
fa7796f
dependency update
jthrilly Nov 17, 2025
ae7c62b
revert some minor deps
jthrilly Nov 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/(interview)/interview/[interviewId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export default async function Page({
redirect('/interview/finished');
}

// If the interview is finished, redirect to the finish page
if (!session && interview?.finishTime) {
// If the interview is finished and there is no session, redirect to the finish page
if (interview?.finishTime && !session) {
redirect('/interview/finished');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Interview } from '@prisma/client';
import type { Row } from '@tanstack/react-table';
import { MoreHorizontal } from 'lucide-react';
import Link from 'next/link';
import { objectHash } from 'ohash';
import { hash as objectHash } from 'ohash';
import { useState } from 'react';
import { DeleteInterviewsDialog } from '~/app/dashboard/interviews/_components/DeleteInterviewsDialog';
import { ExportInterviewsDialog } from '~/app/dashboard/interviews/_components/ExportInterviewsDialog';
Expand Down
112 changes: 70 additions & 42 deletions app/dashboard/_components/InterviewsTable/Columns.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use client';

import type { Codebook, NcNetwork, Stage } from '@codaco/shared-consts';
import { type ColumnDef } from '@tanstack/react-table';
import { Checkbox } from '~/components/ui/checkbox';
import Image from 'next/image';
import { DataTableColumnHeader } from '~/components/DataTable/ColumnHeader';
import { Progress } from '~/components/ui/progress';
import type { Stage } from '@codaco/shared-consts';
import { Badge } from '~/components/ui/badge';
import { Checkbox } from '~/components/ui/checkbox';
import { Progress } from '~/components/ui/progress';
import TimeAgo from '~/components/ui/TimeAgo';
import Image from 'next/image';
import type { GetInterviewsReturnType } from '~/queries/interviews';
import NetworkSummary from './NetworkSummary';

export const InterviewColumns = (): ColumnDef<
Awaited<GetInterviewsReturnType>[0]
Expand All @@ -32,30 +33,24 @@ export const InterviewColumns = (): ColumnDef<
enableSorting: false,
enableHiding: false,
},
// {
// accessorKey: 'id',
// header: ({ column }) => {
// return <DataTableColumnHeader column={column} title="Interview ID" />;
// },
// },
// {
// accessorKey: 'finishTime',
// header: 'Finish Time',
// cell: ({ row }) => {
// // finishTime is optional
// if (!row.original.finishTime) {
// return 'Not completed';
// }
// const date = new Date(row.original.finishTime);
// return date.toLocaleString();
// },
// },
{
id: 'identifier',
accessorKey: 'participant.identifier',
header: ({ column }) => {
return (
<DataTableColumnHeader column={column} title="Participant Identifier" />
<div className="flex items-center gap-2">
<Image
src="/images/participant.svg"
alt="Participant icon"
className="max-w-none"
width={24}
height={24}
/>
<DataTableColumnHeader
column={column}
title="Participant Identifier"
/>
</div>
);
},
cell: ({ row }) => {
Expand All @@ -64,13 +59,6 @@ export const InterviewColumns = (): ColumnDef<
className="flex items-center gap-2"
title={row.original.participant.identifier}
>
<Image
src="/images/participant.svg"
alt="Protocol icon"
className="max-w-none"
width={24}
height={24}
/>
<Badge variant={'outline'}>
<span className="max-w-56 truncate">
{row.original.participant.identifier}
Expand All @@ -81,47 +69,65 @@ export const InterviewColumns = (): ColumnDef<
},
},
{
id: 'protocolName',
accessorKey: 'protocol.name',
header: ({ column }) => {
return <DataTableColumnHeader column={column} title="Protocol Name" />;
return (
<div className="flex items-center gap-2">
<Image
src="/images/protocol-icon.png"
alt="Protocol icon"
className="max-w-none"
width={24}
height={24}
/>
<DataTableColumnHeader column={column} title="Protocol Name" />
</div>
);
},
cell: ({ row }) => {
const protocolFileName = row.original.protocol.name;
const protocolName = protocolFileName.replace(/\.netcanvas$/, '');
return (
<div
className="flex w-full max-w-72 items-center gap-2"
title={row.original.protocol.name}
>
<Image
src="/images/protocol-icon.png"
alt="Protocol icon"
width={32}
height={24}
/>
<span className="truncate">{row.original.protocol.name}</span>
<span className="truncate">{protocolName}</span>
</div>
);
},
},
{
id: 'startTime',
accessorKey: 'startTime',
header: 'Started',
header: ({ column }) => {
return <DataTableColumnHeader column={column} title="Started" />;
},
cell: ({ row }) => {
const date = new Date(row.original.startTime);
return <TimeAgo date={date} />;
return <TimeAgo date={date} className="text-xs" />;
},
},
{
id: 'lastUpdated',
accessorKey: 'lastUpdated',
header: ({ column }) => {
return <DataTableColumnHeader column={column} title="Updated" />;
},
cell: ({ row }) => {
const date = new Date(row.original.lastUpdated);
return <TimeAgo date={date} />;
return <TimeAgo date={date} className="text-xs" />;
},
},
{
id: 'progress',
accessorFn: (row) => {
const stages = row.protocol.stages;
return Array.isArray(stages)
? (row.currentStep / stages.length) * 100
: 0;
},
header: ({ column }) => {
return <DataTableColumnHeader column={column} title="Progress" />;
},
Expand All @@ -136,6 +142,24 @@ export const InterviewColumns = (): ColumnDef<
);
},
},
{
id: 'network',
accessorFn: (row) => {
const network = row.network as NcNetwork;
const nodeCount = network?.nodes?.length ?? 0;
const edgeCount = network?.edges?.length ?? 0;
return nodeCount + edgeCount;
},
header: ({ column }) => {
return <DataTableColumnHeader column={column} title="Network" />;
},
cell: ({ row }) => {
const network = row.original.network as NcNetwork;
const codebook = row.original.protocol.codebook as Codebook;

return <NetworkSummary network={network} codebook={codebook} />;
},
},
{
accessorKey: 'exportTime',
header: ({ column }) => {
Expand All @@ -146,7 +170,11 @@ export const InterviewColumns = (): ColumnDef<
return <Badge variant="secondary">Not exported</Badge>;
}

return <TimeAgo date={row.original.exportTime} />;
return (
<div className="text-xs">
<TimeAgo date={row.original.exportTime} />
</div>
);
},
},
];
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { HardDriveUpload } from 'lucide-react';
import { objectHash } from 'ohash';
import { hash as objectHash } from 'ohash';
import { use, useMemo, useState } from 'react';
import { ActionsDropdown } from '~/app/dashboard/_components/InterviewsTable/ActionsDropdown';
import { InterviewColumns } from '~/app/dashboard/_components/InterviewsTable/Columns';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function InterviewsTableServer() {

return (
<Suspense
fallback={<DataTableSkeleton columnCount={6} filterableColumnCount={2} />}
fallback={<DataTableSkeleton columnCount={7} filterableColumnCount={2} />}
>
<InterviewsTable
interviewsPromise={interviewsPromise}
Expand Down
Loading
Loading