Skip to content

Commit be6fe07

Browse files
chore(inspect): minor UI improvements (#3040)
* Improve query client * Add a welcome screen * Invalidate projects after creating a new project * Fix grid spacing * Invalidate only after all items are uploaded Via open-edge-platform/training_extensions#4905 Co-authored-by: João Vilaça <joao.vilaca@intel.com> * Render toast messages * Move toast into router provider This allows us to render components that rely on router contexts such as useParams * Set font family for sonner * Fix lint * Fix cyclic dependencies --------- Co-authored-by: João Vilaça <joao.vilaca@intel.com>
1 parent 6ddb323 commit be6fe07

File tree

18 files changed

+323
-169
lines changed

18 files changed

+323
-169
lines changed
Lines changed: 44 additions & 0 deletions
Loading

application/ui/src/assets/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ export { ReactComponent as VideoFile } from './video-file.svg';
1919
export { ReactComponent as Webcam } from './webcam.svg';
2020
export { ReactComponent as Webhook } from './webhook.svg';
2121
export { ReactComponent as Image } from './image.svg';
22+
export { ReactComponent as Fireworks } from './fire-works.svg';

application/ui/src/components/error-page/error-page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Button, Heading, IllustratedMessage, View } from '@geti/ui';
55
import { NotFound } from '@geti/ui/icons';
66
import { isRouteErrorResponse, useRouteError } from 'react-router';
77

8-
import { paths } from '../../router';
8+
import { paths } from '../../routes/paths';
99
import { redirectTo } from '../../routes/utils';
1010

1111
const useErrorMessage = () => {

application/ui/src/components/notification/notification.component.tsx

Lines changed: 0 additions & 61 deletions
This file was deleted.

application/ui/src/components/notification/notification.module.scss

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Grid, Heading, minmax, repeat } from '@geti/ui';
1+
import { Flex, Grid, Heading, minmax, repeat } from '@geti/ui';
22

33
import { DatasetItemContainer } from './dataset-item/dataset-item.component';
44
import { MediaItem } from './types';
@@ -17,17 +17,20 @@ export const DatasetList = ({ mediaItems }: DatasetItemProps) => {
1717
];
1818

1919
return (
20-
<Grid
21-
flex={1}
22-
columns={repeat('auto-fill', minmax('size-1600', '1fr'))}
23-
rows={['max-content', '1fr']}
24-
gap={'size-100'}
25-
alignContent={'start'}
26-
>
27-
<Heading gridColumn={'1/-1'}>Normal images</Heading>
28-
{mediaItemsToRender.map((mediaItem, index) => (
29-
<DatasetItemContainer key={mediaItem?.id ?? index} mediaItem={mediaItem} />
30-
))}
31-
</Grid>
20+
<Flex gap='size-200' direction={'column'}>
21+
<Heading>Normal images</Heading>
22+
23+
<Grid
24+
flex={1}
25+
columns={repeat('auto-fill', minmax('size-1600', '1fr'))}
26+
rows={['max-content', '1fr']}
27+
gap={'size-100'}
28+
alignContent={'start'}
29+
>
30+
{mediaItemsToRender.map((mediaItem, index) => (
31+
<DatasetItemContainer key={mediaItem?.id ?? index} mediaItem={mediaItem} />
32+
))}
33+
</Grid>
34+
</Flex>
3235
);
3336
};

application/ui/src/features/inspect/dataset/dataset.component.tsx

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { Suspense } from 'react';
22

33
import { $api } from '@geti-inspect/api';
44
import { useProjectIdentifier } from '@geti-inspect/hooks';
5-
import { Button, Divider, FileTrigger, Flex, Heading, Loading, View } from '@geti/ui';
5+
import { Button, Divider, FileTrigger, Flex, Heading, Loading, toast, View } from '@geti/ui';
6+
import { useQueryClient } from '@tanstack/react-query';
67

78
import { DatasetList } from './dataset-list.component';
89
import { DatasetStatusPanel } from './dataset-status-panel.component';
@@ -25,28 +26,47 @@ const useMediaItems = () => {
2526

2627
const UploadImages = () => {
2728
const { projectId } = useProjectIdentifier();
29+
const queryClient = useQueryClient();
2830

2931
const captureImageMutation = $api.useMutation('post', '/api/projects/{project_id}/capture');
3032

31-
const captureImage = (file: File) => {
32-
const formData = new FormData();
33-
formData.append('file', file);
34-
35-
captureImageMutation.mutate({
36-
// @ts-expect-error There is an incorrect type in OpenAPI
37-
body: formData,
38-
params: {
39-
path: {
40-
project_id: projectId,
41-
},
42-
},
33+
const handleAddMediaItem = async (files: File[]) => {
34+
const uploadPromises = files.map((file) => {
35+
const formData = new FormData();
36+
formData.append('file', file);
37+
38+
return captureImageMutation.mutateAsync({
39+
params: { path: { project_id: projectId } },
40+
// @ts-expect-error There is an incorrect type in OpenAPI
41+
body: formData,
42+
});
4343
});
44+
45+
const promises = await Promise.allSettled(uploadPromises);
46+
47+
const succeeded = promises.filter((result) => result.status === 'fulfilled').length;
48+
const failed = promises.filter((result) => result.status === 'rejected').length;
49+
50+
await queryClient.invalidateQueries({
51+
queryKey: ['get', '/api/projects/{project_id}/images'],
52+
});
53+
54+
if (failed === 0) {
55+
toast({ type: 'success', message: `Uploaded ${succeeded} item(s)` });
56+
} else if (succeeded === 0) {
57+
toast({ type: 'error', message: `Failed to upload ${failed} item(s)` });
58+
} else {
59+
toast({
60+
type: 'warning',
61+
message: `Uploaded ${succeeded} item(s), ${failed} failed`,
62+
});
63+
}
4464
};
4565

4666
const captureImages = (files: FileList | null) => {
4767
if (files === null) return;
4868

49-
Array.from(files).forEach((file) => captureImage(file));
69+
handleAddMediaItem(Array.from(files));
5070
};
5171

5272
return (

application/ui/src/features/inspect/projects-management/project-list-item/project-list-item.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { SchemaProjectList } from '@geti-inspect/api/spec';
99
import { Flex, PhotoPlaceholder, Text, TextField, type TextFieldRef } from '@geti/ui';
1010
import { useNavigate } from 'react-router';
1111

12-
import { paths } from '../../../../router';
12+
import { paths } from '../../../../routes/paths';
1313

1414
import styles from './project-list-item.module.scss';
1515

application/ui/src/features/inspect/projects-management/projects-list-panel.component.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ interface AddProjectProps {
5050
}
5151

5252
const AddProjectButton = ({ onSetProjectInEdition, projectsCount }: AddProjectProps) => {
53-
const addProjectMutation = $api.useMutation('post', '/api/projects');
53+
const addProjectMutation = $api.useMutation('post', '/api/projects', {
54+
meta: {
55+
invalidates: [['get', '/api/projects']],
56+
},
57+
});
5458

5559
const addProject = () => {
5660
const newProjectId = uuid();

application/ui/src/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,7 @@ a {
8080
svg {
8181
fill: currentColor;
8282
}
83+
84+
[data-sonner-toaster] {
85+
font-family: var(--spectrum-global-font-family-base) !important;
86+
}

0 commit comments

Comments
 (0)