Skip to content

Commit bfd3000

Browse files
authored
React UI: Added logging (#1288)
1 parent 731b896 commit bfd3000

File tree

23 files changed

+867
-204
lines changed

23 files changed

+867
-204
lines changed

cvat-canvas/README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ Canvas itself handles:
3737
EXTREME_POINTS = 'By 4 points'
3838
}
3939

40+
enum Mode {
41+
IDLE = 'idle',
42+
DRAG = 'drag',
43+
RESIZE = 'resize',
44+
DRAW = 'draw',
45+
EDIT = 'edit',
46+
MERGE = 'merge',
47+
SPLIT = 'split',
48+
GROUP = 'group',
49+
DRAG_CANVAS = 'drag_canvas',
50+
ZOOM_CANVAS = 'zoom_canvas',
51+
}
52+
4053
interface DrawData {
4154
enabled: boolean;
4255
shapeType?: string;
@@ -70,6 +83,7 @@ Canvas itself handles:
7083
}
7184

7285
interface Canvas {
86+
mode(): Mode;
7387
html(): HTMLDivElement;
7488
setZLayer(zLayer: number | null): void;
7589
setup(frameData: any, objectStates: any[]): void;
@@ -128,14 +142,19 @@ Standard JS events are used.
128142
- canvas.dragstop
129143
- canvas.zoomstart
130144
- canvas.zoomstop
145+
- canvas.zoom
146+
- canvas.fit
147+
- canvas.dragshape => {id: number}
148+
- canvas.resizeshape => {id: number}
131149
```
132150

133151
### WEB
134152
```js
135153
// Create an instance of a canvas
136154
const canvas = new window.canvas.Canvas();
137155

138-
console.log('Version', window.canvas.CanvasVersion);
156+
console.log('Version ', window.canvas.CanvasVersion);
157+
console.log('Current mode is ', window.canvas.mode());
139158

140159
// Put canvas to a html container
141160
htmlContainer.appendChild(canvas.html());

cvat-canvas/src/typescript/canvasView.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
7474
return this.controller.mode;
7575
}
7676

77-
private onDrawDone(data: object, continueDraw?: boolean): void {
77+
private onDrawDone(data: object | null, duration: number, continueDraw?: boolean): void {
7878
if (data) {
7979
const { zLayer } = this.controller;
8080
const event: CustomEvent = new CustomEvent('canvas.drawn', {
@@ -87,6 +87,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
8787
zOrder: zLayer || 0,
8888
},
8989
continue: continueDraw,
90+
duration,
9091
},
9192
});
9293

@@ -137,12 +138,13 @@ export class CanvasViewImpl implements CanvasView, Listener {
137138
this.mode = Mode.IDLE;
138139
}
139140

140-
private onMergeDone(objects: any[]): void {
141+
private onMergeDone(objects: any[]| null, duration?: number): void {
141142
if (objects) {
142143
const event: CustomEvent = new CustomEvent('canvas.merged', {
143144
bubbles: false,
144145
cancelable: true,
145146
detail: {
147+
duration,
146148
states: objects,
147149
},
148150
});
@@ -701,6 +703,12 @@ export class CanvasViewImpl implements CanvasView, Listener {
701703
} else if ([UpdateReasons.IMAGE_ZOOMED, UpdateReasons.IMAGE_FITTED].includes(reason)) {
702704
this.moveCanvas();
703705
this.transformCanvas();
706+
if (reason === UpdateReasons.IMAGE_FITTED) {
707+
this.canvas.dispatchEvent(new CustomEvent('canvas.fit', {
708+
bubbles: false,
709+
cancelable: true,
710+
}));
711+
}
704712
} else if (reason === UpdateReasons.IMAGE_MOVED) {
705713
this.moveCanvas();
706714
} else if ([UpdateReasons.OBJECTS_UPDATED, UpdateReasons.SET_Z_LAYER].includes(reason)) {
@@ -1159,6 +1167,13 @@ export class CanvasViewImpl implements CanvasView, Listener {
11591167
).map((x: number): number => x - offset);
11601168

11611169
this.drawnStates[state.clientID].points = points;
1170+
this.canvas.dispatchEvent(new CustomEvent('canvas.dragshape', {
1171+
bubbles: false,
1172+
cancelable: true,
1173+
detail: {
1174+
id: state.clientID,
1175+
},
1176+
}));
11621177
this.onEditDone(state, points);
11631178
}
11641179
});
@@ -1209,6 +1224,13 @@ export class CanvasViewImpl implements CanvasView, Listener {
12091224
).map((x: number): number => x - offset);
12101225

12111226
this.drawnStates[state.clientID].points = points;
1227+
this.canvas.dispatchEvent(new CustomEvent('canvas.resizeshape', {
1228+
bubbles: false,
1229+
cancelable: true,
1230+
detail: {
1231+
id: state.clientID,
1232+
},
1233+
}));
12121234
this.onEditDone(state, points);
12131235
}
12141236
});

