Skip to content

Commit

Permalink
[CVAT-UI] Data annotation team requests and some fixes (cvat-ai#1753)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsekachev authored and Fernando Martínez González committed Aug 3, 2020
1 parent e79cda9 commit 4a3b099
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Implemented import and export of annotations with relative image paths (<https://github.com/opencv/cvat/pull/1463>)
- Using only single click to start editing or remove a point (<https://github.com/opencv/cvat/pull/1571>)
- Added support for attributes in VOC XML format (https://github.com/opencv/cvat/pull/1792)
- Colorized object items in the side panel (<https://github.com/opencv/cvat/pull/1753>)

### Deprecated
-
Expand All @@ -54,6 +55,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- A couple of exceptions in AAM related with early object activation (<https://github.com/opencv/cvat/pull/1755>)
- Propagation from the latest frame (<https://github.com/opencv/cvat/pull/1800>)
- Number attribute value validation (didn't work well with floats) (<https://github.com/opencv/cvat/pull/1800>)
- Annotations aren't updated after reopening a task (<https://github.com/opencv/cvat/pull/1753>)
- Labels aren't updated after reopening a task (<https://github.com/opencv/cvat/pull/1753>)
- Canvas isn't fitted after collapsing side panel in attribute annotation mode (<https://github.com/opencv/cvat/pull/1753>)


### Security
Expand Down
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.0.1",
"version": "3.1.0",
"description": "Part of Computer Vision Tool which presents an interface for client-side integration",
"main": "babel.config.js",
"scripts": {
Expand Down
10 changes: 10 additions & 0 deletions cvat-core/src/annotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@
}
}

async function closeSession(session) {
const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);

if (cache.has(session)) {
cache.delete(session);
}
}

async function getAnnotations(session, frame, allTracks, filters) {
const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
Expand Down Expand Up @@ -382,5 +391,6 @@
redoActions,
clearActions,
getActions,
closeSession,
};
})();
25 changes: 25 additions & 0 deletions cvat-core/src/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,21 @@
};
}

/**
* Method removes all task related data from the client (annotations, history, etc.)
* @method close
* @returns {module:API.cvat.classes.Task}
* @memberof module:API.cvat.classes.Task
* @readonly
* @async
* @instance
* @throws {module:API.cvat.exceptions.PluginError}
*/
async close() {
const result = await PluginRegistry.apiWrapper.call(this, Task.prototype.close);
return result;
}

/**
* Method updates data of a created task or creates new task from scratch
* @method save
Expand Down Expand Up @@ -1388,6 +1403,7 @@
redoActions,
clearActions,
getActions,
closeSession,
} = require('./annotations');

buildDublicatedAPI(Job.prototype);
Expand Down Expand Up @@ -1601,6 +1617,15 @@
return result;
};

Task.prototype.close.implementation = function closeTask() {
for (const job of this.jobs) {
closeSession(job);
}

closeSession(this);
return this;
};

Task.prototype.save.implementation = async function saveTaskImplementation(onUpdate) {
// TODO: Add ability to change an owner and an assignee
if (typeof (this.id) !== 'undefined') {
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/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-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.4.1",
"version": "1.4.2",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
20 changes: 13 additions & 7 deletions cvat-ui/src/actions/annotation-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,19 @@ export function confirmCanvasReady(): AnyAction {
};
}

export function closeJob(): ThunkAction<Promise<void>, {}, {}, AnyAction> {
return async (dispatch: ActionCreator<Dispatch>): Promise<void> => {
const { jobInstance } = receiveAnnotationsParameters();
if (jobInstance) {
await jobInstance.task.close();
}

dispatch({
type: AnnotationActionTypes.CLOSE_JOB,
});
};
}

export function getJobAsync(
tid: number,
jid: number,
Expand All @@ -918,13 +931,6 @@ export function getJobAsync(
const filters = initialFilters;
const { showAllInterpolationTracks } = state.settings.workspace;

// Check if already loaded job is different from asking one
if (state.annotation.job.instance && state.annotation.job.instance.id !== jid) {
dispatch({
type: AnnotationActionTypes.CLOSE_JOB,
});
}

dispatch({
type: AnnotationActionTypes.GET_JOB,
payload: {
Expand Down
3 changes: 2 additions & 1 deletion cvat-ui/src/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ $danger-icon-color: #ff4136;
$info-icon-color: #0074d9;
$objects-bar-tabs-color: #bebebe;
$objects-bar-icons-color: #242424; // #6e6e6e
$active-object-item-background-color: #d8ecff;
$active-label-background-color: #d8ecff;
$object-item-border-color: #000;
$slider-color: #1890ff;

$monospaced-fonts-stack: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Row, Col } from 'antd/lib/grid';
import Text from 'antd/lib/typography/Text';
import Icon from 'antd/lib/icon';

import { Canvas } from 'cvat-canvas-wrapper';
import { LogType } from 'cvat-logger';
import {
activateObject as activateObjectAction,
Expand All @@ -35,6 +36,7 @@ interface StateToProps {
jobInstance: any;
keyMap: Record<string, ExtendedKeyMapOptions>;
normalizedKeyMap: Record<string, string>;
canvasInstance: Canvas;
canvasIsReady: boolean;
}

Expand All @@ -60,6 +62,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
labels,
},
canvas: {
instance: canvasInstance,
ready: canvasIsReady,
},
},
Expand All @@ -77,6 +80,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
states,
keyMap,
normalizedKeyMap,
canvasInstance,
canvasIsReady,
};
}
Expand All @@ -103,6 +107,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
activateObject,
keyMap,
normalizedKeyMap,
canvasInstance,
canvasIsReady,
} = props;

Expand All @@ -115,6 +120,19 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.

const [sidebarCollapsed, setSidebarCollapsed] = useState(false);

const collapse = (): void => {
const [collapser] = window.document
.getElementsByClassName('attribute-annotation-sidebar');

if (collapser) {
collapser.addEventListener('transitionend', () => {
canvasInstance.fitCanvas();
}, { once: true });
}

setSidebarCollapsed(!sidebarCollapsed);
};

const [activeObjectState] = activatedStateID === null
? [null] : states.filter((objectState: any): boolean => (
objectState.clientID === activatedStateID
Expand Down Expand Up @@ -235,7 +253,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
className={`cvat-objects-sidebar-sider
ant-layout-sider-zero-width-trigger
ant-layout-sider-zero-width-trigger-left`}
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
onClick={collapse}
>
{sidebarCollapsed ? <Icon type='menu-fold' title='Show' />
: <Icon type='menu-unfold' title='Hide' />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ function ObjectItemComponent(props: Props): JSX.Element {
: 'cvat-objects-sidebar-state-item cvat-objects-sidebar-state-active-item';

return (
<div style={{ display: 'flex' }}>
<div style={{ display: 'flex', marginBottom: '1px' }}>
<Popover
placement='left'
trigger='click'
Expand All @@ -872,14 +872,14 @@ function ObjectItemComponent(props: Props): JSX.Element {
>
<div
className='cvat-objects-sidebar-state-item-color'
style={{ background: ` ${color}` }}
style={{ background: `${color}` }}
/>
</Popover>
<div
onMouseEnter={activate}
id={`cvat-objects-sidebar-state-item-${clientID}`}
className={className}
style={{ borderColor: ` ${color}` }}
style={{ backgroundColor: `${color}88` }}
>
<ItemTop
serverID={serverID}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,15 @@
overflow-y: auto;
}

.cvat-objects-sidebar-state-active-item {
background: $active-object-item-background-color;
.cvat-objects-sidebar-state-item.cvat-objects-sidebar-state-active-item {
border-top: 2px solid $object-item-border-color;
border-right: 2px solid $object-item-border-color;
border-bottom: 2px solid $object-item-border-color;
padding: 3px 1px 1px 3px;
}

.cvat-objects-sidebar-state-item-color {
border: 1px solid $object-item-border-color;
width: 7px;
opacity: 1;

Expand All @@ -122,7 +126,7 @@
.cvat-objects-sidebar-state-item {
width: 100%;
padding: 5px 3px 3px 3px;
border-bottom: 1px dashed;
opacity: 1;

> div:nth-child(1) {
> div:nth-child(1) {
Expand Down Expand Up @@ -218,7 +222,7 @@
}

.cvat-objects-sidebar-label-active-item {
background: $active-object-item-background-color;
background: $active-label-background-color;
}

.cvat-objects-sidebar-label-item {
Expand Down
4 changes: 2 additions & 2 deletions cvat-ui/src/components/header/settings-modal/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,6 @@
}
}

.cvat-settings-modal .ant-modal-body{
.cvat-settings-modal .ant-modal-body {
padding-top: 0;
}
}
37 changes: 24 additions & 13 deletions cvat-ui/src/containers/annotation-page/top-bar/top-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
searchAnnotationsAsync,
changeWorkspace as changeWorkspaceAction,
activateObject,
closeJob as closeJobAction,
} from 'actions/annotation-actions';
import { Canvas } from 'cvat-canvas-wrapper';

Expand Down Expand Up @@ -58,6 +59,7 @@ interface DispatchToProps {
redo(sessionInstance: any, frameNumber: any): void;
searchAnnotations(sessionInstance: any, frameFrom: any, frameTo: any): void;
changeWorkspace(workspace: Workspace): void;
closeJob(): void;
}

function mapStateToProps(state: CombinedState): StateToProps {
Expand Down Expand Up @@ -153,6 +155,9 @@ function mapDispatchToProps(dispatch: any): DispatchToProps {
dispatch(activateObject(null, null));
dispatch(changeWorkspaceAction(workspace));
},
closeJob(): void {
dispatch(closeJobAction());
},
};
}

Expand All @@ -177,13 +182,16 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
this.autoSaveInterval = window.setInterval(this.autoSave.bind(this), autoSaveInterval);

this.unblock = history.block((location: any) => {
if (jobInstance.annotations.hasUnsavedChanges() && location.pathname !== '/settings'
&& location.pathname !== `/tasks/${jobInstance.task.id}/jobs/${jobInstance.id}`) {
const { task, id: jobID } = jobInstance;
const { id: taskID } = task;

if (jobInstance.annotations.hasUnsavedChanges()
&& location.pathname !== `/tasks/${taskID}/jobs/${jobID}`) {
return 'You have unsaved changes, please confirm leaving this page.';
}
return undefined;
});
this.beforeUnloadCallback = this.beforeUnloadCallback.bind(this);

window.addEventListener('beforeunload', this.beforeUnloadCallback);
}

Expand Down Expand Up @@ -238,9 +246,11 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
}

public componentWillUnmount(): void {
const { closeJob } = this.props;
window.clearInterval(this.autoSaveInterval);
window.removeEventListener('beforeunload', this.beforeUnloadCallback);
this.unblock();
closeJob();
}

private undo = (): void => {
Expand Down Expand Up @@ -443,6 +453,17 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
copy(url);
};

private beforeUnloadCallback = (event: BeforeUnloadEvent): string | undefined => {
const { jobInstance } = this.props;
if (jobInstance.annotations.hasUnsavedChanges()) {
const confirmationMessage = 'You have unsaved changes, please confirm leaving this page.';
// eslint-disable-next-line no-param-reassign
event.returnValue = confirmationMessage;
return confirmationMessage;
}
return undefined;
};

private autoSave(): void {
const { autoSave, saving } = this.props;

Expand All @@ -458,16 +479,6 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
}
}

private beforeUnloadCallback(event: BeforeUnloadEvent): any {
const { jobInstance } = this.props;
if (jobInstance.annotations.hasUnsavedChanges()) {
const confirmationMessage = 'You have unsaved changes, please confirm leaving this page.';
// eslint-disable-next-line no-param-reassign
event.returnValue = confirmationMessage;
return confirmationMessage;
}
return undefined;
}

public render(): JSX.Element {
const {
Expand Down

0 comments on commit 4a3b099

Please sign in to comment.