diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js index c4a09ae43b8d..ac464a1f053b 100644 --- a/cvat-core/src/session.js +++ b/cvat-core/src/session.js @@ -955,6 +955,7 @@ use_cache: undefined, copy_data: undefined, dimension: undefined, + allowed_annotation_mode: undefined, }; const updatedFields = new FieldUpdateTrigger({ @@ -1049,6 +1050,16 @@ description: { get: () => data.description, }, + /** + * @name allowedAnnotationMode + * @type {string} + * @memberof module:API.cvat.classes.Task + * @instance + * @throws {module:API.cvat.exceptions.ArgumentError} + */ + allowedAnnotationMode: { + get: () => data.allowed_annotation_mode, + }, /** * @name projectId * @type {integer|null} 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 47d76e24a80b..27df169c2e63 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 @@ -5,7 +5,7 @@ import React from 'react'; import Layout from 'antd/lib/layout'; -import { ActiveControl, Rotation } from 'reducers/interfaces'; +import { ActiveControl, Rotation, AllowedInstruments } from 'reducers/interfaces'; import GlobalHotKeys, { KeyMap } from 'utils/mousetrap-react'; import { Canvas } from 'cvat-canvas-wrapper'; @@ -33,6 +33,7 @@ interface Props { keyMap: KeyMap; normalizedKeyMap: Record; labels: any[]; + allowedAnnotationMode: string; mergeObjects(enabled: boolean): void; groupObjects(enabled: boolean): void; @@ -70,6 +71,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { normalizedKeyMap, keyMap, labels, + allowedAnnotationMode, mergeObjects, groupObjects, splitTrack, @@ -224,29 +226,33 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { + -
@@ -255,7 +261,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element { canvasInstance={canvasInstance} activeControl={activeControl} mergeObjects={mergeObjects} - disabled={!labels.length} + disabled={!labels.length || allowedAnnotationMode !== AllowedInstruments.POLYSHAPE} /> 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 d8c9c7615ddf..c1a1f66242c6 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 @@ -19,7 +19,7 @@ import getCore from 'cvat-core-wrapper'; import openCVWrapper from 'utils/opencv-wrapper/opencv-wrapper'; import { IntelligentScissors } from 'utils/opencv-wrapper/intelligent-scissors'; import { - CombinedState, ActiveControl, OpenCVTool, ObjectType, + CombinedState, ActiveControl, OpenCVTool, ObjectType, AllowedInstruments, } from 'reducers/interfaces'; import { interactWithCanvas, @@ -383,7 +383,9 @@ class OpenCVControlComponent extends React.PureComponent ) : ( ); } + if (jobInstance.task.allowedAnnotationMode === AllowedInstruments.TAG) { + if (ws === Workspace.STANDARD3D) { + return null; + } + return ( + + {ws} + + ); + } if (ws !== Workspace.STANDARD3D) { return ( - + {ws} ); diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx index f057ae6413d0..820565c0e66d 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/controls-side-bar/controls-side-bar.tsx @@ -26,6 +26,7 @@ interface StateToProps { keyMap: KeyMap; normalizedKeyMap: Record; labels: any[]; + type: string; } interface DispatchToProps { @@ -43,7 +44,12 @@ function mapStateToProps(state: CombinedState): StateToProps { const { annotation: { canvas: { instance: canvasInstance, activeControl }, - job: { labels }, + job: { + labels, + instance: { + task: { allowedAnnotationMode }, + }, + }, }, settings: { player: { rotateAll }, @@ -58,6 +64,7 @@ function mapStateToProps(state: CombinedState): StateToProps { labels, normalizedKeyMap, keyMap, + allowedAnnotationMode, }; } diff --git a/cvat-ui/src/reducers/interfaces.ts b/cvat-ui/src/reducers/interfaces.ts index 443383548d60..3961ca3c4b39 100644 --- a/cvat-ui/src/reducers/interfaces.ts +++ b/cvat-ui/src/reducers/interfaces.ts @@ -492,6 +492,12 @@ export enum Workspace { TAG_ANNOTATION = 'Tag annotation', } +export enum AllowedInstruments { + RECTANGLE = 'Rectangle', + POLYSHAPE = 'Polyshape', + TAG = 'Tag', +} + export enum GridColor { White = 'White', Black = 'Black', diff --git a/cvat/apps/engine/migrations/0045_task_allowed_annotation_mode.py b/cvat/apps/engine/migrations/0045_task_allowed_annotation_mode.py new file mode 100644 index 000000000000..f042600a8aa5 --- /dev/null +++ b/cvat/apps/engine/migrations/0045_task_allowed_annotation_mode.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.13 on 2021-10-25 15:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('engine', '0044_task_description'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='allowed_annotation_mode', + field=models.CharField(blank=True, default='', max_length=64), + ), + ] diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index 46f4207363d5..2b07875d0cd0 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -237,6 +237,7 @@ class Task(models.Model): dimension = models.CharField(max_length=2, choices=DimensionType.choices(), default=DimensionType.DIM_2D) subset = models.CharField(max_length=64, blank=True, default="") is_exchange_notified = models.BooleanField(default=False) + allowed_annotation_mode = models.CharField(max_length=64, blank=True, default="") # Extend default permission model class Meta: diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index e74f45e1b188..9bd214a24263 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -391,7 +391,7 @@ class Meta: 'bug_tracker', 'created_date', 'updated_date', 'overlap', 'segment_size', 'status', 'labels', 'segments', 'data_chunk_size', 'data_compressed_chunk_type', 'data_original_chunk_type', 'size', 'image_quality', - 'data', 'dimension', 'subset') + 'data', 'dimension', 'subset', 'allowed_annotation_mode') read_only_fields = ('mode', 'created_date', 'updated_date', 'status', 'data_chunk_size', 'owner', 'assignee', 'data_compressed_chunk_type', 'data_original_chunk_type', 'size', 'image_quality', 'data') write_once_fields = ('overlap', 'segment_size', 'project_id')