cvat-canvas/src/typescript/drawHandler.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export interface DrawHandler {
3131

3232
export class DrawHandlerImpl implements DrawHandler {
3333
// callback is used to notify about creating new shape
34-
private onDrawDone: (data: object, continueDraw?: boolean) => void;
34+
private onDrawDone: (data: object | null, duration?: number, continueDraw?: boolean) => void;
35+
private startTimestamp: number;
3536
private canvas: SVG.Container;
3637
private text: SVG.Container;
3738
private cursorPosition: {
@@ -180,7 +181,7 @@ export class DrawHandlerImpl implements DrawHandler {
180181
this.onDrawDone({
181182
shapeType,
182183
points: [xtl, ytl, xbr, ybr],
183-
});
184+
}, Date.now() - this.startTimestamp);
184185
}
185186
}).on('drawupdate', (): void => {
186187
this.shapeSizeElement.update(this.drawInstance);
@@ -213,7 +214,7 @@ export class DrawHandlerImpl implements DrawHandler {
213214
this.onDrawDone({
214215
shapeType,
215216
points: [xtl, ytl, xbr, ybr],
216-
});
217+
}, Date.now() - this.startTimestamp);
217218
}
218219
}
219220
}).on('undopoint', (): void => {
@@ -300,21 +301,21 @@ export class DrawHandlerImpl implements DrawHandler {
300301
this.onDrawDone({
301302
shapeType,
302303
points,
303-
});
304+
}, Date.now() - this.startTimestamp);
304305
} else if (shapeType === 'polyline'
305306
&& ((box.xbr - box.xtl) >= consts.SIZE_THRESHOLD
306307
|| (box.ybr - box.ytl) >= consts.SIZE_THRESHOLD)
307308
&& points.length >= 2 * 2) {
308309
this.onDrawDone({
309310
shapeType,
310311
points,
311-
});
312+
}, Date.now() - this.startTimestamp);
312313
} else if (shapeType === 'points'
313314
&& (e.target as any).getAttribute('points') !== '0,0') {
314315
this.onDrawDone({
315316
shapeType,
316317
points,
317-
});
318+
}, Date.now() - this.startTimestamp);
318319
}
319320
});
320321
}
@@ -365,7 +366,7 @@ export class DrawHandlerImpl implements DrawHandler {
365366
attributes: { ...this.drawData.initialState.attributes },
366367
label: this.drawData.initialState.label,
367368
color: this.drawData.initialState.color,
368-
}, e.detail.originalEvent.ctrlKey);
369+
}, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey);
369370
});
370371
}
371372

@@ -405,7 +406,7 @@ export class DrawHandlerImpl implements DrawHandler {
405406
attributes: { ...this.drawData.initialState.attributes },
406407
label: this.drawData.initialState.label,
407408
color: this.drawData.initialState.color,
408-
}, e.detail.originalEvent.ctrlKey);
409+
}, Date.now() - this.startTimestamp, e.detail.originalEvent.ctrlKey);
409410
});
410411
}
411412

@@ -583,14 +584,16 @@ export class DrawHandlerImpl implements DrawHandler {
583584
this.setupDrawEvents();
584585
}
585586

587+
this.startTimestamp = Date.now();
586588
this.initialized = true;
587589
}
588590

