WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 16fa8ca

Browse files
committed
Moved export hook to a separate file
Signed-off-by: Dmitry Kalinin <[email protected]>
1 parent 909d2ff commit 16fa8ca

File tree

3 files changed

+97
-56
lines changed

3 files changed

+97
-56
lines changed

application/ui/src/features/inspect/models/export-model-dialog.component.tsx

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@
33

44
import { useState } from 'react';
55

6-
import { $api, fetchClient } from '@geti-inspect/api';
7-
import { useProjectIdentifier } from '@geti-inspect/hooks';
86
import { Button, ButtonGroup, Content, Dialog, Divider, Flex, Heading, Item, Picker, Text, type Key } from '@geti/ui';
9-
import { useMutation } from '@tanstack/react-query';
107
import type { SchemaCompressionType, SchemaExportType } from 'src/api/openapi-spec';
118
import { Onnx, OpenVino, PyTorch } from 'src/assets/icons';
129

1310
import type { ModelData } from '../../../hooks/utils';
14-
import { useExportStatus } from '../footer/status-bar/adapters/use-export-status';
15-
import { downloadBlob, sanitizeFilename } from '../utils';
1611

1712
import classes from './export-model-dialog.module.scss';
1813

@@ -30,61 +25,21 @@ const COMPRESSION_OPTIONS: { id: SchemaCompressionType | 'none'; name: string }[
3025
{ id: 'int8_acq', name: 'INT8 ACQ' },
3126
];
3227

28+
export interface ExportOptions {
29+
format: SchemaExportType;
30+
formatLabel: string;
31+
compression: SchemaCompressionType | null;
32+
}
33+
3334
interface ExportModelDialogProps {
3435
model: ModelData;
3536
close: () => void;
37+
onExport: (options: ExportOptions) => void;
3638
}
3739

