From 69fb2469f019ca3615971a932734f1c41f22b4aa Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Sun, 8 Sep 2024 22:40:11 +0300 Subject: [PATCH 1/9] Removed legacy component to setup shortcuts --- .../objects-side-bar/label-item.tsx | 27 +--- .../label-key-selector-popover.tsx | 89 ----------- .../objects-side-bar/labels-list.tsx | 142 +++++++----------- .../objects-side-bar/styles.scss | 28 ---- .../objects-side-bar/label-item.tsx | 9 +- cvat-ui/src/reducers/annotation-reducer.ts | 30 ++-- 6 files changed, 77 insertions(+), 248 deletions(-) delete mode 100644 cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-key-selector-popover.tsx diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx index 963f5d617ba..c6d5627c7a1 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-item.tsx @@ -1,39 +1,33 @@ // Copyright (C) 2020-2022 Intel Corporation +// Copyright (C) 2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT import React from 'react'; import { Row, Col } from 'antd/lib/grid'; -import Button from 'antd/lib/button'; import Text from 'antd/lib/typography/Text'; import { LockFilled, UnlockOutlined, EyeInvisibleFilled, EyeOutlined, } from '@ant-design/icons'; import CVATTooltip from 'components/common/cvat-tooltip'; -import LabelKeySelectorPopover from './label-key-selector-popover'; interface Props { labelName: string; labelColor: string; - labelID: number; visible: boolean; statesHidden: boolean; statesLocked: boolean; - keyToLabelMapping: Record; hideStates(): void; showStates(): void; lockStates(): void; unlockStates(): void; - updateLabelShortcutKey(updatedKey: string, labelID: number): void; } function LabelItemComponent(props: Props): JSX.Element { const { labelName, labelColor, - labelID, - keyToLabelMapping, visible, statesHidden, statesLocked, @@ -41,14 +35,8 @@ function LabelItemComponent(props: Props): JSX.Element { showStates, lockStates, unlockStates, - updateLabelShortcutKey, } = props; - // create reversed mapping just to receive key easily - const labelToKeyMapping: Record = Object.fromEntries( - Object.entries(keyToLabelMapping).map(([key, _labelID]) => [_labelID, key]), - ); - const labelShortcutKey = labelToKeyMapping[labelID] || '?'; const classes = { lock: { enabled: { className: 'cvat-label-item-button-lock cvat-label-item-button-lock-enabled' }, @@ -74,24 +62,13 @@ function LabelItemComponent(props: Props): JSX.Element { {' '} - + {labelName} - - - - - {statesLocked ? ( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-key-selector-popover.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-key-selector-popover.tsx deleted file mode 100644 index 41ed4947d27..00000000000 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/label-key-selector-popover.tsx +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2021-2022 Intel Corporation -// Copyright (C) 2024 CVAT.ai Corporation -// -// SPDX-License-Identifier: MIT - -import React from 'react'; -import { useSelector } from 'react-redux'; -import Popover from 'antd/lib/popover'; -import Button from 'antd/lib/button'; -import { Row, Col } from 'antd/lib/grid'; -import Text from 'antd/lib/typography/Text'; - -import { CombinedState } from 'reducers'; -import CVATTooltip from 'components/common/cvat-tooltip'; - -interface LabelKeySelectorPopoverProps { - updateLabelShortcutKey(updatedKey: string, labelID: number): void; - keyToLabelMapping: Record; - labelID: number; - children: JSX.Element; -} - -interface LabelKeySelectorPopoverContentProps { - updateLabelShortcutKey(updatedKey: string, labelID: number): void; - labelID: number; - keyToLabelMapping: Record; -} - -function PopoverContent(props: LabelKeySelectorPopoverContentProps): JSX.Element { - const { keyToLabelMapping, labelID, updateLabelShortcutKey } = props; - const labels = useSelector((state: CombinedState) => state.annotation.job.labels); - - return ( -
- {[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'], ['0']].map((arr, i_) => ( - - {arr.map((i) => { - const previousLabelID = keyToLabelMapping[i]; - const labelName = Number.isInteger(previousLabelID) ? - labels.filter((label: any): boolean => label.id === previousLabelID)[0]?.name || - 'undefined' : - 'None'; - - return ( - - - - - - ); - })} - - ))} -
- ); -} - -const MemoizedContent = React.memo(PopoverContent); - -function LabelKeySelectorPopover(props: LabelKeySelectorPopoverProps): JSX.Element { - const { - children, labelID, updateLabelShortcutKey, keyToLabelMapping, - } = props; - - return ( - - )} - placement='left' - > - {children} - - ); -} - -export default React.memo(LabelKeySelectorPopover); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx index 06cb70ca8de..703c03b5ffa 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx @@ -3,20 +3,21 @@ // // SPDX-License-Identifier: MIT -import React, { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React, { useEffect } from 'react'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import message from 'antd/lib/message'; -import { LabelType } from 'cvat-core-wrapper'; +import { LabelType, ShapeType } from 'cvat-core-wrapper'; import { CombinedState, ObjectType } from 'reducers'; import { rememberObject, updateAnnotationsAsync } from 'actions/annotation-actions'; import LabelItemContainer from 'containers/annotation-page/standard-workspace/objects-side-bar/label-item'; -import GlobalHotKeys, { KeyMap, KeyMapItem } from 'utils/mousetrap-react'; +import GlobalHotKeys, { KeyMapItem } from 'utils/mousetrap-react'; import Text from 'antd/lib/typography/Text'; import { ShortcutScope } from 'utils/enums'; import { registerComponentShortcuts } from 'actions/shortcuts-actions'; import { subKeyMap } from 'utils/component-subkeymap'; import { useResetShortcutsOnUnmount } from 'utils/hooks'; +import { getCVATStore } from 'cvat-store'; const componentShortcuts: Record = {}; @@ -34,33 +35,29 @@ registerComponentShortcuts(componentShortcuts); function LabelsListComponent(): JSX.Element { const dispatch = useDispatch(); - const labels = useSelector((state: CombinedState) => state.annotation.job.labels); - const activatedStateID = useSelector((state: CombinedState) => state.annotation.annotations.activatedStateID); - const activeShapeType = useSelector((state: CombinedState) => state.annotation.drawing.activeShapeType); - const activeObjectType = useSelector((state: CombinedState) => state.annotation.drawing.activeObjectType); - const states = useSelector((state: CombinedState) => state.annotation.annotations.states); - const keyMap = useSelector((state: CombinedState) => state.shortcuts.keyMap); + + const { labels, keyMap } = useSelector((state: CombinedState) => ({ + labels: state.annotation.job.labels, + activeShapeType: state.annotation.drawing.activeShapeType, + activeObjectType: state.annotation.drawing.activeObjectType, + keyMap: state.shortcuts.keyMap, + }), shallowEqual); + const labelIDs = labels.map((label: any): number => label.id); - const [keyToLabelMapping, setKeyToLabelMapping] = useState>( - Object.fromEntries(labelIDs.slice(0, 10).map((labelID: number, idx: number) => [(idx + 1) % 10, labelID])), - ); useResetShortcutsOnUnmount(componentShortcuts); + const keyToLabelMapping = Object.fromEntries( + labelIDs.slice(0, 10).map((labelID: number, idx: number) => [(idx + 1) % 10, labelID]), + ); + useEffect(() => { - const updatedComponentShortcuts = Object.keys(componentShortcuts).reduce((acc: KeyMap, key: string) => { - acc[key] = { - ...componentShortcuts[key], - sequences: keyMap[key].sequences, - }; - return acc; - }, {}); - - for (const [id, labelID] of Object.entries(keyToLabelMapping)) { + const updatedComponentShortcuts = JSON.parse(JSON.stringify(componentShortcuts)); + for (const [index, labelID] of Object.entries(keyToLabelMapping)) { if (labelID) { const labelName = labels.find((label: any) => label.id === labelID)?.name; - updatedComponentShortcuts[`SWITCH_LABEL_${id}`] = { - ...updatedComponentShortcuts[`SWITCH_LABEL_${id}`], + updatedComponentShortcuts[`SWITCH_LABEL_${index}`] = { + ...updatedComponentShortcuts[`SWITCH_LABEL_${index}`], nonActive: false, name: `Switch label to ${labelName}`, description: `Changes the label to ${labelName} for the activated @@ -70,63 +67,45 @@ function LabelsListComponent(): JSX.Element { } registerComponentShortcuts(updatedComponentShortcuts); - }, [keyToLabelMapping]); - - const updateLabelShortcutKey = useCallback( - (key: string, labelID: number) => { - // unassign any keys assigned to the current labels - const keyToLabelMappingCopy = { ...keyToLabelMapping }; - for (const shortKey of Object.keys(keyToLabelMappingCopy)) { - if (keyToLabelMappingCopy[shortKey] === labelID) { - delete keyToLabelMappingCopy[shortKey]; - } - } - - if (key === '—') { - setKeyToLabelMapping(keyToLabelMappingCopy); - return; - } + }, [labels]); - // check if this key is assigned to another label - if (key in keyToLabelMappingCopy) { - // try to find a new key for the other label - for (let i = 0; i < 10; i++) { - const adjustedI = (i + 1) % 10; - if (!(adjustedI in keyToLabelMappingCopy)) { - keyToLabelMappingCopy[adjustedI] = keyToLabelMappingCopy[key]; - break; - } - } - // delete assigning to the other label - delete keyToLabelMappingCopy[key]; - } - - // assigning to the current label - keyToLabelMappingCopy[key] = labelID; - setKeyToLabelMapping(keyToLabelMappingCopy); - }, - [keyToLabelMapping], - ); - - const handleHelper = (event: KeyboardEvent, i: number): void => { + const handleHelper = (event: KeyboardEvent, index: number): void => { if (event) event.preventDefault(); - const labelID = keyToLabelMapping[i]; + const labelID = keyToLabelMapping[index]; const label = labels.find((_label: any) => _label.id === labelID)!; - if (Number.isInteger(labelID) && label && Number.isInteger(activatedStateID)) { - const activatedState = states.filter((state: any) => state.clientID === activatedStateID)[0]; - const bothAreTags = activatedState.objectType === ObjectType.TAG && label.type === ObjectType.TAG; - const labelIsApplicable = label.type === LabelType.ANY || - activatedState.shapeType === label.type || bothAreTags; - if (activatedState && labelIsApplicable) { - activatedState.label = label; - dispatch(updateAnnotationsAsync([activatedState])); - } - } else { - const bothAreTags = activeObjectType === ObjectType.TAG && label.type === ObjectType.TAG; - const labelIsApplicable = label.type === LabelType.ANY || - activeShapeType === label.type || bothAreTags; - if (labelIsApplicable) { - dispatch(rememberObject({ activeLabelID: labelID })); + if (Number.isInteger(labelID) && label) { + const relevantAppState = getCVATStore().getState(); + const { states, activatedStateID } = relevantAppState.annotation.annotations; + const { activeShapeType, activeObjectType } = relevantAppState.annotation.drawing; + + if (Number.isInteger(activatedStateID)) { + const activatedState = states.filter((state: any) => state.clientID === activatedStateID)[0]; + const bothAreTags = activatedState.objectType === ObjectType.TAG && label.type === LabelType.TAG; + const labelIsApplicable = label.type === LabelType.ANY || + (activatedState.shapeType === label.type && activatedState.shapeType !== ShapeType.SKELETON) || + bothAreTags; + if (activatedState && labelIsApplicable) { + activatedState.label = label; + dispatch(updateAnnotationsAsync([activatedState])); + } + } else { + if (label.type === LabelType.TAG) { + dispatch(rememberObject({ activeLabelID: labelID, activeObjectType: ObjectType.TAG }, false)); + } else if (label.type === LabelType.MASK) { + dispatch(rememberObject({ + activeLabelID: labelID, + activeObjectType: ObjectType.SHAPE, + activeShapeType: ShapeType.MASK, + }, false)); + } else { + dispatch(rememberObject({ + activeLabelID: labelID, + activeObjectType: activeObjectType !== ObjectType.TAG ? activeObjectType : ObjectType.SHAPE, + activeShapeType: label.type === LabelType.ANY && activeShapeType !== ShapeType.SKELETON ? + activeShapeType : label.type as unknown as ShapeType, + }, false)); + } + message.destroy(); message.success(`Default label has been changed to "${label.name}"`); } @@ -149,12 +128,7 @@ function LabelsListComponent(): JSX.Element { {labelIDs.map( (labelID: number): JSX.Element => ( - + ), )} diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss index ff75c1a6e5f..b573bb61618 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/styles.scss @@ -375,34 +375,6 @@ border-radius: $border-radius-base; } -.cvat-label-item-setup-shortcut-button { - border-color: $objects-bar-icons-color; -} - -.cvat-label-item-setup-shortcut-popover { - margin-top: -$grid-unit-size; - margin-bottom: -$grid-unit-size; - - > div { - padding-top: $grid-unit-size; - padding-bottom: $grid-unit-size; - - > div { - display: flex; - justify-content: center; - - > button { - width: $grid-unit-size * 15; - overflow-x: hidden; - - span:first-child { - margin-right: $grid-unit-size; - } - } - } - } -} - .cvat-objects-appearance-content { > div { width: 100%; diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/label-item.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/label-item.tsx index 56bdff93be1..e3399b54518 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/label-item.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/label-item.tsx @@ -12,8 +12,6 @@ import { CombinedState, ObjectType } from 'reducers'; interface OwnProps { labelID: number; - keyToLabelMapping: Record; - updateLabelShortcutKey(updatedKey: string, labelID: number): void; } interface StateToProps { @@ -150,17 +148,13 @@ class LabelItemContainer extends React.PureComponent { } public render(): JSX.Element { - const { - labelName, labelColor, keyToLabelMapping, labelID, updateLabelShortcutKey, - } = this.props; + const { labelName, labelColor } = this.props; const { visible, statesHidden, statesLocked } = this.state; return ( { showStates={this.showStates} lockStates={this.lockStates} unlockStates={this.unlockStates} - updateLabelShortcutKey={updateLabelShortcutKey} /> ); } diff --git a/cvat-ui/src/reducers/annotation-reducer.ts b/cvat-ui/src/reducers/annotation-reducer.ts index 941d04fc401..54d94ee7ce8 100644 --- a/cvat-ui/src/reducers/annotation-reducer.ts +++ b/cvat-ui/src/reducers/annotation-reducer.ts @@ -468,21 +468,23 @@ export default (state = defaultState, action: AnyAction): AnnotationState => { const { payload } = action; let { activeControl } = state.canvas; - if ('activeObjectType' in payload && payload.activeObjectType === ObjectType.TAG) { - activeControl = ActiveControl.CURSOR; - } else if ('activeShapeType' in payload) { - const controlMapping = { - [ShapeType.RECTANGLE]: ActiveControl.DRAW_RECTANGLE, - [ShapeType.POLYGON]: ActiveControl.DRAW_POLYGON, - [ShapeType.POLYLINE]: ActiveControl.DRAW_POLYLINE, - [ShapeType.POINTS]: ActiveControl.DRAW_POINTS, - [ShapeType.ELLIPSE]: ActiveControl.DRAW_ELLIPSE, - [ShapeType.CUBOID]: ActiveControl.DRAW_CUBOID, - [ShapeType.SKELETON]: ActiveControl.DRAW_SKELETON, - [ShapeType.MASK]: ActiveControl.DRAW_MASK, - }; + if (payload.updateCurrentControl) { + if ('activeObjectType' in payload && payload.activeObjectType === ObjectType.TAG) { + activeControl = ActiveControl.CURSOR; + } else if ('activeShapeType' in payload) { + const controlMapping = { + [ShapeType.RECTANGLE]: ActiveControl.DRAW_RECTANGLE, + [ShapeType.POLYGON]: ActiveControl.DRAW_POLYGON, + [ShapeType.POLYLINE]: ActiveControl.DRAW_POLYLINE, + [ShapeType.POINTS]: ActiveControl.DRAW_POINTS, + [ShapeType.ELLIPSE]: ActiveControl.DRAW_ELLIPSE, + [ShapeType.CUBOID]: ActiveControl.DRAW_CUBOID, + [ShapeType.SKELETON]: ActiveControl.DRAW_SKELETON, + [ShapeType.MASK]: ActiveControl.DRAW_MASK, + }; - activeControl = controlMapping[payload.activeShapeType as ShapeType]; + activeControl = controlMapping[payload.activeShapeType as ShapeType]; + } } return { From d48de5cd7b7e25ddbad40199c5572ad86988229d Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Sun, 8 Sep 2024 22:48:23 +0300 Subject: [PATCH 2/9] Added changelog --- ...sekachev.bs_removed_legacy_component_to_setup_shortcuts.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelog.d/20240908_224722_sekachev.bs_removed_legacy_component_to_setup_shortcuts.md diff --git a/changelog.d/20240908_224722_sekachev.bs_removed_legacy_component_to_setup_shortcuts.md b/changelog.d/20240908_224722_sekachev.bs_removed_legacy_component_to_setup_shortcuts.md new file mode 100644 index 00000000000..96d6e63f41b --- /dev/null +++ b/changelog.d/20240908_224722_sekachev.bs_removed_legacy_component_to_setup_shortcuts.md @@ -0,0 +1,4 @@ +### Removed + +- Legacy component to setup shortcuts to switch a label + () From c66cd09496481ddbe78f8ed4f2d68af3f9a28c3d Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Sun, 8 Sep 2024 23:27:06 +0300 Subject: [PATCH 3/9] Missing code --- cvat-ui/src/actions/annotation-actions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cvat-ui/src/actions/annotation-actions.ts b/cvat-ui/src/actions/annotation-actions.ts index a5594093db5..31b73314a13 100644 --- a/cvat-ui/src/actions/annotation-actions.ts +++ b/cvat-ui/src/actions/annotation-actions.ts @@ -1058,10 +1058,10 @@ export function rememberObject(createParams: { activeNumOfPoints?: number; activeRectDrawingMethod?: RectDrawingMethod; activeCuboidDrawingMethod?: CuboidDrawingMethod; -}): AnyAction { +}, updateCurrentControl = true): AnyAction { return { type: AnnotationActionTypes.REMEMBER_OBJECT, - payload: createParams, + payload: { ...createParams, updateCurrentControl }, }; } From e41c7a7b60b7d394f52597e6f550bd46f32ec140 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Sun, 8 Sep 2024 23:54:47 +0300 Subject: [PATCH 4/9] Removed not relevant test --- .../case_72_hotkeys_change_labels.js | 45 +------------------ 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js index b61419694fa..6bd7ee4bb16 100644 --- a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js +++ b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js @@ -1,5 +1,5 @@ // Copyright (C) 2021-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -135,48 +135,5 @@ context('Hotkeys to change labels feature.', () => { .find('.cvat-objects-sidebar-state-item-label-selector') .should('have.text', secondLabelCurrentVal); }); - - it('Check changing shortcut for a label.', () => { - // Go to a labels tab - cy.get('.cvat-objects-sidebar-tabs').within(() => { - cy.contains('[role="tab"]', 'Labels').click(); - }); - cy.contains('.cvat-label-item-setup-shortcut-button', '1').click(); - cy.get('.cvat-label-item-setup-shortcut-popover') - .should('be.visible') - .within(() => { - cy.get('[type="button"]').then(($btn) => { - expect($btn[0].innerText).to.be.equal(`1:${firstLabelCurrentVal}`); - expect($btn[1].innerText).to.be.equal(`2:${secondLabelCurrentVal}`); - expect($btn[2].innerText).to.be.equal('3:None'); - // Click to "3" button - cy.get($btn[2]).click(); - }); - }); - cy.get('.cvat-label-item-setup-shortcut-popover') - .should('be.visible') - .within(() => { - cy.get('[type="button"]').then(($btn) => { - // Buttons 1 and 3 have changed values - expect($btn[0].innerText).to.be.equal('1:None'); - expect($btn[2].innerText).to.be.equal(`3:${firstLabelCurrentVal}`); - }); - }); - cy.contains('.cvat-label-item-setup-shortcut-button', '3').should('exist'); - cy.get('.cvat-canvas-container').click(); // Hide shortcut popover - // Go to "Objects" tab - cy.get('.cvat-objects-sidebar-tabs').within(() => { - cy.contains('[role="tab"]', 'Objects').click(); - }); - // Checking the label change via the new hotkey value - cy.get('.cvat-canvas-container').click(270, 260); - cy.get('#cvat_canvas_shape_1').should('have.class', 'cvat_canvas_shape_activated'); - cy.get('body').type('{Ctrl}3'); - cy.contains('tspan', `${firstLabelCurrentVal} 1 (manual)`).should('be.visible'); - cy.get('#cvat-objects-sidebar-state-item-1') - .find('.cvat-objects-sidebar-state-item-label-selector') - .should('have.text', firstLabelCurrentVal); - cy.checkCanvasSidebarColorEqualness(1); - }); }); }); From 5bf2ef42d0756d1deebdd74624a8a558c5490110 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 9 Sep 2024 00:00:15 +0300 Subject: [PATCH 5/9] Updated test --- .../e2e/actions_tasks/case_72_hotkeys_change_labels.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js index 6bd7ee4bb16..f2c154d421f 100644 --- a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js +++ b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js @@ -7,7 +7,7 @@ context('Hotkeys to change labels feature.', () => { const caseId = '72'; - const labelName = `Case ${caseId}`; + const labelName = `Case_${caseId}`; const taskName = labelName; const attrName = `Attr for ${labelName}`; const textDefaultValue = '2'; @@ -22,7 +22,7 @@ context('Hotkeys to change labels feature.', () => { const archivePath = `cypress/fixtures/${archiveName}`; const imagesFolder = `cypress/fixtures/${imageFileName}`; const directoryToArchive = imagesFolder; - const secondLabel = `Case ${caseId} second`; + const secondLabel = `Case_${caseId}_second`; const additionalAttrsSecondLabel = [{ name: attrName, values: '0;3;1', From efcff94a3728436dd1ad4b202a4efafd5b4fbd76 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 9 Sep 2024 13:51:44 +0300 Subject: [PATCH 6/9] Updated test --- .../cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js index f2c154d421f..dcc251a2505 100644 --- a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js +++ b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js @@ -71,7 +71,7 @@ context('Hotkeys to change labels feature.', () => { cy.get('.cvat-objects-sidebar-tabs').within(() => { cy.contains('[role="tab"]', 'Labels').click(); }); - cy.get('.cvat-objects-sidebar-label-item').then(($objectsSidebarLabelItem) => { + cy.get('.cvat-objects-sidebar-label-item .cvat-text').then(($objectsSidebarLabelItem) => { firstLabelCurrentVal = $objectsSidebarLabelItem[0].innerText.slice(0, -2); secondLabelCurrentVal = $objectsSidebarLabelItem[1].innerText.slice(0, -2); }); From 0741f6c060b511594031c187a9576d8fb674b1bd Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 9 Sep 2024 14:04:16 +0300 Subject: [PATCH 7/9] Removed extra fetch from storage --- .../standard-workspace/objects-side-bar/labels-list.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx index 703c03b5ffa..752ac43b5a1 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx @@ -38,8 +38,6 @@ function LabelsListComponent(): JSX.Element { const { labels, keyMap } = useSelector((state: CombinedState) => ({ labels: state.annotation.job.labels, - activeShapeType: state.annotation.drawing.activeShapeType, - activeObjectType: state.annotation.drawing.activeObjectType, keyMap: state.shortcuts.keyMap, }), shallowEqual); From f8e7344ec01aa669db14d8741f5a43789f3874ea Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 9 Sep 2024 14:07:37 +0300 Subject: [PATCH 8/9] Minor refactoring --- .../objects-side-bar/labels-list.tsx | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx index 752ac43b5a1..b01be3d359b 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/labels-list.tsx @@ -21,11 +21,13 @@ import { getCVATStore } from 'cvat-store'; const componentShortcuts: Record = {}; -for (const i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) { - componentShortcuts[`SWITCH_LABEL_${i}`] = { +const makeKey = (index: number) => `SWITCH_LABEL_${index}`; + +for (const index of [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) { + componentShortcuts[makeKey(index)] = { name: 'Switch label', description: 'Change label of a selected object or default label of the next created object if no one object is activated', - sequences: [`ctrl+${i}`], + sequences: [`ctrl+${index}`], nonActive: true, scope: ShortcutScope.OBJECTS_SIDEBAR, }; @@ -54,12 +56,13 @@ function LabelsListComponent(): JSX.Element { for (const [index, labelID] of Object.entries(keyToLabelMapping)) { if (labelID) { const labelName = labels.find((label: any) => label.id === labelID)?.name; - updatedComponentShortcuts[`SWITCH_LABEL_${index}`] = { - ...updatedComponentShortcuts[`SWITCH_LABEL_${index}`], + const key = makeKey(+index); + updatedComponentShortcuts[key] = { + ...updatedComponentShortcuts[key], nonActive: false, name: `Switch label to ${labelName}`, description: `Changes the label to ${labelName} for the activated - object or for the next drawn object if no objects are activated`, + object or for the next drawn object if no objects are activated`, }; } } @@ -112,9 +115,9 @@ function LabelsListComponent(): JSX.Element { const handlers: Record void> = {}; - for (const i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) { - handlers[`SWITCH_LABEL_${i}`] = (event: KeyboardEvent) => { - handleHelper(event, i); + for (const index of [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) { + handlers[makeKey(index)] = (event: KeyboardEvent) => { + handleHelper(event, index); }; } From 8e77970dc2f49209bb35a816130c2f3e7fd07040 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 9 Sep 2024 14:18:51 +0300 Subject: [PATCH 9/9] Updated test --- .../e2e/actions_tasks/case_72_hotkeys_change_labels.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js index dcc251a2505..a92813b8ac4 100644 --- a/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js +++ b/tests/cypress/e2e/actions_tasks/case_72_hotkeys_change_labels.js @@ -7,7 +7,7 @@ context('Hotkeys to change labels feature.', () => { const caseId = '72'; - const labelName = `Case_${caseId}`; + const labelName = `Case ${caseId}`; const taskName = labelName; const attrName = `Attr for ${labelName}`; const textDefaultValue = '2'; @@ -22,7 +22,7 @@ context('Hotkeys to change labels feature.', () => { const archivePath = `cypress/fixtures/${archiveName}`; const imagesFolder = `cypress/fixtures/${imageFileName}`; const directoryToArchive = imagesFolder; - const secondLabel = `Case_${caseId}_second`; + const secondLabel = `Case ${caseId} second`; const additionalAttrsSecondLabel = [{ name: attrName, values: '0;3;1', @@ -72,8 +72,8 @@ context('Hotkeys to change labels feature.', () => { cy.contains('[role="tab"]', 'Labels').click(); }); cy.get('.cvat-objects-sidebar-label-item .cvat-text').then(($objectsSidebarLabelItem) => { - firstLabelCurrentVal = $objectsSidebarLabelItem[0].innerText.slice(0, -2); - secondLabelCurrentVal = $objectsSidebarLabelItem[1].innerText.slice(0, -2); + firstLabelCurrentVal = $objectsSidebarLabelItem[0].innerText; + secondLabelCurrentVal = $objectsSidebarLabelItem[1].innerText; }); cy.get('.cvat-objects-sidebar-tabs').within(() => { cy.contains('[role="tab"]', 'Objects').click();