Skip to content

Commit 9ebf22c

Browse files
authored
Merge pull request #205 from joshunrau/frontend
frontend changes
2 parents 064cb17 + 602b4eb commit 9ebf22c

145 files changed

Lines changed: 7431 additions & 8499 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,6 @@ testemails.txt
143143
# uploaded datasets
144144
*.tsv
145145
*.csv
146-
!demo-dataset.csv
146+
!demo-dataset.csv
147+
148+
.claude

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/dist
2+
/coverage
3+
web/src/route-tree.ts

eslint.config.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import { config } from '@douglasneuroinformatics/eslint-config';
22

3-
export default config({
4-
env: {
5-
browser: true,
6-
es2021: true,
7-
node: true
3+
export default config(
4+
{
5+
env: {
6+
browser: true,
7+
es2021: true,
8+
node: true
9+
},
10+
react: {
11+
enabled: true,
12+
version: '18'
13+
},
14+
typescript: {
15+
enabled: true
16+
}
817
},
9-
react: {
10-
enabled: true,
11-
version: '18'
12-
},
13-
typescript: {
14-
enabled: true
18+
{
19+
rules: {
20+
'@typescript-eslint/consistent-type-definitions': 'off',
21+
'@typescript-eslint/no-empty-object-type': 'off',
22+
'@typescript-eslint/no-namespace': 'off',
23+
'@typescript-eslint/only-throw-error': 'off'
24+
}
1525
}
16-
});
26+
);

pnpm-lock.yaml

Lines changed: 1781 additions & 1948 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/.storybook/main.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ const config: StorybookConfig = {
1010
'@storybook/addon-interactions',
1111
'@storybook/addon-themes'
1212
],
13-
docs: {
14-
autodocs: 'tag'
15-
},
13+
docs: {},
1614
framework: {
1715
name: '@storybook/react-vite',
1816
options: {}

web/package.json

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,47 +19,40 @@
1919
"@douglasneuroinformatics/libjs": "catalog:",
2020
"@douglasneuroinformatics/liblicense": "^1.0.0",
2121
"@douglasneuroinformatics/libpasswd": "^0.0.3",
22-
"@douglasneuroinformatics/libui": "^4.8.0",
23-
"@headlessui/react": "^2.2.0",
24-
"@heroicons/react": "^2.2.0",
25-
"@tanstack/react-query": "^5.71.3",
26-
"@tanstack/react-query-devtools": "^5.71.3",
27-
"@tanstack/react-router": "^1.115.2",
22+
"@douglasneuroinformatics/libui": "^6.2.0",
23+
"@tanstack/react-query": "^5.90.21",
24+
"@tanstack/react-query-devtools": "^5.91.3",
25+
"@tanstack/react-router": "^1.163.2",
2826
"@tanstack/react-table": "^8.21.3",
29-
"@tanstack/zod-adapter": "^1.132.7",
30-
"axios": "^1.8.4",
31-
"framer-motion": "^12.6.3",
32-
"immer": "^10.1.3",
27+
"@tanstack/zod-adapter": "^1.163.2",
28+
"axios": "^1.13.5",
29+
"http-status-codes": "^2.3.0",
30+
"immer": "^11.1.4",
3331
"jwt-decode": "^4.0.0",
34-
"lucide-react": "^0.487.0",
35-
"react": "^19.1.0",
36-
"react-dom": "^19.1.0",
37-
"react-dropzone": "^14.3.8",
38-
"react-error-boundary": "^5.0.0",
39-
"ts-pattern": "^5.7.0",
32+
"lucide-react": "^0.575.0",
33+
"motion": "^12.34.3",
34+
"react": "^19.2.4",
35+
"react-dom": "^19.2.4",
36+
"react-dropzone": "^15.0.0",
37+
"ts-pattern": "^5.9.0",
4038
"usehooks-ts": "^3.1.1",
4139
"zod": "catalog:",
42-
"zustand": "^5.0.3"
40+
"zustand": "^5.0.11"
4341
},
4442
"devDependencies": {
45-
"@douglasneuroinformatics/libui-form-types": "^0.11.0",
46-
"@import-meta-env/unplugin": "^0.6.2",
47-
"@storybook/addon-essentials": "^8.6.11",
48-
"@storybook/addon-interactions": "^8.6.11",
49-
"@storybook/addon-links": "^8.6.11",
50-
"@storybook/addon-themes": "^8.6.11",
51-
"@storybook/react": "^8.6.11",
52-
"@storybook/react-vite": "^8.6.11",
53-
"@tailwindcss/vite": "^4.1.4",
54-
"@tanstack/react-router-devtools": "^1.115.2",
55-
"@tanstack/router-plugin": "^1.115.2",
56-
"@types/react": "^19.1.0",
57-
"@types/react-dom": "^19.1.1",
58-
"@vitejs/plugin-react-swc": "^3.8.1",
59-
"autoprefixer": "^10.4.21",
60-
"postcss": "^8.5.4",
61-
"storybook": "^8.6.11",
62-
"tailwindcss": "^4.1.4",
63-
"vite": "^6.2.4"
43+
"@import-meta-env/unplugin": "^0.6.3",
44+
"@storybook/react-vite": "^9.1.17",
45+
"@tailwindcss/vite": "^4.2.1",
46+
"@tanstack/react-router-devtools": "^1.163.2",
47+
"@tanstack/router-plugin": "^1.163.2",
48+
"@types/react": "^19.2.14",
49+
"@types/react-dom": "^19.2.3",
50+
"@vitejs/plugin-react": "^4.7.0",
51+
"autoprefixer": "^10.4.27",
52+
"postcss": "^8.5.6",
53+
"storybook": "^9.1.17",
54+
"tailwindcss": "^4.2.1",
55+
"type-fest": "catalog:",
56+
"vite": "^6.4.1"
6457
}
6558
}

web/src/App.tsx

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,15 @@
1-
import { Suspense } from 'react';
2-
3-
import { CoreProvider } from '@douglasneuroinformatics/libui/providers';
41
import { QueryClientProvider } from '@tanstack/react-query';
5-
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
6-
import { createRouter, RouterProvider } from '@tanstack/react-router';
7-
import { ErrorBoundary } from 'react-error-boundary';
8-
9-
import { LoadingFallback } from './components';
10-
import { ErrorPage } from './components/ErrorPage.js';
11-
// Import the generated route tree
12-
import { routeTree } from './routeTree.gen';
13-
import { queryClient } from './services/react-query.js';
2+
import { RouterProvider } from '@tanstack/react-router';
143

15-
// Create a new router instance
16-
const router = createRouter({
17-
defaultPendingComponent: LoadingFallback,
18-
routeTree
19-
});
4+
import { router } from './router';
5+
import { queryClient } from './services/react-query';
206

21-
// Register the router instance for type safety
22-
declare module '@tanstack/react-router' {
23-
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
24-
interface Register {
25-
router: typeof router;
26-
}
27-
}
7+
import './styles.css';
288

299
export const App = () => {
3010
return (
31-
<Suspense fallback={<LoadingFallback />}>
32-
<ErrorBoundary FallbackComponent={ErrorPage}>
33-
<QueryClientProvider client={queryClient}>
34-
<CoreProvider>
35-
<RouterProvider router={router} />
36-
</CoreProvider>
37-
<ReactQueryDevtools />
38-
</QueryClientProvider>
39-
</ErrorBoundary>
40-
</Suspense>
11+
<QueryClientProvider client={queryClient}>
12+
<RouterProvider router={router} />
13+
</QueryClientProvider>
4114
);
4215
};

web/src/features/auth/components/AuthLayout.tsx renamed to web/src/components/AuthLayout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Card, Heading, LanguageToggle, ThemeToggle } from '@douglasneuroinforma
22
import { cn } from '@douglasneuroinformatics/libui/utils';
33
import { Link } from '@tanstack/react-router';
44