38-
export const ExportModelDialog = ({ model, close }: ExportModelDialogProps) => {
39-
const { projectId } = useProjectIdentifier();
40-
const { data: project } = $api.useSuspenseQuery('get', '/api/projects/{project_id}', {
41-
params: { path: { project_id: projectId } },
42-
});
40+
export const ExportModelDialog = ({ model, close, onExport }: ExportModelDialogProps) => {
4341
const [selectedFormat, setSelectedFormat] = useState<SchemaExportType>('openvino');
4442
const [selectedCompression, setSelectedCompression] = useState<SchemaCompressionType | 'none'>('none');
45-
const { startExport, completeExport } = useExportStatus();
46-
47-
const exportMutation = useMutation({
48-
mutationFn: async () => {
49-
const compression = selectedCompression === 'none' ? null : selectedCompression;
50-
51-
const formatLabel = EXPORT_FORMATS.find((f) => f.id === selectedFormat)?.name ?? selectedFormat;
52-
startExport(model.name, formatLabel);
53-
54-
const response = await fetchClient.POST('/api/projects/{project_id}/models/{model_id}:export', {
55-
params: {
56-
path: {
57-
project_id: projectId,
58-
model_id: model.id,
59-
},
60-
},
61-
body: {
62-
format: selectedFormat,
63-
compression,
64-
},
65-
parseAs: 'blob',
66-
});
67-
68-
if (response.error) {
69-
throw new Error('Export failed');
70-
}
71-
72-
const blob = response.data as Blob;
73-
const compressionSuffix = compression ? `_${compression}` : '';
74-
const sanitizedProjectName = sanitizeFilename(project.name);
75-
const sanitizedModelName = sanitizeFilename(model.name);
76-
const filename = `${sanitizedProjectName}_${sanitizedModelName}_${selectedFormat}${compressionSuffix}.zip`;
77-
78-
return { blob, filename };
79-
},
80-
onSuccess: ({ blob, filename }) => {
81-
completeExport(true);
82-
downloadBlob(blob, filename);
83-
},
84-
onError: () => {
85-
completeExport(false);
86-
},
87-
});
8843

8944
const handleFormatChange = (value: string) => {
9045
const format = value as SchemaExportType;
@@ -101,7 +56,10 @@ export const ExportModelDialog = ({ model, close }: ExportModelDialogProps) => {
10156
};
10257

10358
const handleExport = () => {
104-
exportMutation.mutate();
59+
const formatLabel = EXPORT_FORMATS.find((f) => f.id === selectedFormat)?.name ?? selectedFormat;
60+
const compression = selectedCompression === 'none' ? null : selectedCompression;
61+
62+
onExport({ format: selectedFormat, formatLabel, compression });
10563
close();
10664
};
10765

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { fetchClient } from '@geti-inspect/api';
5+
import { useMutation } from '@tanstack/react-query';
6+
import type { SchemaCompressionType, SchemaExportType } from 'src/api/openapi-spec';
7+
8+
import { useExportStatus } from '../../footer/status-bar/adapters/use-export-status';
9+
import { downloadBlob, sanitizeFilename } from '../../utils';
10+
11+
export interface ExportModelParams {
12+
projectId: string;
13+
projectName: string;
14+
modelId: string;
15+
modelName: string;
16+
format: SchemaExportType;
17+
formatLabel: string;
18+
compression: SchemaCompressionType | null;
19+
}
20+
21+
export const useExportModel = () => {
22+
const { startExport, completeExport } = useExportStatus();
23+
24+
return useMutation({
25+
mutationFn: async (params: ExportModelParams) => {
26+
const { projectId, projectName, modelId, modelName, format, formatLabel, compression } = params;
27+
28+
startExport(modelName, formatLabel);
29+
30+
const response = await fetchClient.POST('/api/projects/{project_id}/models/{model_id}:export', {
31+
params: {
32+
path: {
33+
project_id: projectId,
34+
model_id: modelId,
35+
},
36+
},
37+
body: {
38+
format,
39+
compression,
40+
},
41+
parseAs: 'blob',
42+
});
43+
44+
if (response.error) {
45+
throw new Error('Export failed');
46+
}
47+
48+
const blob = response.data as Blob;
49+
const compressionSuffix = compression ? `_${compression}` : '';
50+
const sanitizedProjectName = sanitizeFilename(projectName);
51+
const sanitizedModelName = sanitizeFilename(modelName);
52+
const filename = `${sanitizedProjectName}_${sanitizedModelName}_${format}${compressionSuffix}.zip`;
53+
54+
return { blob, filename };
55+
},
56+
onSuccess: ({ blob, filename }) => {
57+
completeExport(true);
58+
downloadBlob(blob, filename);
59+
},
60+
onError: () => {
61+
completeExport(false);
62+
},
63+
});
64+
};

application/ui/src/features/inspect/models/model-actions-menu.component.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import { MoreMenu } from '@geti/ui/icons';
77

88
import type { ModelData } from '../../../hooks/utils';
99
import { JobLogsDialog } from '../jobs/show-job-logs.component';
10-
import { ExportModelDialog } from './export-model-dialog.component';
10+
import { ExportModelDialog, type ExportOptions } from './export-model-dialog.component';
11+
import { useExportModel } from './hooks/use-export-model.hook';
1112

1213
interface ModelActionsMenuProps {
1314
model: ModelData;
@@ -18,8 +19,12 @@ type DialogType = 'logs' | 'delete' | 'export' | null;
1819

1920
export const ModelActionsMenu = ({ model, selectedModelId }: ModelActionsMenuProps) => {
2021
const { projectId } = useProjectIdentifier();
22+
const { data: project } = $api.useSuspenseQuery('get', '/api/projects/{project_id}', {
23+
params: { path: { project_id: projectId } },
24+
});
2125
const patchPipeline = usePatchPipeline(projectId);
2226
const [openDialog, setOpenDialog] = useState<DialogType>(null);
27+
const exportModel = useExportModel();
2328

2429
const cancelJobMutation = $api.useMutation('post', '/api/jobs/{job_id}:cancel');
2530
const deleteModelMutation = $api.useMutation('delete', '/api/projects/{project_id}/models/{model_id}', {
@@ -154,7 +159,21 @@ export const ModelActionsMenu = ({ model, selectedModelId }: ModelActionsMenuPro
154159

155160
<DialogContainer onDismiss={() => setOpenDialog(null)}>
156161
{openDialog === 'export' && canExportModel ? (
157-
<ExportModelDialog model={model} close={() => setOpenDialog(null)} />
162+
<ExportModelDialog
163+
model={model}
164+
close={() => setOpenDialog(null)}
165+
onExport={(options: ExportOptions) => {
166+
exportModel.mutate({
167+
projectId,
168+
projectName: project.name,
169+
modelId: model.id,
170+
modelName: model.name,
171+
format: options.format,
172+
formatLabel: options.formatLabel,
173+
compression: options.compression,
174+
});
175+
}}
176+
/>
158177
) : null}
159178
</DialogContainer>
160179
</>

0 commit comments

Comments
 (0)