diff --git a/changelog.d/20240202_210037_sekachev.bs_update_dropdown_triggers.md b/changelog.d/20240202_210037_sekachev.bs_update_dropdown_triggers.md new file mode 100644 index 000000000000..d0077305e695 --- /dev/null +++ b/changelog.d/20240202_210037_sekachev.bs_update_dropdown_triggers.md @@ -0,0 +1,4 @@ +### Changed + +- Now menus in the web interface are triggered by click, not by hover as before + () diff --git a/cvat-ui/package.json b/cvat-ui/package.json index bf7b1bfbc599..21fe7cd13727 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.61.4", + "version": "1.62.0", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { diff --git a/cvat-ui/src/components/actions-menu/actions-menu.tsx b/cvat-ui/src/components/actions-menu/actions-menu.tsx index 62426c332684..6f17e335c8ac 100644 --- a/cvat-ui/src/components/actions-menu/actions-menu.tsx +++ b/cvat-ui/src/components/actions-menu/actions-menu.tsx @@ -1,26 +1,26 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT import './styles.scss'; import React, { useCallback } from 'react'; -import Menu from 'antd/lib/menu'; import Modal from 'antd/lib/modal'; import { LoadingOutlined } from '@ant-design/icons'; -// eslint-disable-next-line import/no-extraneous-dependencies -import { MenuInfo } from 'rc-menu/lib/interface'; -import { DimensionType } from 'cvat-core-wrapper'; +import { DimensionType, CVATCore } from 'cvat-core-wrapper'; +import Menu, { MenuInfo } from 'components/dropdown-menu'; import { usePlugins } from 'utils/hooks'; import { CombinedState } from 'reducers'; +type AnnotationFormats = Awaited>; + interface Props { taskID: number; projectID: number | null; taskMode: string; bugTracker: string; - loaders: any[]; - dumpers: any[]; + loaders: AnnotationFormats['loaders']; + dumpers: AnnotationFormats['dumpers']; inferenceIsActive: boolean; taskDimension: DimensionType; backupIsActive: boolean; @@ -137,7 +137,11 @@ function ActionsMenuComponent(props: Props): JSX.Element { ); return ( - + { menuItems.sort((menuItem1, menuItem2) => menuItem1[1] - menuItem2[1]) .map((menuItem) => menuItem[0]) } diff --git a/cvat-ui/src/components/annotation-page/canvas/views/canvas2d/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/canvas/views/canvas2d/canvas-wrapper.tsx index 03538135c9e5..1e2cdea614a5 100644 --- a/cvat-ui/src/components/annotation-page/canvas/views/canvas2d/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/canvas/views/canvas2d/canvas-wrapper.tsx @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -1118,7 +1118,12 @@ class CanvasWrapperComponent extends React.PureComponent { - }> + } + > diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/control-visibility-observer.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/control-visibility-observer.tsx index 792f29940162..6df9f56ee13a 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/control-visibility-observer.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/control-visibility-observer.tsx @@ -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 @@ -9,7 +9,6 @@ import { SmallDashOutlined } from '@ant-design/icons'; import Popover from 'antd/lib/popover'; import React, { useEffect, useRef, useState } from 'react'; import ReactDOM from 'react-dom'; -import { ConnectedComponent } from 'react-redux'; import withVisibilityHandling from './handle-popover-visibility'; const extraControlsContentClassName = 'cvat-extra-controls-control-content'; @@ -19,13 +18,14 @@ const CustomPopover = withVisibilityHandling(Popover, 'extra-controls'); export function ExtraControlsControl(): JSX.Element { const [hasChildren, setHasChildren] = useState(false); const [initialized, setInitialized] = useState(false); + const [visible, setVisible] = useState(true); useEffect(() => { if (!initialized) { setInitialized(true); } - window.document.body.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); + setVisible(false); }, []); onUpdateChildren = () => { @@ -37,7 +37,8 @@ export function ExtraControlsControl(): JSX.Element { return ( ( - ControlComponent: React.FunctionComponent

| ConnectedComponent, + ControlComponent: React.FunctionComponent

, ): React.FunctionComponent