5-
import { Logo } from '@/components';
5+
import { Logo } from '@/components/Logo';
66

77
type AuthLayoutProps = {
88
children: React.ReactNode;
@@ -13,7 +13,7 @@ type AuthLayoutProps = {
1313
export const AuthLayout = ({ children, maxWidth, title }: AuthLayoutProps) => {
1414
return (
1515
<div className="flex min-h-screen w-full flex-col">
16-
<div className="flex w-full flex-grow flex-col items-center justify-center">
16+
<div className="flex w-full grow flex-col items-center justify-center">
1717
<Card
1818
className={cn(
1919
'sm:bg-card w-full border-none bg-inherit px-2.5 py-1.5 sm:border-solid',
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { $DatasetViewPagination } from '@databank/core';
2+
import { ActionDropdown, Button } from '@douglasneuroinformatics/libui/components';
3+
import { useTranslation } from '@douglasneuroinformatics/libui/hooks';
4+
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
5+
6+
type DatasetPaginationProps = {
7+
currentPage: number;
8+
itemsPerPage: number;
9+
kind: 'COLUMN' | 'ROW';
10+
setDatasetPagination: (newPaginationDto: $DatasetViewPagination) => void;
11+
totalNumberOfItems: number;
12+
};
13+
14+
export const DatasetPagination = ({
15+
currentPage,
16+
itemsPerPage,
17+
kind,
18+
setDatasetPagination,
19+
totalNumberOfItems
20+
}: DatasetPaginationProps) => {
21+
const { t } = useTranslation('common');
22+
const totalNumberOfPage = Math.ceil(totalNumberOfItems / itemsPerPage);
23+
24+
const handleSelectPageOption = (options: string) => {
25+
switch (options) {
26+
case '10':
27+
setDatasetPagination({ currentPage: 1, itemsPerPage: 10 });
28+
break;
29+
case '20':
30+
setDatasetPagination({ currentPage: 1, itemsPerPage: 20 });
31+
break;
32+
case '50':
33+
setDatasetPagination({ currentPage: 1, itemsPerPage: 50 });
34+
break;
35+
case '100':
36+
setDatasetPagination({ currentPage: 1, itemsPerPage: 100 });
37+
break;
38+
case 'All':
39+
setDatasetPagination({ currentPage: 1, itemsPerPage: totalNumberOfItems });
40+
break;
41+
}
42+
};
43+
44+
return (
45+
<div className="flex items-center justify-between border-t py-3">
46+
<p className="text-muted-foreground hidden text-sm sm:block">
47+
{kind === 'COLUMN' ? t('columnPagination') : t('rowPagination')}
48+
</p>
49+
<div className="flex flex-1 items-center justify-end gap-2">
50+
<ActionDropdown
51+
options={['10', '20', '50', '100', 'All']}
52+
title={(kind === 'COLUMN' ? t('columnsPerPage') : t('rowsPerPage')).concat(`: ${itemsPerPage}`)}
53+
onSelection={(options) => handleSelectPageOption(options)}
54+
/>
55+
<p className="text-muted-foreground text-sm tabular-nums">
56+
{currentPage} / {totalNumberOfPage}
57+
</p>
58+
<Button
59+
disabled={currentPage === 1}
60+
size="sm"
61+
type="button"
62+
variant="outline"
63+
onClick={() => setDatasetPagination({ currentPage: currentPage - 1, itemsPerPage })}
64+
>
65+
<ChevronLeftIcon className="size-4" />
66+
</Button>
67+
<Button
68+
disabled={currentPage === totalNumberOfPage}
69+
size="sm"
70+
type="button"
71+
variant="outline"
72+
onClick={() => setDatasetPagination({ currentPage: currentPage + 1, itemsPerPage })}
73+
>
74+
<ChevronRightIcon className="size-4" />
75+
</Button>
76+
</div>
77+
</div>
78+
);
79+
};

0 commit comments

Comments
 (0)