From 3d8f3c6f0b9bee0cf1c8a66df5fc555a84cfe77f Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Fri, 8 Jan 2021 19:11:25 +0300 Subject: [PATCH 001/194] Update CHANGELOG and bump the server version till 1.3.0-alpha --- CHANGELOG.md | 19 +++++++++++++++++++ cvat/__init__.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b7d6452..d1554355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.3.0-alpha] - Unreleased +### Added +- + +### Changed +- + +### Deprecated +- + +### Removed +- + +### Fixed +- + +### Security +- + ## [1.2.0] - 2020-01-08 ### Fixed diff --git a/cvat/__init__.py b/cvat/__init__.py index 625c22d9..7038e6ec 100644 --- a/cvat/__init__.py +++ b/cvat/__init__.py @@ -4,6 +4,6 @@ from cvat.utils.version import get_version -VERSION = (1, 2, 0, 'final', 0) +VERSION = (1, 3, 0, 'alpha', 0) __version__ = get_version(VERSION) From 069fadc053aa5c8d4676a9696753818f5db1db36 Mon Sep 17 00:00:00 2001 From: manasars <44188718+manasars@users.noreply.github.com> Date: Fri, 8 Jan 2021 23:12:10 +0530 Subject: [PATCH 002/194] CVAT-3D: support lidar data on the server side (#2534) * CVAT-3D Updated the Mime Types with Bin Support, added dependency of open3D * CVAT-3D Added additional column as Dimension for engine_task table and created a relatedfiles table for PCD to Image mapping. * Added Support for 3D file Upload in BIN and PCD. * Added Dimension attribute defaulting to 2D for importer and exporter. * Added props passing for dimension attribute, filtering of import, Migration Scripts and Dimension attribute for MpegChunk Writers Co-authored-by: cdp --- Dockerfile | 2 + cvat-core/src/annotation-formats.js | 22 ++ cvat-core/src/api-implementation.js | 5 +- cvat-core/src/enums.js | 15 ++ cvat-core/src/session.js | 11 + .../components/actions-menu/actions-menu.tsx | 7 +- .../components/actions-menu/dump-submenu.tsx | 7 +- .../actions-menu/export-submenu.tsx | 7 +- .../components/actions-menu/load-submenu.tsx | 5 +- .../top-bar/annotation-menu.tsx | 3 + .../model-runner-modal/detector-runner.tsx | 4 +- .../containers/actions-menu/actions-menu.tsx | 1 + cvat-ui/src/reducers/interfaces.ts | 5 + cvat/apps/dataset_manager/formats/registry.py | 14 +- cvat/apps/dataset_manager/serializers.py | 3 +- cvat/apps/engine/assets/3d_preview.jpeg | Bin 0 -> 247293 bytes cvat/apps/engine/cache.py | 9 +- cvat/apps/engine/frame_provider.py | 6 +- cvat/apps/engine/media.mimetypes | 3 +- cvat/apps/engine/media_extractors.py | 222 +++++++++++++++++- .../migrations/0036_auto_20201216_0943.py | 33 +++ cvat/apps/engine/models.py | 23 ++ cvat/apps/engine/serializers.py | 4 +- cvat/apps/engine/task.py | 51 +++- .../tests/assets/test_pointcloud_pcd.zip | Bin 0 -> 2606 bytes .../tests/assets/test_velodyne_points.zip | Bin 0 -> 2992 bytes cvat/apps/engine/tests/test_rest_api.py | 124 +++++++++- cvat/apps/engine/views.py | 2 +- cvat/requirements/base.txt | 1 + 29 files changed, 543 insertions(+), 46 deletions(-) create mode 100644 cvat/apps/engine/assets/3d_preview.jpeg create mode 100644 cvat/apps/engine/migrations/0036_auto_20201216_0943.py create mode 100644 cvat/apps/engine/tests/assets/test_pointcloud_pcd.zip create mode 100644 cvat/apps/engine/tests/assets/test_velodyne_points.zip diff --git a/Dockerfile b/Dockerfile index 2ce2cd35..93233393 100644 --- a/Dockerfile +++ b/Dockerfile @@ -73,6 +73,8 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -yq \ apache2 \ libapache2-mod-xsendfile \ + libgomp1 \ + libgl1 \ supervisor \ libldap-2.4-2 \ libsasl2-2 \ diff --git a/cvat-core/src/annotation-formats.js b/cvat-core/src/annotation-formats.js index 795c9863..0bad3b7f 100644 --- a/cvat-core/src/annotation-formats.js +++ b/cvat-core/src/annotation-formats.js @@ -15,6 +15,7 @@ format: initialData.ext, version: initialData.version, enabled: initialData.enabled, + dimension: initialData.dimension, }; Object.defineProperties(this, { @@ -58,6 +59,16 @@ */ get: () => data.enabled, }, + dimension: { + /** + * @name dimension + * @type {string} + * @memberof module:API.cvat.enums.DimensionType + * @readonly + * @instance + */ + get: () => data.dimension, + }, }); } } @@ -74,6 +85,7 @@ format: initialData.ext, version: initialData.version, enabled: initialData.enabled, + dimension: initialData.dimension, }; Object.defineProperties(this, { @@ -117,6 +129,16 @@ */ get: () => data.enabled, }, + dimension: { + /** + * @name dimension + * @type {string} + * @memberof module:API.cvat.enums.DimensionType + * @readonly + * @instance + */ + get: () => data.dimension, + }, }); } } diff --git a/cvat-core/src/api-implementation.js b/cvat-core/src/api-implementation.js index f3e2aa26..1d2dbff5 100644 --- a/cvat-core/src/api-implementation.js +++ b/cvat-core/src/api-implementation.js @@ -10,7 +10,7 @@ isBoolean, isInteger, isEnum, isString, checkFilter, } = require('./common'); - const { TaskStatus, TaskMode } = require('./enums'); + const { TaskStatus, TaskMode, DimensionType } = require('./enums'); const User = require('./user'); const { AnnotationFormats } = require('./annotation-formats'); @@ -176,6 +176,7 @@ search: isString, status: isEnum.bind(TaskStatus), mode: isEnum.bind(TaskMode), + dimension: isEnum.bind(DimensionType), }); if ('search' in filter && Object.keys(filter).length > 1) { @@ -198,7 +199,7 @@ } const searchParams = new URLSearchParams(); - for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page', 'projectId']) { + for (const field of ['name', 'owner', 'assignee', 'search', 'status', 'mode', 'id', 'page', 'projectId', 'dimension']) { if (Object.prototype.hasOwnProperty.call(filter, field)) { searchParams.set(field, filter[field]); } diff --git a/cvat-core/src/enums.js b/cvat-core/src/enums.js index 107bc86f..4ce6d80c 100644 --- a/cvat-core/src/enums.js +++ b/cvat-core/src/enums.js @@ -33,6 +33,20 @@ COMPLETED: 'completed', }); + /** + * Task dimension + * @enum + * @name DimensionType + * @memberof module:API.cvat.enums + * @property {string} DIMENSION_2D '2d' + * @property {string} DIMENSION_3D '3d' + * @readonly + */ + const DimensionType = Object.freeze({ + DIMENSION_2D: '2d', + DIMENSION_3D: '3d', + }); + /** * Review statuses * @enum {string} @@ -333,5 +347,6 @@ RQStatus, colors, Source, + DimensionType, }; })(); diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js index 19bc32df..5b6aa41f 100644 --- a/cvat-core/src/session.js +++ b/cvat-core/src/session.js @@ -974,6 +974,7 @@ use_zip_chunks: undefined, use_cache: undefined, copy_data: undefined, + dimension: undefined, }; let updatedFields = { @@ -1452,6 +1453,16 @@ updatedFields = fields; }, }, + dimension: { + /** + * @name enabled + * @type {string} + * @memberof module:API.cvat.enums.DimensionType + * @readonly + * @instance + */ + get: () => data.dimension, + }, }), ); diff --git a/cvat-ui/src/components/actions-menu/actions-menu.tsx b/cvat-ui/src/components/actions-menu/actions-menu.tsx index 723bf68e..644f2945 100644 --- a/cvat-ui/src/components/actions-menu/actions-menu.tsx +++ b/cvat-ui/src/components/actions-menu/actions-menu.tsx @@ -11,6 +11,7 @@ import { MenuInfo } from 'rc-menu/lib/interface'; import DumpSubmenu from './dump-submenu'; import LoadSubmenu from './load-submenu'; import ExportSubmenu from './export-submenu'; +import { DimensionType } from '../../reducers/interfaces'; interface Props { taskID: number; @@ -22,7 +23,7 @@ interface Props { dumpActivities: string[] | null; exportActivities: string[] | null; inferenceIsActive: boolean; - + taskDimension: DimensionType; onClickMenu: (params: MenuInfo, file?: File) => void; } @@ -47,6 +48,7 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { dumpActivities, exportActivities, loadActivity, + taskDimension, } = props; let latestParams: MenuInfo | null = null; @@ -102,6 +104,7 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { dumpers, dumpActivities, menuKey: Actions.DUMP_TASK_ANNO, + taskDimension, })} {LoadSubmenu({ loaders, @@ -110,11 +113,13 @@ export default function ActionsMenuComponent(props: Props): JSX.Element { onClickMenuWrapper(null, file); }, menuKey: Actions.LOAD_TASK_ANNO, + taskDimension, })} {ExportSubmenu({ exporters: dumpers, exportActivities, menuKey: Actions.EXPORT_TASK_DATASET, + taskDimension, })} {!!bugTracker && Open bug tracker} diff --git a/cvat-ui/src/components/actions-menu/dump-submenu.tsx b/cvat-ui/src/components/actions-menu/dump-submenu.tsx index 5f71273f..91721ac6 100644 --- a/cvat-ui/src/components/actions-menu/dump-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/dump-submenu.tsx @@ -6,6 +6,7 @@ import React from 'react'; import Menu from 'antd/lib/menu'; import { DownloadOutlined, LoadingOutlined } from '@ant-design/icons'; import Text from 'antd/lib/typography/Text'; +import { DimensionType } from '../../reducers/interfaces'; function isDefaultFormat(dumperName: string, taskMode: string): boolean { return ( @@ -19,15 +20,19 @@ interface Props { menuKey: string; dumpers: any[]; dumpActivities: string[] | null; + taskDimension: DimensionType; } export default function DumpSubmenu(props: Props): JSX.Element { - const { taskMode, menuKey, dumpers, dumpActivities } = props; + const { + taskMode, menuKey, dumpers, dumpActivities, taskDimension, + } = props; return ( {dumpers .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .filter((dumper: any): boolean => dumper.dimension === taskDimension) .map( (dumper: any): JSX.Element => { const pending = (dumpActivities || []).includes(dumper.name); diff --git a/cvat-ui/src/components/actions-menu/export-submenu.tsx b/cvat-ui/src/components/actions-menu/export-submenu.tsx index 28affd5f..68356500 100644 --- a/cvat-ui/src/components/actions-menu/export-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/export-submenu.tsx @@ -6,20 +6,25 @@ import React from 'react'; import Menu from 'antd/lib/menu'; import Text from 'antd/lib/typography/Text'; import { ExportOutlined, LoadingOutlined } from '@ant-design/icons'; +import { DimensionType } from '../../reducers/interfaces'; interface Props { menuKey: string; exporters: any[]; exportActivities: string[] | null; + taskDimension: DimensionType; } export default function ExportSubmenu(props: Props): JSX.Element { - const { menuKey, exporters, exportActivities } = props; + const { + menuKey, exporters, exportActivities, taskDimension, + } = props; return ( {exporters .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .filter((exporter: any): boolean => exporter.dimension === taskDimension) .map( (exporter: any): JSX.Element => { const pending = (exportActivities || []).includes(exporter.name); diff --git a/cvat-ui/src/components/actions-menu/load-submenu.tsx b/cvat-ui/src/components/actions-menu/load-submenu.tsx index 53bbe3c7..476e577f 100644 --- a/cvat-ui/src/components/actions-menu/load-submenu.tsx +++ b/cvat-ui/src/components/actions-menu/load-submenu.tsx @@ -8,23 +8,26 @@ import Upload from 'antd/lib/upload'; import Button from 'antd/lib/button'; import Text from 'antd/lib/typography/Text'; import { UploadOutlined, LoadingOutlined } from '@ant-design/icons'; +import { DimensionType } from '../../reducers/interfaces'; interface Props { menuKey: string; loaders: any[]; loadActivity: string | null; onFileUpload(file: File): void; + taskDimension: DimensionType; } export default function LoadSubmenu(props: Props): JSX.Element { const { - menuKey, loaders, loadActivity, onFileUpload, + menuKey, loaders, loadActivity, onFileUpload, taskDimension, } = props; return ( {loaders .sort((a: any, b: any) => a.name.localeCompare(b.name)) + .filter((loader: any): boolean => loader.dimension === taskDimension) .map( (loader: any): JSX.Element => { const accept = loader.format diff --git a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx index 6871ff29..67b4a7e1 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/annotation-menu.tsx @@ -164,6 +164,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { dumpers, dumpActivities, menuKey: Actions.DUMP_TASK_ANNO, + taskDimension: jobInstance.task.dimension, })} {LoadSubmenu({ loaders, @@ -172,11 +173,13 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element { onClickMenuWrapper(null, file); }, menuKey: Actions.LOAD_JOB_ANNO, + taskDimension: jobInstance.task.dimension, })} {ExportSubmenu({ exporters: dumpers, exportActivities, menuKey: Actions.EXPORT_TASK_DATASET, + taskDimension: jobInstance.task.dimension, })} Remove annotations diff --git a/cvat-ui/src/components/model-runner-modal/detector-runner.tsx b/cvat-ui/src/components/model-runner-modal/detector-runner.tsx index 8a000e1a..db757867 100644 --- a/cvat-ui/src/components/model-runner-modal/detector-runner.tsx +++ b/cvat-ui/src/components/model-runner-modal/detector-runner.tsx @@ -21,6 +21,7 @@ import { Model, StringObject } from 'reducers/interfaces'; import { clamp } from 'utils/math'; import consts from 'consts'; +import { DimensionType } from '../../reducers/interfaces'; interface Props { withCleanup: boolean; @@ -127,7 +128,8 @@ function DetectorRunner(props: Props): JSX.Element { Model: - Select - Radio - Checkbox - Text - Number + Select + Radio + Checkbox + Text + Number diff --git a/cvat-ui/src/reducers/notifications-reducer.ts b/cvat-ui/src/reducers/notifications-reducer.ts index 7ca5a845..cf3caec3 100644 --- a/cvat-ui/src/reducers/notifications-reducer.ts +++ b/cvat-ui/src/reducers/notifications-reducer.ts @@ -376,6 +376,7 @@ export default function (state = defaultState, action: AnyAction): Notifications updating: { message: `Could not update task ${taskID}`, reason: action.payload.error.toString(), + className: 'cvat-notification-notice-update-task-failed', }, }, }, @@ -412,6 +413,7 @@ export default function (state = defaultState, action: AnyAction): Notifications 'Could not delete the ' + `task ${taskID}`, reason: action.payload.error.toString(), + className: 'cvat-notification-notice-delete-task-failed', }, }, }, @@ -427,6 +429,7 @@ export default function (state = defaultState, action: AnyAction): Notifications creating: { message: 'Could not create the task', reason: action.payload.error.toString(), + className: 'cvat-notification-notice-create-task-failed', }, }, }, diff --git a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js index 4fc1ef3a..27226a2e 100644 --- a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js +++ b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js @@ -37,6 +37,11 @@ context('Multiple users. Assign task, job.', () => { password: 'Fv5Df3#f55g', }; + before(() => { + cy.imageGenerator(imagesFolder, imageFileName, width, height, color, posX, posY, labelName, imagesCount); + cy.createZipArchive(directoryToArchive, archivePath); + }); + after(() => { cy.login(); cy.getTaskID(taskName).then(($taskID) => { @@ -46,7 +51,7 @@ context('Multiple users. Assign task, job.', () => { describe(`Testing case "${caseId}"`, () => { // First user is "admin". - it('Register second user and logout.', () => { + it('Register second user, tries to create task and logout.', () => { cy.visit('auth/register'); cy.url().should('include', '/auth/register'); cy.userRegistration( @@ -56,6 +61,21 @@ context('Multiple users. Assign task, job.', () => { secondUser.emailAddr, secondUser.password, ); + cy.createAnnotationTask( + taskName, + labelName, + attrName, + textDefaultValue, + archiveName, + null, + null, + false, + false, + null, + 'fail', + ); + cy.closeNotification('.cvat-notification-notice-create-task-failed'); + cy.contains('.cvat-item-task-name', `${taskName}`).should('not.exist'); cy.logout(secondUserName); }); it('Register third user and logout.', () => { @@ -70,13 +90,21 @@ context('Multiple users. Assign task, job.', () => { ); cy.logout(thirdUserName); }); - it('First user login and create a task', () => { + it('First user login, create a task and logout', () => { cy.login(); - cy.imageGenerator(imagesFolder, imageFileName, width, height, color, posX, posY, labelName, imagesCount); - cy.createZipArchive(directoryToArchive, archivePath); cy.createAnnotationTask(taskName, labelName, attrName, textDefaultValue, archiveName); + cy.logout(); + }); + it('Second user login, tries to add label and logout', () => { + cy.login(secondUserName, secondUser.password); + cy.openTask(taskName); + cy.addNewLabel('failAddLabel'); + cy.closeNotification('.cvat-notification-notice-update-task-failed'); + cy.contains('.cvat-constructor-viewer-item', 'failAddLabel').should('not.exist'); + cy.logout(secondUserName); }); it('Assign the task to the second user and logout', () => { + cy.login(); cy.openTask(taskName); cy.assignTaskToUser(secondUserName); cy.logout(); @@ -98,9 +126,16 @@ context('Multiple users. Assign task, job.', () => { cy.assignJobToUser(0, thirdUserName); cy.logout(); }); - it('Third user login. The task can be opened.', () => { + it('Third user login. Tries to delete task. The task can be opened.', () => { cy.login(thirdUserName, thirdUser.password); cy.contains('strong', taskName).should('exist'); + cy.getTaskID(taskName).then(($taskID) => { + cy.deleteTask(taskName, $taskID); + }); + cy.closeNotification('.cvat-notification-notice-delete-task-failed'); + cy.contains('.cvat-item-task-name', taskName) + .parents('.cvat-tasks-list-item') + .should('not.have.attr', 'style'); cy.openTask(taskName); cy.logout(thirdUserName); }); diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js index a90058e5..4a1d494f 100644 --- a/tests/cypress/support/commands.js +++ b/tests/cypress/support/commands.js @@ -54,6 +54,7 @@ Cypress.Commands.add( forProject = false, attachToProject = false, projectName, + expectedResult = 'success', ) => { cy.get('#cvat-create-task-button').click({ force: true }); cy.url().should('include', '/tasks/create'); @@ -64,7 +65,7 @@ Cypress.Commands.add( cy.get('.cvat-new-attribute-button').click(); cy.get('[placeholder="Name"]').type(attrName); cy.get('.cvat-attribute-type-input').click(); - cy.get('.ant-select-item-option').contains('Text').click(); + cy.get('.cvat-attribute-type-input-text').click(); cy.get('[placeholder="Default value"]').type(textDefaultValue); if (multiAttrParams) { cy.updateAttributes(multiAttrParams); @@ -89,7 +90,9 @@ Cypress.Commands.add( cy.advancedConfiguration(advancedConfigurationParams); } cy.contains('button', 'Submit').click(); - cy.contains('The task has been created'); + if (expectedResult === 'success') { + cy.contains('The task has been created'); + } if (!forProject) { cy.goToTaskList(); } else { @@ -394,7 +397,7 @@ Cypress.Commands.add('getTaskID', (taskName) => { Cypress.Commands.add('deleteTask', (taskName, taskID) => { cy.contains('strong', taskName).parents('.cvat-tasks-list-item').find('.cvat-menu-icon').trigger('mouseover'); cy.get('.cvat-actions-menu').contains('Delete').click(); - cy.get('.ant-modal-content') + cy.get('.cvat-modal-confirm-delete-task') .should('contain', `The task ${taskID} will be deleted`) .within(() => { cy.contains('button', 'Delete').click(); From 41626ebabfc4e189f5b43daeb775e471c5bca63c Mon Sep 17 00:00:00 2001 From: Dmitry Kruchinin <33020454+dvkruchinin@users.noreply.github.com> Date: Mon, 11 Jan 2021 10:45:29 +0300 Subject: [PATCH 006/194] Cypress test. Feedback button. (#2637) * Add css class * Cypress test. Feedback button, popover content * Rework check a.href value Co-authored-by: Kruchinin --- cvat-ui/src/components/feedback/feedback.tsx | 1 + .../actions_users/case_38_feedback_button.js | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/cypress/integration/actions_users/case_38_feedback_button.js diff --git a/cvat-ui/src/components/feedback/feedback.tsx b/cvat-ui/src/components/feedback/feedback.tsx index b1741186..2fc28030 100644 --- a/cvat-ui/src/components/feedback/feedback.tsx +++ b/cvat-ui/src/components/feedback/feedback.tsx @@ -107,6 +107,7 @@ export default function Feedback(): JSX.Element { title={Help to make CVAT better} content={renderContent()} visible={visible} + overlayClassName='cvat-feedback-popover' > - - + + {currentAttribute} {` [${currentIndex + 1}/${attributesCount}]`} - - - - + ); } diff --git a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx index f371a287..b64d2c5f 100644 --- a/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx +++ b/cvat-ui/src/components/annotation-page/attribute-annotation-workspace/attribute-annotation-sidebar/object-switcher.tsx @@ -1,13 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Text from 'antd/lib/typography/Text'; -import Tooltip from 'antd/lib/tooltip'; import Button from 'antd/lib/button'; import { LeftOutlined, RightOutlined } from '@ant-design/icons'; +import CVATTooltip from 'components/common/cvat-tooltip'; + interface Props { currentLabel: string; clientID: number; @@ -26,21 +27,29 @@ function ObjectSwitcher(props: Props): JSX.Element { const title = `${currentLabel} ${clientID} [${currentIndex + 1}/${objectsCount}]`; return (
- - - - + + {currentLabel} {` ${clientID} `} {`[${currentIndex + 1}/${objectsCount}]`} - - - - +
); } diff --git a/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx b/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx index 04ecd78c..49035958 100644 --- a/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/canvas-point-context-menu.tsx @@ -1,16 +1,16 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import Button from 'antd/lib/button'; -import Tooltip from 'antd/lib/tooltip'; import { DeleteOutlined, EnvironmentOutlined } from '@ant-design/icons'; import { connect } from 'react-redux'; import { CombinedState, ContextMenuType } from 'reducers/interfaces'; import { updateAnnotationsAsync, updateCanvasContextMenu } from 'actions/annotation-actions'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface StateToProps { activatedState: any | null; @@ -103,11 +103,11 @@ function CanvasPointContextMenu(props: Props): React.ReactPortal | null { return visible && contextMenuFor && type === ContextMenuType.CANVAS_SHAPE_POINT ? ReactDOM.createPortal(
- + - + {contextMenuFor && contextMenuFor.shapeType === 'polygon' && (
); diff --git a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx index 6fe71158..4947f766 100644 --- a/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx +++ b/cvat-ui/src/components/annotation-page/review-workspace/controls-side-bar/issue-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { ActiveControl } from 'reducers/interfaces'; import { Canvas } from 'cvat-canvas-wrapper'; import { RectangleIcon } from 'icons'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -20,7 +20,7 @@ function ResizeControl(props: Props): JSX.Element { const { activeControl, canvasInstance, selectIssuePosition } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx b/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx index 02b5572e..579bec31 100644 --- a/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx +++ b/cvat-ui/src/components/annotation-page/review/hidden-issue-label.tsx @@ -1,13 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { ReactPortal, useEffect } from 'react'; import ReactDOM from 'react-dom'; import Tag from 'antd/lib/tag'; -import Tooltip from 'antd/lib/tooltip'; import { CheckOutlined, CloseCircleOutlined } from '@ant-design/icons'; +import CVATTooltip from 'components/common/cvat-tooltip'; + interface Props { id: number; message: string; @@ -34,7 +35,7 @@ export default function HiddenIssueLabel(props: Props): ReactPortal { const elementID = `cvat-hidden-issue-label-${id}`; return ReactDOM.createPortal( - + - , + , window.document.getElementById('cvat_canvas_attachment_board') as HTMLElement, ); } diff --git a/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx b/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx index 8660017d..27b89772 100644 --- a/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx +++ b/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -9,10 +9,10 @@ import { CloseOutlined } from '@ant-design/icons'; import Comment from 'antd/lib/comment'; import Text from 'antd/lib/typography/Text'; import Title from 'antd/lib/typography/Title'; -import Tooltip from 'antd/lib/tooltip'; import Button from 'antd/lib/button'; import Input from 'antd/lib/input'; import moment from 'moment'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { id: number; @@ -67,9 +67,9 @@ export default function IssueDialog(props: Props): JSX.Element { author={{_comment.author ? _comment.author.username : 'Unknown'}} content={

{_comment.message}

} datetime={( - + {diff} - + )} /> ); @@ -93,9 +93,9 @@ export default function IssueDialog(props: Props): JSX.Element { {id >= 0 ? `Issue #${id}` : 'Issue'} - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx index 9983fd6c..dd26d376 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/cursor-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { CursorIcon } from 'icons'; import { ActiveControl } from 'reducers/interfaces'; import { Canvas } from 'cvat-canvas-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -20,7 +20,7 @@ function CursorControl(props: Props): JSX.Element { const { canvasInstance, activeControl, cursorShortkey } = props; return ( - + canvasInstance.cancel() : undefined} /> - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx index a8a7ff42..b85f5d6a 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -7,13 +7,13 @@ import { Row, Col } from 'antd/lib/grid'; import Button from 'antd/lib/button'; import InputNumber from 'antd/lib/input-number'; import Radio, { RadioChangeEvent } from 'antd/lib/radio'; -import Tooltip from 'antd/lib/tooltip'; import Text from 'antd/lib/typography/Text'; import { RectDrawingMethod, CuboidDrawingMethod } from 'cvat-canvas-wrapper'; import { ShapeType } from 'reducers/interfaces'; import { clamp } from 'utils/math'; import LabelSelector from 'components/label-selector/label-selector'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { shapeType: ShapeType; @@ -129,11 +129,11 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { { - if (typeof value !== 'undefined') { - onChangePoints(Math.floor(clamp(+value, minimumPoints, Number.MAX_SAFE_INTEGER))); - } else if (!value) { + onChange={(value: number | undefined | string | null) => { + if (typeof value === 'undefined' || value === null) { onChangePoints(undefined); + } else { + onChangePoints(Math.floor(clamp(+value, minimumPoints, Number.MAX_SAFE_INTEGER))); } }} className='cvat-draw-shape-popover-points-selector' @@ -146,14 +146,14 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { )} - + - + - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx index e8f10f29..baa544ff 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/fit-control.tsx @@ -1,13 +1,13 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { FitIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -17,9 +17,9 @@ function FitControl(props: Props): JSX.Element { const { canvasInstance } = props; return ( - + canvasInstance.fit()} /> - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx index fb05e3f9..8b93c757 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/group-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; -import Tooltip from 'antd/lib/tooltip'; import Icon from '@ant-design/icons'; import { GroupIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { ActiveControl } from 'reducers/interfaces'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -19,30 +19,37 @@ interface Props { } function GroupControl(props: Props): JSX.Element { - const { switchGroupShortcut, resetGroupShortcut, activeControl, canvasInstance, groupObjects } = props; + const { + switchGroupShortcut, resetGroupShortcut, activeControl, canvasInstance, groupObjects, + } = props; const dynamicIconProps = - activeControl === ActiveControl.GROUP ? { - className: 'cvat-group-control cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.group({ enabled: false }); - groupObjects(false); - }, - } : { - className: 'cvat-group-control', - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.group({ enabled: true }); - groupObjects(true); - }, - }; - - const title = - `Group shapes/tracks ${switchGroupShortcut}.` + ` Select and press ${resetGroupShortcut} to reset a group`; + activeControl === ActiveControl.GROUP ? + { + className: 'cvat-group-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.group({ enabled: false }); + groupObjects(false); + }, + } : + { + className: 'cvat-group-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.group({ enabled: true }); + groupObjects(true); + }, + }; + + const title = [ + `Group shapes/tracks ${switchGroupShortcut}. `, + `Select and press ${resetGroupShortcut} to reset a group.`, + ].join(' '); + return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx index c9de255d..fdc80926 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/handle-popover-visibility.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx index b00c9eb5..2d29fb21 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/merge-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; -import Tooltip from 'antd/lib/tooltip'; import Icon from '@ant-design/icons'; import { MergeIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { ActiveControl } from 'reducers/interfaces'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -18,28 +18,32 @@ interface Props { } function MergeControl(props: Props): JSX.Element { - const { switchMergeShortcut, activeControl, canvasInstance, mergeObjects } = props; + const { + switchMergeShortcut, activeControl, canvasInstance, mergeObjects, + } = props; const dynamicIconProps = - activeControl === ActiveControl.MERGE ? { - className: 'cvat-merge-control cvat-active-canvas-control', - onClick: (): void => { - canvasInstance.merge({ enabled: false }); - mergeObjects(false); - }, - } : { - className: 'cvat-merge-control', - onClick: (): void => { - canvasInstance.cancel(); - canvasInstance.merge({ enabled: true }); - mergeObjects(true); - }, - }; + activeControl === ActiveControl.MERGE ? + { + className: 'cvat-merge-control cvat-active-canvas-control', + onClick: (): void => { + canvasInstance.merge({ enabled: false }); + mergeObjects(false); + }, + } : + { + className: 'cvat-merge-control', + onClick: (): void => { + canvasInstance.cancel(); + canvasInstance.merge({ enabled: true }); + mergeObjects(true); + }, + }; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx index 05b38556..760a59dd 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/move-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { MoveIcon } from 'icons'; import { ActiveControl } from 'reducers/interfaces'; import { Canvas } from 'cvat-canvas-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -19,7 +19,7 @@ function MoveControl(props: Props): JSX.Element { const { canvasInstance, activeControl } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/opencv-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/opencv-control.tsx index d4903427..8bb4ea87 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/opencv-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/opencv-control.tsx @@ -5,7 +5,6 @@ import React from 'react'; import { connect } from 'react-redux'; import { Row, Col } from 'antd/lib/grid'; -import Tooltip from 'antd/lib/tooltip'; import Popover from 'antd/lib/popover'; import Icon, { ScissorOutlined } from '@ant-design/icons'; import Text from 'antd/lib/typography/Text'; @@ -29,6 +28,7 @@ import { createAnnotationsAsync, } from 'actions/annotation-actions'; import LabelSelector from 'components/label-selector/label-selector'; +import CVATTooltip from 'components/common/cvat-tooltip'; import withVisibilityHandling from './handle-popover-visibility'; interface Props { @@ -293,7 +293,7 @@ class OpenCVControlComponent extends React.PureComponent - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx index 47d216d7..ac7806cb 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/resize-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { ZoomIcon } from 'icons'; import { ActiveControl } from 'reducers/interfaces'; import { Canvas } from 'cvat-canvas-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -19,7 +19,7 @@ function ResizeControl(props: Props): JSX.Element { const { activeControl, canvasInstance } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx index 3aa537eb..9fa1e2f9 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/rotate-control.tsx @@ -4,12 +4,11 @@ import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import Popover from 'antd/lib/popover'; import { RotateIcon } from 'icons'; import { Rotation } from 'reducers/interfaces'; - +import CVATTooltip from 'components/common/cvat-tooltip'; import withVisibilityHandling from './handle-popover-visibility'; interface Props { @@ -27,28 +26,20 @@ function RotateControl(props: Props): JSX.Element { placement='right' content={( <> - + rotateFrame(Rotation.ANTICLOCKWISE90)} component={RotateIcon} /> - - + + rotateFrame(Rotation.CLOCKWISE90)} component={RotateIcon} /> - + )} trigger='hover' diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx index a0e31a60..a202e346 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/setup-tag-popover.tsx @@ -1,13 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import { Row, Col } from 'antd/lib/grid'; import Button from 'antd/lib/button'; -import Tooltip from 'antd/lib/tooltip'; import Text from 'antd/lib/typography/Text'; + import LabelSelector from 'components/label-selector/label-selector'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { labels: any[]; @@ -48,9 +49,9 @@ function SetupTagPopover(props: Props): JSX.Element { - + - + diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx index 43625fd6..61d6bfce 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/split-control.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; -import Tooltip from 'antd/lib/tooltip'; import Icon from '@ant-design/icons'; import { SplitIcon } from 'icons'; import { Canvas } from 'cvat-canvas-wrapper'; import { ActiveControl } from 'reducers/interfaces'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -41,9 +41,9 @@ function SplitControl(props: Props): JSX.Element { }; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx index e877af6c..28043cce 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-picker.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React, { useState } from 'react'; @@ -9,9 +9,9 @@ import Button from 'antd/lib/button'; import Popover from 'antd/lib/popover'; import Text from 'antd/lib/typography/Text'; import { SketchPicker } from 'react-color'; -import Tooltip from 'antd/lib/tooltip'; import getCore from 'cvat-core-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; const core = getCore(); @@ -108,7 +108,7 @@ function ColorPicker(props: Props, ref: React.Ref): JSX.Element { Select color - + - + )} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx index 47695f06..f9fb7070 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/issues-list.tsx @@ -8,12 +8,12 @@ import { CombinedState } from 'reducers/interfaces'; import { LeftOutlined, RightOutlined, EyeInvisibleFilled, EyeOutlined, } from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import Alert from 'antd/lib/alert'; import { Row, Col } from 'antd/lib/grid'; import { changeFrameAsync } from 'actions/annotation-actions'; import { reviewActions } from 'actions/review-actions'; +import CVATTooltip from 'components/common/cvat-tooltip'; export default function LabelsListComponent(): JSX.Element { const dispatch = useDispatch(); @@ -54,17 +54,17 @@ export default function LabelsListComponent(): JSX.Element {
- + - + - + - + - + {issuesHidden ? ( dispatch(reviewActions.switchIssuesHiddenFlag(true))} /> )} - +
diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx index 8aa249ee..0e7cda1e 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -7,9 +7,9 @@ import { Row, Col } from 'antd/lib/grid'; import { MoreOutlined } from '@ant-design/icons'; import Dropdown from 'antd/lib/dropdown'; import Text from 'antd/lib/typography/Text'; -import Tooltip from 'antd/lib/tooltip'; import { ObjectType, ShapeType, ColorBy } from 'reducers/interfaces'; +import CVATTooltip from 'components/common/cvat-tooltip'; import LabelSelector from 'components/label-selector/label-selector'; import ItemMenu from './object-item-menu'; @@ -103,7 +103,7 @@ function ItemTopComponent(props: Props): JSX.Element { - + - + + - + ) : ( ); @@ -118,9 +118,9 @@ function NavigatePrevKeyframe(props: Props): JSX.Element { function NavigateNextKeyframe(props: Props): JSX.Element { const { navigateNextKeyframe, nextKeyFrameShortcut } = props; return navigateNextKeyframe ? ( - + - + ) : ( ); @@ -140,13 +140,13 @@ function SwitchLock(props: Props): JSX.Element { locked, switchLockShortcut, lock, unlock, } = props; return ( - + {locked ? ( ) : ( )} - + ); } @@ -155,26 +155,26 @@ function SwitchOccluded(props: Props): JSX.Element { switchOccludedShortcut, occluded, unsetOccluded, setOccluded, } = props; return ( - + {occluded ? ( ) : ( )} - + ); } function SwitchPinned(props: Props): JSX.Element { const { pinned, pin, unpin } = props; return ( - + {pinned ? ( ) : ( )} - + ); } @@ -184,13 +184,13 @@ function SwitchHidden(props: Props): JSX.Element { } = props; const hiddenStyle = hiddenDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; return ( - + ); } @@ -200,7 +200,7 @@ function SwitchOutside(props: Props): JSX.Element { } = props; const outsideStyle = outsideDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; return ( - + {outside ? ( )} - + ); } @@ -221,13 +221,13 @@ function SwitchKeyframe(props: Props): JSX.Element { } = props; const keyframeStyle = keyframeDisabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}; return ( - + {keyframe ? ( ) : ( )} - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx index d27aa05b..933a1283 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -6,7 +6,6 @@ import React from 'react'; import Menu from 'antd/lib/menu'; import Button from 'antd/lib/button'; import Modal from 'antd/lib/modal'; -import Tooltip from 'antd/lib/tooltip'; import Icon, { LinkOutlined, CopyOutlined, @@ -15,9 +14,11 @@ import Icon, { RetweetOutlined, DeleteOutlined, } from '@ant-design/icons'; + import { BackgroundIcon, ForegroundIcon, ResetPerspectiveIcon, ColorizeIcon, } from 'icons'; +import CVATTooltip from 'components/common/cvat-tooltip'; import { ObjectType, ShapeType, ColorBy } from 'reducers/interfaces'; import ColorPicker from './color-picker'; @@ -71,11 +72,11 @@ function MakeCopyItem(props: ItemProps): JSX.Element { const { copyShortcut, pasteShortcut, copy } = toolProps; return ( - + - + ); } @@ -85,11 +86,11 @@ function PropagateItem(props: ItemProps): JSX.Element { const { propagateShortcut, propagate } = toolProps; return ( - + - + ); } @@ -99,11 +100,11 @@ function TrackingItem(props: ItemProps): JSX.Element { const { activateTracking } = toolProps; return ( - + - + ); } @@ -138,12 +139,12 @@ function ToBackgroundItem(props: ItemProps): JSX.Element { const { toBackgroundShortcut, toBackground } = toolProps; return ( - + - + ); } @@ -153,12 +154,12 @@ function ToForegroundItem(props: ItemProps): JSX.Element { const { toForegroundShortcut, toForeground } = toolProps; return ( - + - + ); } @@ -182,12 +183,12 @@ function SwitchColorItem(props: ItemProps): JSX.Element { onVisibleChange={changeColorPickerVisible} resetVisible={false} > - + - +
); @@ -198,7 +199,7 @@ function RemoveItem(props: ItemProps): JSX.Element { const { removeShortcut, locked, remove } = toolProps; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx index 05c1272a..1e77e7af 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list-header.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -12,8 +12,8 @@ import { CaretDownOutlined, CaretUpFilled, } from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; +import CVATTooltip from 'components/common/cvat-tooltip'; import AnnotationsFiltersInput from 'components/annotation-page/annotations-filters-input'; import StatesOrderingSelector from 'components/annotation-page/standard-workspace/objects-side-bar/states-ordering-selector'; import { StatesOrdering } from 'reducers/interfaces'; @@ -41,9 +41,9 @@ function LockAllSwitcher(props: Props): JSX.Element { } = props; return ( - + {statesLocked ? : } - + ); } @@ -54,13 +54,13 @@ function HideAllSwitcher(props: Props): JSX.Element { } = props; return ( - + ); } @@ -69,13 +69,13 @@ function CollapseAllSwitcher(props: Props): JSX.Element { const { statesCollapsed, expandAllStates, collapseAllStates } = props; return ( - + {statesCollapsed ? ( ) : ( )} - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/cursor-control.tsx b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/cursor-control.tsx index b8b63456..72b2c99d 100644 --- a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/cursor-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/cursor-control.tsx @@ -4,11 +4,11 @@ import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { CursorIcon } from 'icons'; import { ActiveControl } from 'reducers/interfaces'; import { Canvas3d as Canvas } from 'cvat-canvas3d-wrapper'; +import CVATTooltip from 'components/common/cvat-tooltip'; interface Props { canvasInstance: Canvas; @@ -20,15 +20,15 @@ function CursorControl(props: Props): JSX.Element { const { activeControl, cursorShortkey } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/move-control.tsx b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/move-control.tsx index 05ddd20a..4a41c6df 100644 --- a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/move-control.tsx +++ b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/move-control.tsx @@ -4,10 +4,10 @@ import React from 'react'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import { MoveIcon } from 'icons'; import { ActiveControl } from 'reducers/interfaces'; +import CVATTooltip from 'components/common/cvat-tooltip'; import { Canvas3d as Canvas } from 'cvat-canvas3d-wrapper'; interface Props { @@ -19,15 +19,15 @@ function MoveControl(props: Props): JSX.Element { const { activeControl } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/photo-context.tsx b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/photo-context.tsx index b18b84b8..f5b9587b 100644 --- a/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/photo-context.tsx +++ b/cvat-ui/src/components/annotation-page/standard3D-workspace/controls-side-bar/photo-context.tsx @@ -2,10 +2,11 @@ // // SPDX-License-Identifier: MIT +import React from 'react'; import CameraIcon from '@ant-design/icons/CameraOutlined'; -import Tooltip from 'antd/lib/tooltip'; + +import CVATTooltip from 'components/common/cvat-tooltip'; import { Canvas3d as Canvas } from 'cvat-canvas3d-wrapper'; -import React from 'react'; import { ActiveControl } from 'reducers/interfaces'; interface Props { @@ -19,7 +20,7 @@ function PhotoContextControl(props: Props): JSX.Element { const { activeControl, contextImageHide, hideShowContextImage } = props; return ( - + - + ); } diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx index 22ca7c97..5bc79ca2 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-buttons.tsx @@ -1,14 +1,14 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT import React from 'react'; - import { Col } from 'antd/lib/grid'; import Icon from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import Popover from 'antd/lib/popover'; +import CVATTooltip from 'components/common/cvat-tooltip'; + import { FirstIcon, BackJumpIcon, @@ -104,18 +104,18 @@ function PlayerButtons(props: Props): JSX.Element { return ( - + - - + + - + - + - - + + - - + + - + )} > - + {prevButton} - + {!playing ? ( - + - + ) : ( - + - + )} - + - - + + - - + + - + )} > - + {nextButton} - + - + - - + + - + ); } diff --git a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx index 65ef5130..dfe72354 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/player-navigation.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -7,11 +7,11 @@ import React, { useState, useEffect } from 'react'; import { Row, Col } from 'antd/lib/grid'; import { LinkOutlined } from '@ant-design/icons'; import Slider from 'antd/lib/slider'; -import Tooltip from 'antd/lib/tooltip'; import InputNumber from 'antd/lib/input-number'; import Input from 'antd/lib/input'; import Text from 'antd/lib/typography/Text'; +import CVATTooltip from 'components/common/cvat-tooltip'; import { clamp } from 'utils/math'; interface Props { @@ -63,26 +63,26 @@ function PlayerNavigation(props: Props): JSX.Element { - + {frameFilename} - + - + - + - + { - if (typeof value !== 'undefined') { + onChange={(value: number | undefined | string | null) => { + if (typeof value !== 'undefined' && value !== null) { setFrameInputValue(Math.floor(clamp(+value, startFrame, stopFrame))); } }} @@ -93,7 +93,7 @@ function PlayerNavigation(props: Props): JSX.Element { onInputChange(frameInputValue); }} /> - + ); diff --git a/cvat-ui/src/components/annotation-page/top-bar/statistics-modal.tsx b/cvat-ui/src/components/annotation-page/top-bar/statistics-modal.tsx index 7db9b687..2ac1339d 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/statistics-modal.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/statistics-modal.tsx @@ -5,12 +5,13 @@ import React from 'react'; import { Row, Col } from 'antd/lib/grid'; import { QuestionCircleOutlined } from '@ant-design/icons'; -import Tooltip from 'antd/lib/tooltip'; import Table from 'antd/lib/table'; import Modal from 'antd/lib/modal'; import Spin from 'antd/lib/spin'; import Text from 'antd/lib/typography/Text'; +import CVATTooltip from 'components/common/cvat-tooltip'; + interface Props { collecting: boolean; data: any; @@ -76,12 +77,12 @@ export default function StatisticsModalComponent(props: Props): JSX.Element { }); const makeShapesTracksTitle = (title: string): JSX.Element => ( - + {title} - + ); const columns = [ diff --git a/cvat-ui/src/components/common/cvat-tooltip.tsx b/cvat-ui/src/components/common/cvat-tooltip.tsx new file mode 100644 index 00000000..062fedd1 --- /dev/null +++ b/cvat-ui/src/components/common/cvat-tooltip.tsx @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Intel Corporation +// +// SPDX-License-Identifier: MIT + +import React from 'react'; +import Tooltip, { TooltipProps } from 'antd/lib/tooltip'; + +function CVATTooltip(props: TooltipProps): JSX.Element { + const { children, ...rest } = props; + + return ( + + {children} + + ); +} + +export default React.memo(CVATTooltip); diff --git a/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx b/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx index 804a8725..5ac9d3ae 100644 --- a/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx +++ b/cvat-ui/src/components/create-task-page/advanced-configuration-form.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -7,12 +7,12 @@ import { Row, Col } from 'antd/lib/grid'; import { PercentageOutlined } from '@ant-design/icons'; import Input from 'antd/lib/input'; import Checkbox from 'antd/lib/checkbox'; -import Tooltip from 'antd/lib/tooltip'; import Form, { FormInstance, RuleObject, RuleRender } from 'antd/lib/form'; import Text from 'antd/lib/typography/Text'; +import { Store } from 'antd/lib/form/interface'; +import CVATTooltip from 'components/common/cvat-tooltip'; import patterns from 'utils/validation-patterns'; -import { Store } from 'antd/lib/form/interface'; export interface AdvancedConfiguration { bugTracker?: string; @@ -176,7 +176,7 @@ class AdvancedConfigurationForm extends React.PureComponent { private renderImageQuality(): JSX.Element { return ( - + { > } /> - + ); } private renderOverlap(): JSX.Element { return ( - + { > - + ); } private renderSegmentSize(): JSX.Element { return ( - + - + ); } @@ -329,7 +329,7 @@ class AdvancedConfigurationForm extends React.PureComponent { private renderChunkSize(): JSX.Element { return ( - Defines a number of frames to be packed in a chunk when send from client to server. Server @@ -346,12 +346,11 @@ class AdvancedConfigurationForm extends React.PureComponent { More: 1 - 4 )} - mouseLeaveDelay={0} > - + ); } diff --git a/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx b/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx index 6330ca00..30db61c7 100644 --- a/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx +++ b/cvat-ui/src/components/global-error-boundary/global-error-boundary.tsx @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation // // SPDX-License-Identifier: MIT @@ -10,7 +10,6 @@ import Text from 'antd/lib/typography/Text'; import Paragraph from 'antd/lib/typography/Paragraph'; import Collapse from 'antd/lib/collapse'; import TextArea from 'antd/lib/input/TextArea'; -import Tooltip from 'antd/lib/tooltip'; import copy from 'copy-to-clipboard'; import ErrorStackParser from 'error-stack-parser'; @@ -18,6 +17,7 @@ import { ThunkDispatch } from 'utils/redux'; import { resetAfterErrorAsync } from 'actions/boundaries-actions'; import { CombinedState } from 'reducers/interfaces'; import logger, { LogType } from 'cvat-logger'; +import CVATTooltip from 'components/common/cvat-tooltip'; import consts from 'consts'; interface StateToProps { @@ -146,7 +146,7 @@ class GlobalErrorBoundary extends React.PureComponent {