diff --git a/CHANGELOG.md b/CHANGELOG.md index 4667cb9b4e7ceccc58763c9ab79b85393270c73f..5218e7f71b83da42505f5782c2e022cbeb411b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cloud storage content listing when the manifest name contains special characters () - Width and height in CVAT dataset format mask annotations () +- Empty list of export formats for a project without tasks () ### Security - TDB diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 786d91bc4b47062092dd3f6114d88aa6aed20315..2d8c4bdd79f15519f5dd2b18691729bcfc609472 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.50.1", + "version": "1.50.2", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { diff --git a/cvat-ui/src/components/export-dataset/export-dataset-modal.tsx b/cvat-ui/src/components/export-dataset/export-dataset-modal.tsx index 675796fd306cc171bf56702488a350cdcf26f1c7..19d5b47060466850a91eb41b1239ba54ef0825c1 100644 --- a/cvat-ui/src/components/export-dataset/export-dataset-modal.tsx +++ b/cvat-ui/src/components/export-dataset/export-dataset-modal.tsx @@ -1,5 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation -// Copyright (C) 2022 CVAT.ai Corporation +// Copyright (C) 2022-2023 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -18,7 +18,10 @@ import Space from 'antd/lib/space'; import TargetStorageField from 'components/storage/target-storage-field'; import { CombinedState, StorageLocation } from 'reducers'; import { exportActions, exportDatasetAsync } from 'actions/export-actions'; -import { getCore, Storage, StorageData } from 'cvat-core-wrapper'; +import { + Dumper, + getCore, Job, Project, Storage, StorageData, Task, +} from 'cvat-core-wrapper'; const core = getCore(); @@ -56,15 +59,15 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { location: StorageLocation.LOCAL, }); const [defaultStorageLocation, setDefaultStorageLocation] = useState(StorageLocation.LOCAL); - const [defaultStorageCloudId, setDefaultStorageCloudId] = useState(null); + const [defaultStorageCloudId, setDefaultStorageCloudId] = useState(); const [helpMessage, setHelpMessage] = useState(''); const dispatch = useDispatch(); useEffect(() => { - if (instance instanceof core.classes.Project) { + if (instance instanceof Project) { setInstanceType(`project #${instance.id}`); - } else if (instance instanceof core.classes.Task || instance instanceof core.classes.Job) { - if (instance instanceof core.classes.Task) { + } else if (instance instanceof Task || instance instanceof Job) { + if (instance instanceof Task) { setInstanceType(`task #${instance.id}`); } else { setInstanceType(`job #${instance.id}`); @@ -79,16 +82,16 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { useEffect(() => { if (instance) { - if (instance instanceof core.classes.Project || instance instanceof core.classes.Task) { + if (instance instanceof Project || instance instanceof Task) { setDefaultStorageLocation(instance.targetStorage?.location || StorageLocation.LOCAL); - setDefaultStorageCloudId(instance.targetStorage?.cloudStorageId || null); + setDefaultStorageCloudId(instance.targetStorage?.cloudStorageId); } else { core.tasks.get({ id: instance.taskId }) .then((response: any) => { if (response.length) { const [taskInstance] = response; setDefaultStorageLocation(taskInstance.targetStorage?.location || StorageLocation.LOCAL); - setDefaultStorageCloudId(taskInstance.targetStorage?.cloudStorageId || null); + setDefaultStorageCloudId(taskInstance.targetStorage?.cloudStorageId); } }) .catch((error: Error) => { @@ -104,7 +107,6 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { }, [instance]); useEffect(() => { - // eslint-disable-next-line prefer-template setHelpMessage(`Export to ${(defaultStorageLocation) ? defaultStorageLocation.split('_')[0] : 'local'} ` + `storage ${(defaultStorageCloudId) ? `№${defaultStorageCloudId}` : ''}`); }, [defaultStorageLocation, defaultStorageCloudId]); @@ -129,7 +131,7 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { location: defaultStorageLocation, cloudStorageId: defaultStorageCloudId, }) : new Storage(targetStorage), - values.customName ? `${values.customName}.zip` : null, + values.customName ? `${values.customName}.zip` : undefined, ), ); closeModal(); @@ -168,10 +170,13 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { > - + Save images @@ -206,7 +215,7 @@ function ExportDatasetModal(props: StateToProps): JSX.Element { /> { diff --git a/cvat-ui/src/cvat-core-wrapper.ts b/cvat-ui/src/cvat-core-wrapper.ts index fb51b4705dad98272e00fd526c8f2219f2e05df4..d36432d18eca985c249bf9bd16aa8bd512882ecc 100644 --- a/cvat-ui/src/cvat-core-wrapper.ts +++ b/cvat-ui/src/cvat-core-wrapper.ts @@ -22,6 +22,7 @@ import Issue from 'cvat-core/src/issue'; import Comment from 'cvat-core/src/comment'; import User from 'cvat-core/src/user'; import Organization from 'cvat-core/src/organization'; +import { Dumper } from 'cvat-core/src/annotation-formats'; const cvat: any = _cvat; @@ -55,6 +56,7 @@ export { ModelProviders, ModelReturnType, DimensionType, + Dumper, }; export type { diff --git a/tests/cypress/e2e/issues_prs/issue_5381_empty_project_formats.js b/tests/cypress/e2e/issues_prs/issue_5381_empty_project_formats.js new file mode 100644 index 0000000000000000000000000000000000000000..a751b41d103c99a72454a09439da2a4e0ae4e1cb --- /dev/null +++ b/tests/cypress/e2e/issues_prs/issue_5381_empty_project_formats.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 CVAT.ai Corporation +// +// SPDX-License-Identifier: MIT + +/// + +const issueId = '5381'; +const project = { + name: `Issue ${issueId}`, + label: 'Tree', + attrName: 'Kind', + attrVaue: 'Oak', +}; + +context('List of export formats for a project without tasks is not empty', () => { + before(() => { + cy.visit('auth/login'); + cy.login(); + cy.goToProjectsList(); + cy.createProjects(project.name, project.label, project.attrName, project.attrVaue); + cy.goToProjectsList(); + }); + + describe(`Testing issue "${issueId}"`, () => { + it('Export formats list is not empty for empty project', () => { + cy.projectActions(project.name); + cy.get('.cvat-project-actions-menu').contains('Export dataset').click(); + cy.get('.cvat-modal-export-project').should('be.visible').find('.cvat-modal-export-select').click(); + cy.get('.cvat-modal-export-option-item').should('have.length.above', 0); + }); + }); +});