diff --git a/CHANGELOG.md b/CHANGELOG.md index 14a492c09bf3..a54cc7ecdc40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- TDB +- The latest comment displayed in issues sidebar () ### Changed @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- TDB +- It was not possible to copy issue comment from issue dialog () ### Security diff --git a/cvat-canvas/package.json b/cvat-canvas/package.json index 19404cdedda0..e2fac71846e0 100644 --- a/cvat-canvas/package.json +++ b/cvat-canvas/package.json @@ -1,6 +1,6 @@ { "name": "cvat-canvas", - "version": "2.17.5", + "version": "2.17.6", "description": "Part of Computer Vision Annotation Tool which presents its canvas library", "main": "src/canvas.ts", "scripts": { diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index bd279d2c3a60..cfe1c9ce8aab 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -1258,13 +1258,11 @@ export class CanvasViewImpl implements CanvasView, Listener { window.document.addEventListener('keydown', this.onShiftKeyDown); window.document.addEventListener('keyup', this.onShiftKeyUp); - this.attachmentBoard.addEventListener('wheel', (event) => { - event.stopPropagation(); - }); - - this.attachmentBoard.addEventListener('mousemove', (event) => { - event.stopPropagation(); - }); + for (const eventName of ['wheel', 'mousedown', 'dblclick', 'contextmenu']) { + this.attachmentBoard.addEventListener(eventName, (event) => { + event.stopPropagation(); + }); + } this.canvas.addEventListener('wheel', (event): void => { if (event.ctrlKey) return; diff --git a/cvat-ui/package.json b/cvat-ui/package.json index ef151fdee642..4fbfa49cd725 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.57.1", + "version": "1.57.2", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { 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 747730b66e26..9518090b1406 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 @@ -8,7 +8,7 @@ import React, { } from 'react'; import ReactDOM from 'react-dom'; import Tag from 'antd/lib/tag'; -import { CheckCircleOutlined, CloseCircleOutlined, WarningOutlined } from '@ant-design/icons'; +import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'; import { Issue } from 'cvat-core-wrapper'; import CVATTooltip from 'components/common/cvat-tooltip'; @@ -63,7 +63,7 @@ export default function HiddenIssueLabel(props: Props): ReactPortal { const elementID = `cvat-hidden-issue-label-${id}`; return ReactDOM.createPortal( - + )} - {comments[0]?.message || } + {comments[0]?.message || null} , 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 3b4d1954ab79..36a6b2f5f382 100644 --- a/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx +++ b/cvat-ui/src/components/annotation-page/review/issue-dialog.tsx @@ -15,7 +15,6 @@ import Comment from 'antd/lib/comment'; import Text from 'antd/lib/typography/Text'; import Title from 'antd/lib/typography/Title'; import Button from 'antd/lib/button'; -import Spin from 'antd/lib/spin'; import Input from 'antd/lib/input'; import moment from 'moment'; import CVATTooltip from 'components/common/cvat-tooltip'; @@ -148,7 +147,9 @@ export default function IssueDialog(props: Props): JSX.Element { { - lines.length > 0 ? {lines} : + lines.length > 0 ? {lines} : ( + No comments found + ) } diff --git a/cvat-ui/src/components/annotation-page/review/styles.scss b/cvat-ui/src/components/annotation-page/review/styles.scss index aa246cec78cd..bb948207c495 100644 --- a/cvat-ui/src/components/annotation-page/review/styles.scss +++ b/cvat-ui/src/components/annotation-page/review/styles.scss @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -@import 'base.scss'; +@import 'base'; .cvat-create-issue-dialog { position: absolute; @@ -72,7 +72,6 @@ transform-origin: top left; box-shadow: $box-shadow-base; border-radius: 0.5 * $grid-unit-size; - opacity: 0.95; .cvat-issue-dialog-chat { > div { @@ -93,7 +92,7 @@ } } - border-radius: 0.5 * $grid-unit-size; + user-select: all; background: $background-color-1; padding: $grid-unit-size; max-height: $grid-unit-size * 45; 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 0c74413fd478..4499f3e28c1e 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 @@ -18,29 +18,29 @@ import CVATTooltip from 'components/common/cvat-tooltip'; import { ActiveControl, CombinedState, Workspace } from 'reducers'; import moment from 'moment'; import Paragraph from 'antd/lib/typography/Paragraph'; -import { ConflictSeverity, QualityConflict } from 'cvat-core-wrapper'; +import { ConflictSeverity, QualityConflict, Issue } from 'cvat-core-wrapper'; import { changeShowGroundTruth } from 'actions/settings-actions'; import { ShowGroundTruthIcon } from 'icons'; export default function LabelsListComponent(): JSX.Element { const dispatch = useDispatch(); const frame = useSelector((state: CombinedState): number => state.annotation.player.frame.number); - const frameIssues = useSelector((state: CombinedState): any[] => state.review.frameIssues); + const frameIssues = useSelector((state: CombinedState): Issue[] => state.review.frameIssues); const frameConflicts = useSelector((state: CombinedState) => state.review.frameConflicts); const showGroundTruth = useSelector((state: CombinedState) => state.settings.shapes.showGroundTruth); - const issues = useSelector((state: CombinedState): any[] => state.review.issues); + const issues = useSelector((state: CombinedState): Issue[] => state.review.issues); const conflicts = useSelector((state: CombinedState) => state.review.conflicts); - const issuesHidden = useSelector((state: CombinedState): any => state.review.issuesHidden); - const issuesResolvedHidden = useSelector((state: CombinedState): any => state.review.issuesResolvedHidden); + const issuesHidden = useSelector((state: CombinedState) => state.review.issuesHidden); + const issuesResolvedHidden = useSelector((state: CombinedState) => state.review.issuesResolvedHidden); const highlightedConflict = useSelector((state: CombinedState) => state.annotation.annotations.highlightedConflict); const workspace = useSelector((state: CombinedState) => state.annotation.workspace); const ready = useSelector((state: CombinedState) => state.annotation.canvas.ready); const activeControl = useSelector((state: CombinedState) => state.annotation.canvas.activeControl); - let frames = issues.map((issue: any): number => issue.frame).sort((a: number, b: number) => +a - +b); + let frames = issues.map((issue: Issue): number => issue.frame).sort((a: number, b: number) => +a - +b); if (showGroundTruth) { const conflictFrames = conflicts - .map((issue: any): number => issue.frame).sort((a: number, b: number) => +a - +b); + .map((conflict): number => conflict.frame).sort((a: number, b: number) => +a - +b); frames = [...new Set([...frames, ...conflictFrames])]; } const nearestLeft = frames.filter((_frame: number): boolean => _frame < frame).reverse()[0]; @@ -131,45 +131,74 @@ export default function LabelsListComponent(): JSX.Element {
{frameIssues.map( - (frameIssue: any): JSX.Element => ( -
{ - const element = window.document.getElementById( - `cvat_canvas_issue_region_${frameIssue.id}`, - ); - if (element) { - element.setAttribute('fill', 'url(#cvat_issue_region_pattern_2)'); - } - dispatch(activateObject(null, null, null)); - }} - onMouseLeave={() => { - const element = window.document.getElementById( - `cvat_canvas_issue_region_${frameIssue.id}`, - ); - if (element) { - element.setAttribute('fill', 'url(#cvat_issue_region_pattern_1)'); + (frameIssue: Issue): JSX.Element => { + const firstComment = frameIssue.comments[0]; + const lastComment = frameIssue.comments.slice(-1)[0]; + return ( +
- - {`#${frameIssue.id} • Issue`} - - - - {frameIssue.comments[0]?.message ? frameIssue.comments[0]?.message : ''} - - - - - {moment(frameIssue.createdDate).fromNow()} - -
- ), + onMouseEnter={() => { + const element = window.document.getElementById( + `cvat_canvas_issue_region_${frameIssue.id}`, + ); + if (element) { + element.setAttribute('fill', 'url(#cvat_issue_region_pattern_2)'); + } + dispatch(activateObject(null, null, null)); + }} + onMouseLeave={() => { + const element = window.document.getElementById( + `cvat_canvas_issue_region_${frameIssue.id}`, + ); + if (element) { + element.setAttribute('fill', 'url(#cvat_issue_region_pattern_1)'); + } + }} + > + + + + {`#${frameIssue.id} • Issue`} + + + + + {`created ${moment(frameIssue.createdDate).fromNow()}`} + + + + + + {!!firstComment?.owner?.username && ( + {`${firstComment.owner.username}: `} + )} + {firstComment?.message || ''} + + + { lastComment !== firstComment && ( + <> + + + + + + + + {!!lastComment?.owner?.username && ( + {`${lastComment.owner.username}: `} + )} + {lastComment?.message || ''} + + + + )} +
+ ); + }, )} {showGroundTruth && frameConflicts.map( (frameConflict: QualityConflict): 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 a34ebc704146..d2496a654209 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 @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: MIT -@import 'base.scss'; +@import 'base'; .cvat-objects-appearance-collapse.ant-collapse { width: 100%; @@ -123,6 +123,12 @@ padding: $grid-unit-size $grid-unit-size $grid-unit-size $grid-unit-size * 8; } + > .ant-row { + .ant-typography { + margin-bottom: 0; + } + } + p { margin-bottom: 0; } @@ -217,7 +223,7 @@ .cvat-objects-sidebar-state-item { width: 100%; - padding: 5px 3px 3px 3px; + padding: 5px 3px 3px; opacity: 1; > div:nth-child(1) { @@ -297,7 +303,7 @@ .cvat-object-item-radio-attribute { border: 1px double $border-color-hover; - border-radius: 7px 7px 7px 7px; + border-radius: 7px; > legend { text-align: center; @@ -316,7 +322,7 @@ > .ant-radio-group { display: grid; - padding: 1px 5px 1px 5px; + padding: 1px 5px; } } @@ -337,7 +343,7 @@ .cvat-objects-sidebar-label-item { height: 2.5em; border-bottom: 1px solid $border-color-1; - padding: 5px 3px 3px 3px; + padding: 5px 3px 3px; span { @extend .cvat-object-sidebar-icon; @@ -469,10 +475,6 @@ padding: $grid-unit-size * 0.5; border: 1px solid $object-item-border-color; border-bottom: 0; - padding-top: 1px; - padding-left: 1px; - padding-right: 1px; - padding-bottom: 2px; &:last-child { border-bottom: 1px solid $object-item-border-color; diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx index 8eb297feef86..a7ef3808ada9 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx @@ -488,8 +488,7 @@ class ObjectsListContainer extends React.PureComponent { updateAnnotations([state]); } }, - COPY_SHAPE: (event: KeyboardEvent | undefined) => { - preventDefault(event); + COPY_SHAPE: () => { const state = activatedState(); if (state && !readonly) { copyShape(state);