{ let visibilityHeightThreshold = 0; // minimum value of height when element can be pushed to main panel diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx index 4f634ddc2bb8..8ebbfa893ace 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -7,10 +7,11 @@ import React from 'react'; import Layout from 'antd/lib/layout'; import { - ActiveControl, ObjectType, Rotation, ShapeType, CombinedState, + ActiveControl, Rotation, CombinedState, } from 'reducers'; import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import { Canvas, CanvasMode } from 'cvat-canvas-wrapper'; +import { LabelType } from 'cvat-core-wrapper'; import ControlVisibilityObserver, { ExtraControlsControl } from './control-visibility-observer'; import RotateControl, { Props as RotateControlProps } from './rotate-control'; @@ -105,14 +106,14 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { let tagControlVisible = withUnspecifiedType; const skeletonControlVisible = labels.some((label: Label) => label.type === 'skeleton'); labels.forEach((label: Label) => { - rectangleControlVisible = rectangleControlVisible || label.type === ShapeType.RECTANGLE; - polygonControlVisible = polygonControlVisible || label.type === ShapeType.POLYGON; - polylineControlVisible = polylineControlVisible || label.type === ShapeType.POLYLINE; - pointsControlVisible = pointsControlVisible || label.type === ShapeType.POINTS; - ellipseControlVisible = ellipseControlVisible || label.type === ShapeType.ELLIPSE; - cuboidControlVisible = cuboidControlVisible || label.type === ShapeType.CUBOID; - maskControlVisible = maskControlVisible || label.type === ShapeType.MASK; - tagControlVisible = tagControlVisible || label.type === ObjectType.TAG; + rectangleControlVisible = rectangleControlVisible || label.type === LabelType.RECTANGLE; + polygonControlVisible = polygonControlVisible || label.type === LabelType.POLYGON; + polylineControlVisible = polylineControlVisible || label.type === LabelType.POLYLINE; + pointsControlVisible = pointsControlVisible || label.type === LabelType.POINTS; + ellipseControlVisible = ellipseControlVisible || label.type === LabelType.ELLIPSE; + cuboidControlVisible = cuboidControlVisible || label.type === LabelType.CUBOID; + maskControlVisible = maskControlVisible || label.type === LabelType.MASK; + tagControlVisible = tagControlVisible || label.type === LabelType.TAG; }); const preventDefault = (event: KeyboardEvent | undefined): void => { 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 6ebe9579ddd1..03be784ec104 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,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -150,13 +150,11 @@ function DrawShapePopoverComponent(props: Props): JSX.Element { ) : null} - + - - {shapeType !== ShapeType.MASK && ( - + {shapeType !== ShapeType.MASK && ( - - + setColorPickerVisible(true)}> + + + ); } @@ -292,7 +276,11 @@ export default function ItemMenu(props: Props): JSX.Element { const is2D = jobInstance.dimension === DimensionType.DIMENSION_2D; return ( -

+ window.document.body.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))} + className='cvat-object-item-menu' + selectable={false} + > {!readonly && objectType !== ObjectType.TAG && ( diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss b/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss index d24862b91f89..5d61bd02f079 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss +++ b/cvat-ui/src/components/annotation-page/standard-workspace/styles.scss @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -9,8 +9,7 @@ height: 100%; > .ant-layout-content { - overflow-y: hidden; - overflow-x: hidden; + overflow: hidden hidden; } } @@ -27,8 +26,7 @@ .cvat-objects-sidebar { height: 100%; - overflow-y: auto; - overflow-x: hidden; + overflow: hidden auto; > .ant-layout-sider-children { display: flex; @@ -274,21 +272,16 @@ width: 100%; } - > div:last-child { - span { - width: 100%; + > div:last-child > div { + display: flex; + justify-content: space-between; + + &:has(.cvat-draw-mask-shape-button) { + justify-content: space-around; } button { - width: 100%; - - &:nth-child(1) { - border-radius: 3px 0 0 3px; - } - - &:nth-child(2) { - border-radius: 0 3px 3px 0; - } + width: $grid-unit-size * 15; } } } diff --git a/cvat-ui/src/components/annotation-page/styles.scss b/cvat-ui/src/components/annotation-page/styles.scss index ebf03fb22009..c802b3a1fb14 100644 --- a/cvat-ui/src/components/annotation-page/styles.scss +++ b/cvat-ui/src/components/annotation-page/styles.scss @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2023 CVAT.ai Corporation +// Copyright (C) 2023-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -460,7 +460,7 @@ .ant-modal-body { padding: 1px; - .recently-used-wrapper { + .cvat-recently-used-filters-wrapper { padding-top: $grid-unit-size * 2; } diff --git a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss index 7c6bd18272d6..713749ecde07 100644 --- a/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss +++ b/cvat-ui/src/components/annotation-page/tag-annotation-workspace/styles.scss @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2023 CVAT.ai Corporation +// Copyright (C) 2023-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -84,5 +84,5 @@ .cvat-add-tag-button { margin-left: $grid-unit-size; width: $grid-unit-size * 4; - height: $grid-unit-size * 3; + height: $grid-unit-size * 4; } 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 dac05ace0ac5..4a0272366960 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 @@ -1,5 +1,5 @@ // Copyright (C) 2020-2022 Intel Corporation -// Copyright (C) 2022 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT @@ -7,16 +7,15 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { withRouter, RouteComponentProps } from 'react-router'; -import Menu from 'antd/lib/menu'; import Modal from 'antd/lib/modal'; import Text from 'antd/lib/typography/Text'; import InputNumber from 'antd/lib/input-number'; import Checkbox from 'antd/lib/checkbox'; import Collapse from 'antd/lib/collapse'; -// eslint-disable-next-line import/no-extraneous-dependencies -import { MenuInfo } from 'rc-menu/lib/interface'; import CVATTooltip from 'components/common/cvat-tooltip'; +import Menu, { MenuInfo } from 'components/dropdown-menu'; + import { getCore, JobStage } from 'cvat-core-wrapper'; import AnnotationsActionsModalContent from '../annotations-actions/annotations-actions-modal'; @@ -187,7 +186,14 @@ function AnnotationMenuComponent(props: Props & RouteComponentProps): JSX.Elemen }; return ( - onClickMenuWrapper(params)} className='cvat-annotation-menu' selectable={false}> + { + onClickMenuWrapper(params); + }} + className='cvat-annotation-menu' + selectable={false} + > Upload annotations Export job dataset Remove annotations diff --git a/cvat-ui/src/components/annotation-page/top-bar/filters-modal.tsx b/cvat-ui/src/components/annotation-page/top-bar/filters-modal.tsx index b1f7ec1da6bb..7e54fcd34785 100644 --- a/cvat-ui/src/components/annotation-page/top-bar/filters-modal.tsx +++ b/cvat-ui/src/components/annotation-page/top-bar/filters-modal.tsx @@ -303,10 +303,15 @@ function FiltersModalComponent(): JSX.Element { >
- +
- )} + { + if (action.key === MenuKeys.RESEND_INVITATION) { + onResendInvitation(invitation.key); + } else if (action.key === MenuKeys.DELETE_INVITATION) { + onDeleteInvitation(invitation.key); + } + }} + > + Resend invitation + + Remove invitation +
+ )} > diff --git a/cvat-ui/src/components/organization-page/top-bar.tsx b/cvat-ui/src/components/organization-page/top-bar.tsx index bc4a700ca4b4..225410c1b10d 100644 --- a/cvat-ui/src/components/organization-page/top-bar.tsx +++ b/cvat-ui/src/components/organization-page/top-bar.tsx @@ -1,9 +1,10 @@ // Copyright (C) 2021-2022 Intel Corporation -// Copyright (C) 2022-2023 CVAT.ai Corporation +// Copyright (C) 2022-2024 CVAT.ai Corporation // // SPDX-License-Identifier: MIT import React, { useState, useRef, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import moment from 'moment'; import { Row, Col } from 'antd/lib/grid'; @@ -16,7 +17,6 @@ import Input from 'antd/lib/input'; import Form from 'antd/lib/form'; import Select from 'antd/lib/select'; import Dropdown from 'antd/lib/dropdown'; -import Menu from 'antd/lib/menu'; import { useForm } from 'antd/lib/form/Form'; import { Store } from 'antd/lib/form/interface'; @@ -31,7 +31,7 @@ import { removeOrganizationAsync, updateOrganizationAsync, } from 'actions/organization-actions'; -import { useHistory } from 'react-router-dom'; +import Menu from 'components/dropdown-menu'; export interface Props { organizationInstance: any; @@ -120,32 +120,35 @@ function OrganizationTopBar(props: Props): JSX.Element { - ( - - - { - e.preventDefault(); - history.push({ - pathname: '/organization/webhooks', - }); - return false; - }} - > - Setup webhooks - - - {owner && userID === owner.id ? ( - - Remove organization + ( + + + { + e.preventDefault(); + history.push({ + pathname: '/organization/webhooks', + }); + return false; + }} + > + Setup webhooks + - ) : null} - - )} + {owner && userID === owner.id ? ( + + Remove organization + + ) : null} + + )} >