You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
6.5 KiB
TypeScript

// Copyright (C) 2021 Intel Corporation
//
// SPDX-License-Identifier: MIT
import './styles.scss';
import React, { useState, useEffect, useCallback } from 'react';
import Modal from 'antd/lib/modal';
import Notification from 'antd/lib/notification';
import { useSelector, useDispatch } from 'react-redux';
import { DownloadOutlined, LoadingOutlined } from '@ant-design/icons';
import Text from 'antd/lib/typography/Text';
import Select from 'antd/lib/select';
import Checkbox from 'antd/lib/checkbox';
import Input from 'antd/lib/input';
import Form from 'antd/lib/form';
import { CombinedState } from 'reducers/interfaces';
import { exportActions, exportDatasetAsync } from 'actions/export-actions';
import getCore from 'cvat-core-wrapper';
const core = getCore();
type FormValues = {
selectedFormat: string | undefined;
saveImages: boolean;
customName: string | undefined;
};
function ExportDatasetModal(): JSX.Element {
const [instanceType, setInstanceType] = useState('');
const [activities, setActivities] = useState<string[]>([]);
const [form] = Form.useForm();
const dispatch = useDispatch();
const instance = useSelector((state: CombinedState) => state.export.instance);
const modalVisible = useSelector((state: CombinedState) => state.export.modalVisible);
const dumpers = useSelector((state: CombinedState) => state.formats.annotationFormats.dumpers);
const { tasks: taskExportActivities, projects: projectExportActivities } = useSelector(
(state: CombinedState) => state.export,
);
const initActivities = (): void => {
if (instance instanceof core.classes.Project) {
setInstanceType(`project #${instance.id}`);
setActivities(projectExportActivities[instance.id] || []);
} else if (instance) {
const taskID = instance instanceof core.classes.Task ? instance.id : instance.taskId;
setInstanceType(`task #${taskID}`);
setActivities(taskExportActivities[taskID] || []);
if (instance.mode === 'interpolation' && instance.dimension === '2d') {
form.setFieldsValue({ selectedFormat: 'CVAT for video 1.1' });
} else if (instance.mode === 'annotation' && instance.dimension === '2d') {
form.setFieldsValue({ selectedFormat: 'CVAT for images 1.1' });
}
}
};
useEffect(() => {
initActivities();
}, [instance?.id, instance instanceof core.classes.Project, taskExportActivities, projectExportActivities]);
const closeModal = (): void => {
form.resetFields();
dispatch(exportActions.closeExportModal());
};
const handleExport = useCallback(
(values: FormValues): void => {
// have to validate format before so it would not be undefined
dispatch(
exportDatasetAsync(
instance,
values.selectedFormat as string,
values.customName ? `${values.customName}.zip` : '',
values.saveImages,
),
);
closeModal();
Notification.info({
message: 'Dataset export started',
description:
`Dataset export was started for ${instanceType}. ` +
'Download will start automatically as soon as the dataset is ready.',
className: `cvat-notification-notice-export-${instanceType.split(' ')[0]}-start`,
});
},
[instance, instanceType],
);
return (
<Modal
title={`Export ${instanceType} as a dataset`}
visible={modalVisible}
onCancel={closeModal}
onOk={() => form.submit()}
className={`cvat-modal-export-${instanceType.split(' ')[0]}`}
destroyOnClose
>
<Form
name='Export dataset'
form={form}
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
initialValues={
{
selectedFormat: undefined,
saveImages: false,
customName: undefined,
} as FormValues
}
onFinish={handleExport}
>
<Form.Item
name='selectedFormat'
label='Export format'
rules={[{ required: true, message: 'Format must be selected' }]}
>
<Select placeholder='Select dataset format' className='cvat-modal-export-select'>
{dumpers
.sort((a: any, b: any) => a.name.localeCompare(b.name))
.filter((dumper: any): boolean => dumper.dimension === instance?.dimension)
.map(
(dumper: any): JSX.Element => {
const pending = (activities || []).includes(dumper.name);
const disabled = !dumper.enabled || pending;
return (
<Select.Option
value={dumper.name}
key={dumper.name}
disabled={disabled}
className='cvat-modal-export-option-item'
>
<DownloadOutlined />
<Text disabled={disabled}>{dumper.name}</Text>
{pending && <LoadingOutlined style={{ marginLeft: 10 }} />}
</Select.Option>
);
},
)}
</Select>
</Form.Item>
<Form.Item name='saveImages' valuePropName='checked' wrapperCol={{ offset: 8, span: 16 }}>
<Checkbox>Save images</Checkbox>
</Form.Item>
<Form.Item label='Custom name' name='customName'>
<Input
placeholder='Custom name for a dataset'
suffix='.zip'
className='cvat-modal-export-filename-input'
/>
</Form.Item>
</Form>
</Modal>
);
}
export default React.memo(ExportDatasetModal);