Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task moving between projects #3164

Merged
merged 39 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d1afcdd
Label name edition
ActiveChooN Feb 15, 2021
f000852
Added wrong label id handling
ActiveChooN Feb 15, 2021
34a877f
Restored missed logging
ActiveChooN Feb 15, 2021
5cd83f3
Merge branch 'dk/label-edit' into dk/tasks-move-between-projects
ActiveChooN Feb 15, 2021
22af7d2
temp
ActiveChooN Feb 21, 2021
574725e
Merge branch 'develop' into dk/tasks-move-between-projects
ActiveChooN Mar 19, 2021
4105af9
Merge branch 'develop' into dk/tasks-move-between-projects
ActiveChooN Apr 21, 2021
10b12f1
Merged develop into dk/tasks-move-between-projects
ActiveChooN Apr 21, 2021
4bb1553
Merge branch 'dk/tasks-move-between-projects' of https://github.com/o…
ActiveChooN Apr 21, 2021
6a6fbe1
Fixed merge issues
ActiveChooN Apr 21, 2021
92dc948
Merge branch 'develop' into dk/tasks-move-between-projects
ActiveChooN May 3, 2021
a11c503
Changed to new request schema
ActiveChooN May 4, 2021
d0276eb
Finished simplest move implementation
ActiveChooN May 6, 2021
5ff9865
Removed unused API method from cvat-core
ActiveChooN May 6, 2021
2d1b232
Added labels automapping
ActiveChooN May 7, 2021
d7bbdd9
Added moving from project to project
ActiveChooN May 7, 2021
c46d70f
Added proper validators
ActiveChooN May 11, 2021
583d28c
Merge branch 'develop' into dk/tasks-move-between-projects
ActiveChooN May 11, 2021
df7eef7
Fixed request performance
ActiveChooN May 11, 2021
3f08321
Fixed performance for task to project request
ActiveChooN May 11, 2021
e4be881
Merge branch 'dk/tasks-move-between-projects' of https://github.com/o…
ActiveChooN May 12, 2021
c4feb84
Fixed linters problems
ActiveChooN May 12, 2021
c87e838
Added server tests
ActiveChooN May 12, 2021
cd76047
Added CHANGELOG, increased packages version
ActiveChooN May 12, 2021
92e7f13
Update CHANGELOG.md
ActiveChooN May 13, 2021
28f37ec
Added special object for field updating
ActiveChooN May 14, 2021
16d390d
Update cvat-ui/src/reducers/notifications-reducer.ts
ActiveChooN May 14, 2021
325407e
Update cvat-ui/src/reducers/notifications-reducer.ts
ActiveChooN May 14, 2021
3916c52
Update cvat-ui/src/reducers/notifications-reducer.ts
ActiveChooN May 14, 2021
5fee08f
Fixed eslint issue
ActiveChooN May 14, 2021
56a9715
Simplified actions
ActiveChooN May 17, 2021
bde6e5b
Small fixes
ActiveChooN May 17, 2021
46860c9
Renamed values
ActiveChooN May 17, 2021
9b8533d
Merge branch 'develop' into dk/tasks-move-between-projects
May 20, 2021
f6adc0b
Fixed eslint issue
ActiveChooN May 20, 2021
f7833e0
Fixed incorrect merge from develop.
May 20, 2021
d2b2acc
Merge branch 'dk/tasks-move-between-projects' of github.com:openvinot…
May 20, 2021
dc82c04
Fixed cvat-core version
ActiveChooN May 20, 2021
bac8a97
Merge branch 'dk/tasks-move-between-projects' of https://github.com/o…
ActiveChooN May 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Hotkeys to switch a label of existing object or to change default label (for objects created with N) (<https://github.com/openvinotoolkit/cvat/pull/3070>)
- A script to convert some kinds of DICOM files to regular images (<https://github.com/openvinotoolkit/cvat/pull/3095>)
- Helm chart prototype (<https://github.com/openvinotoolkit/cvat/pull/3102>)
- Initial implementation of moving tasks between projects (<https://github.com/openvinotoolkit/cvat/pull/3164>)

### Changed

Expand Down
2 changes: 1 addition & 1 deletion cvat-core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-core",
"version": "3.13.0",
"version": "3.12.3",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "babel.config.js",
"scripts": {
Expand Down
32 changes: 32 additions & 0 deletions cvat-core/src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,37 @@
}
negativeIDGenerator.start = -1;

class FieldUpdateTrigger {
constructor(initialFields) {
const data = { ...initialFields };

Object.defineProperties(
this,
Object.freeze({
...Object.assign(
{},
...Array.from(Object.keys(data), (key) => ({
[key]: {
get: () => data[key],
set: (value) => {
data[key] = value;
},
enumerable: true,
},
})),
),
reset: {
value: () => {
Object.keys(data).forEach((key) => {
data[key] = false;
});
},
},
}),
);
}
}

module.exports = {
isBoolean,
isInteger,
Expand All @@ -114,5 +145,6 @@
negativeIDGenerator,
checkExclusiveFields,
camelToSnake,
FieldUpdateTrigger,
};
})();
4 changes: 3 additions & 1 deletion cvat-core/src/server-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,9 @@

const closureId = Date.now();
predictAnnotations.latestRequest.id = closureId;
const predicate = () => !predictAnnotations.latestRequest.fetching || predictAnnotations.latestRequest.id !== closureId;
const predicate = () => (
!predictAnnotations.latestRequest.fetching || predictAnnotations.latestRequest.id !== closureId
);
if (predictAnnotations.latestRequest.fetching) {
waitFor(5, predicate).then(() => {
if (predictAnnotations.latestRequest.id !== closureId) {
Expand Down
42 changes: 19 additions & 23 deletions cvat-core/src/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
const User = require('./user');
const Issue = require('./issue');
const Review = require('./review');
const { FieldUpdateTrigger } = require('./common');

function buildDublicatedAPI(prototype) {
Object.defineProperties(prototype, {
Expand Down Expand Up @@ -734,11 +735,11 @@
task: undefined,
};

let updatedFields = {
const updatedFields = new FieldUpdateTrigger({
assignee: false,
reviewer: false,
status: false,
};
});

for (const property in data) {
if (Object.prototype.hasOwnProperty.call(data, property)) {
Expand Down Expand Up @@ -865,9 +866,6 @@
},
__updatedFields: {
get: () => updatedFields,
set: (fields) => {
updatedFields = fields;
},
},
}),
);
Expand Down Expand Up @@ -1040,13 +1038,14 @@
dimension: undefined,
};

let updatedFields = {
const updatedFields = new FieldUpdateTrigger({
name: false,
assignee: false,
bug_tracker: false,
subset: false,
labels: false,
};
project_id: false,
});

for (const property in data) {
if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) {
Expand Down Expand Up @@ -1126,11 +1125,18 @@
* @name projectId
* @type {integer|null}
* @memberof module:API.cvat.classes.Task
* @readonly
* @instance
*/
projectId: {
get: () => data.project_id,
set: (projectId) => {
if (!Number.isInteger(projectId) || projectId <= 0) {
throw new ArgumentError('Value must be a positive integer');
}

updatedFields.project_id = true;
data.project_id = projectId;
},
},
/**
* @name status
Expand Down Expand Up @@ -1558,9 +1564,6 @@
},
__updatedFields: {
get: () => updatedFields,
set: (fields) => {
updatedFields = fields;
},
},
}),
);
Expand Down Expand Up @@ -1721,11 +1724,7 @@

await serverProxy.jobs.save(this.id, jobData);

this.__updatedFields = {
status: false,
assignee: false,
reviewer: false,
};
this.__updatedFields.reset();

return this;
}
Expand Down Expand Up @@ -2000,6 +1999,9 @@
case 'subset':
taskData.subset = this.subset;
break;
case 'project_id':
taskData.project_id = this.projectId;
break;
case 'labels':
taskData.labels = [...this._internalData.labels.map((el) => el.toJSON())];
break;
Expand All @@ -2011,13 +2013,7 @@

await serverProxy.tasks.saveTask(this.id, taskData);

this.updatedFields = {
assignee: false,
name: false,
bugTracker: false,
subset: false,
labels: false,
};
this.__updatedFields.reset();

return this;
}
Expand Down
44 changes: 44 additions & 0 deletions cvat-ui/src/actions/tasks-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export enum TasksActionTypes {
UPDATE_TASK_SUCCESS = 'UPDATE_TASK_SUCCESS',
UPDATE_TASK_FAILED = 'UPDATE_TASK_FAILED',
HIDE_EMPTY_TASKS = 'HIDE_EMPTY_TASKS',
SWITCH_MOVE_TASK_MODAL_VISIBLE = 'SWITCH_MOVE_TASK_MODAL_VISIBLE',
}

function getTasks(): AnyAction {
Expand Down Expand Up @@ -519,3 +520,46 @@ export function hideEmptyTasks(hideEmpty: boolean): AnyAction {

return action;
}

export function switchMoveTaskModalVisible(visible: boolean, taskId: number | null = null): AnyAction {
const action = {
type: TasksActionTypes.SWITCH_MOVE_TASK_MODAL_VISIBLE,
payload: {
taskId,
visible,
},
};

return action;
}

interface LabelMap {
label_id: number;
new_label_name: string | null;
clear_attributes: boolean;
}

export function moveTaskToProjectAsync(
taskInstance: any,
projectId: any,
labelMap: LabelMap[],
): ThunkAction<Promise<void>, {}, {}, AnyAction> {
return async (dispatch: ActionCreator<Dispatch>): Promise<void> => {
dispatch(updateTask());
try {
// eslint-disable-next-line no-param-reassign
taskInstance.labels = labelMap.map((mapper) => {
const [label] = taskInstance.labels.filter((_label: any) => mapper.label_id === _label.id);
label.name = mapper.new_label_name;
return label;
});
// eslint-disable-next-line no-param-reassign
taskInstance.projectId = projectId;
await taskInstance.save();
const [task] = await cvat.tasks.get({ id: taskInstance.id });
dispatch(updateTaskSuccess(task, task.id));
} catch (error) {
dispatch(updateTaskFailed(error, taskInstance));
}
};
}
1 change: 1 addition & 0 deletions cvat-ui/src/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ $layout-lg-grid-color: rgba(0, 0, 0, 0.15);

$header-color: #d8d8d8;
$text-color: #303030;
$text-color-secondary: rgba(0, 0, 0, 0.45);
$hover-menu-color: rgba(24, 144, 255, 0.05);
$completed-progress-color: #61c200;
$inprogress-progress-color: #1890ff;
Expand Down
2 changes: 2 additions & 0 deletions cvat-ui/src/components/actions-menu/actions-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export enum Actions {
EXPORT_TASK_DATASET = 'export_task_dataset',
DELETE_TASK = 'delete_task',
RUN_AUTO_ANNOTATION = 'run_auto_annotation',
MOVE_TASK_TO_PROJECT = 'move_task_to_project',
OPEN_BUG_TRACKER = 'open_bug_tracker',
}

Expand Down Expand Up @@ -128,6 +129,7 @@ export default function ActionsMenuComponent(props: Props): JSX.Element {
Automatic annotation
</Menu.Item>
<hr />
<Menu.Item key={Actions.MOVE_TASK_TO_PROJECT}>Move to project</Menu.Item>
<Menu.Item key={Actions.DELETE_TASK}>Delete</Menu.Item>
</Menu>
);
Expand Down
7 changes: 6 additions & 1 deletion cvat-ui/src/components/actions-menu/load-submenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ export default function LoadSubmenu(props: Props): JSX.Element {
return false;
}}
>
<Button block type='link' disabled={disabled} className='cvat-menu-load-submenu-item-button'>
<Button
block
type='link'
disabled={disabled}
className='cvat-menu-load-submenu-item-button'
>
<UploadOutlined />
<Text>{loader.name}</Text>
{pending && <LoadingOutlined style={{ marginLeft: 10 }} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MIT

import React, { useEffect, useState } from 'react';
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
import { SelectValue } from 'antd/lib/select';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const core = getCore();
type Props = {
value: number | null;
onSelect: (id: number | null) => void;
filter?: (value: Project, index: number, array: Project[]) => unknown
};

type Project = {
Expand All @@ -21,7 +22,7 @@ type Project = {
};

export default function ProjectSearchField(props: Props): JSX.Element {
const { value, onSelect } = props;
const { value, filter, onSelect } = props;
const [searchPhrase, setSearchPhrase] = useState('');

const [projects, setProjects] = useState<Project[]>([]);
Expand All @@ -43,8 +44,12 @@ export default function ProjectSearchField(props: Props): JSX.Element {
const handleFocus = (open: boolean): void => {
if (!projects.length && open) {
core.projects.searchNames().then((result: Project[]) => {
if (result) {
setProjects(result);
let projectsResponse = result;
if (typeof filter === 'function') {
projectsResponse = projectsResponse.filter(filter);
}
if (projectsResponse) {
setProjects(projectsResponse);
}
});
}
Expand Down
Loading