589591
public constructor(
590-
onDrawDone: (data: object, continueDraw?: boolean) => void,
592+
onDrawDone: (data: object | null, duration?: number, continueDraw?: boolean) => void,
591593
canvas: SVG.Container,
592594
text: SVG.Container,
593595
) {
596+
this.startTimestamp = Date.now();
594597
this.onDrawDone = onDrawDone;
595598
this.canvas = canvas;
596599
this.text = text;

cvat-canvas/src/typescript/mergeHandler.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ export interface MergeHandler {
1515

1616
export class MergeHandlerImpl implements MergeHandler {
1717
// callback is used to notify about merging end
18-
private onMergeDone: (objects: any[]) => void;
18+
private onMergeDone: (objects: any[] | null, duration?: number) => void;
1919
private onFindObject: (event: MouseEvent) => void;
20+
private startTimestamp: number;
2021
private canvas: SVG.Container;
2122
private initialized: boolean;
2223
private statesToBeMerged: any[]; // are being merged
@@ -57,6 +58,7 @@ export class MergeHandlerImpl implements MergeHandler {
5758

5859
private initMerging(): void {
5960
this.canvas.node.addEventListener('click', this.onFindObject);
61+
this.startTimestamp = Date.now();
6062
this.initialized = true;
6163
}
6264

@@ -66,7 +68,7 @@ export class MergeHandlerImpl implements MergeHandler {
6668
this.release();
6769

6870
if (statesToBeMerged.length > 1) {
69-
this.onMergeDone(statesToBeMerged);
71+
this.onMergeDone(statesToBeMerged, Date.now() - this.startTimestamp);
7072
} else {
7173
this.onMergeDone(null);
7274
// here is a cycle
@@ -77,12 +79,13 @@ export class MergeHandlerImpl implements MergeHandler {
7779
}
7880

7981
public constructor(
80-
onMergeDone: (objects: any[]) => void,
82+
onMergeDone: (objects: any[] | null, duration?: number) => void,
8183
onFindObject: (event: MouseEvent) => void,
8284
canvas: SVG.Container,
8385
) {
8486
this.onMergeDone = onMergeDone;
8587
this.onFindObject = onFindObject;
88+
this.startTimestamp = Date.now();
8689
this.canvas = canvas;
8790
this.statesToBeMerged = [];
8891
this.highlightedShapes = {};

cvat-core/src/api.js

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
function build() {
1616
const PluginRegistry = require('./plugins');
17-
const User = require('./user');
17+
const loggerStorage = require('./logger-storage');
18+
const Log = require('./log');
1819
const ObjectState = require('./object-state');
1920
const Statistics = require('./statistics');
2021
const { Job, Task } = require('./session');
@@ -41,6 +42,7 @@ function build() {
4142
ServerError,
4243
} = require('./exceptions');
4344

45+
const User = require('./user');
4446
const pjson = require('../package.json');
4547
const config = require('./config');
4648

@@ -419,6 +421,53 @@ function build() {
419421
return result;
420422
},
421423
},
424+
/**
425+
* Namespace to working with logs
426+
* @namespace logger
427+
* @memberof module:API.cvat
428+
*/
429+
/**
430+
* Method to logger configuration
431+
* @method configure
432+
* @memberof module:API.cvat.logger
433+
* @param {function} isActiveChecker - callback to know if logger
434+
* should increase working time or not
435+
* @param {object} userActivityCallback - container for a callback <br>
436+
* Logger put here a callback to update user activity timer <br>
437+
* You can call it outside
438+
* @instance
439+
* @async
440+
* @throws {module:API.cvat.exceptions.PluginError}
441+
* @throws {module:API.cvat.exceptions.ArgumentError}
442+
*/
443+
444+
/**
445+
* Append log to a log collection <br>
446+
* Durable logs will have been added after "close" method is called for them <br>
447+
* Ignore rules exist for some logs (e.g. zoomImage, changeAttribute) <br>
448+
* Payload of ignored logs are shallowly combined to previous logs of the same type
449+
* @method log
450+
* @memberof module:API.cvat.logger
451+
* @param {module:API.cvat.enums.LogType | string} type - log type
452+
* @param {Object} [payload = {}] - any other data that will be appended to the log
453+
* @param {boolean} [wait = false] - specifies if log is durable
454+
* @returns {module:API.cvat.classes.Log}
455+
* @instance
456+
* @async
457+
* @throws {module:API.cvat.exceptions.PluginError}
458+
* @throws {module:API.cvat.exceptions.ArgumentError}
459+
*/
460+
461+
/**
462+
* Save accumulated logs on a server
463+
* @method save
464+
* @memberof module:API.cvat.logger
465+
* @throws {module:API.cvat.exceptions.PluginError}
466+
* @throws {module:API.cvat.exceptions.ServerError}
467+
* @instance
468+
* @async
469+
*/
470+
logger: loggerStorage,
422471
/**
423472
* Namespace contains some changeable configurations
424473
* @namespace config
@@ -432,12 +481,6 @@ function build() {
432481
* @property {string} proxy Axios proxy settings.
433482
* For more details please read <a href="https://github.com/axios/axios"> here </a>
434483
* @memberof module:API.cvat.config
435-
* @property {integer} taskID this value is displayed in a logs if available
436-
* @memberof module:API.cvat.config
437-
* @property {integer} jobID this value is displayed in a logs if available
438-
* @memberof module:API.cvat.config
439-
* @property {integer} clientID read only auto-generated
440-
* value which is displayed in a logs
441484
* @memberof module:API.cvat.config
442485
*/
443486
get backendAPI() {
@@ -452,21 +495,6 @@ function build() {
452495
set proxy(value) {
453496
config.proxy = value;
454497
},
455-
get taskID() {
456-
return config.taskID;
457-
},
458-
set taskID(value) {
459-
config.taskID = value;
460-
},
461-
get jobID() {
462-
return config.jobID;
463-
},
464-
set jobID(value) {
465-
config.jobID = value;
466-
},
467-
get clientID() {
468-
return config.clientID;
469-
},
470498
},
471499
/**
472500
* Namespace contains some library information e.g. api version
@@ -524,6 +552,7 @@ function build() {
524552
Task,
525553
User,
526554
Job,
555+
Log,
527556
Attribute,
528557
Label,
529558
Statistics,

cvat-core/src/config.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,4 @@
66
module.exports = {
77
backendAPI: 'http://localhost:7000/api/v1',
88
proxy: false,
9-
taskID: undefined,
10-
jobID: undefined,
11-
clientID: +Date.now().toString().substr(-6),
129
};

0 commit comments

Comments
 (0)