diff --git a/CHANGELOG.md b/CHANGELOG.md index eb9c68ec398c..57b9cb892c53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- +- PATCH requests from cvat-core submit only changed fields () ### Deprecated diff --git a/cvat-core/package-lock.json b/cvat-core/package-lock.json index 52e1e13811d5..10541c46426a 100644 --- a/cvat-core/package-lock.json +++ b/cvat-core/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-core", - "version": "3.9.0", + "version": "3.9.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/cvat-core/package.json b/cvat-core/package.json index 84140ddef9a3..bbb559549bcd 100644 --- a/cvat-core/package.json +++ b/cvat-core/package.json @@ -1,6 +1,6 @@ { "name": "cvat-core", - "version": "3.9.0", + "version": "3.9.1", "description": "Part of Computer Vision Tool which presents an interface for client-side integration", "main": "babel.config.js", "scripts": { diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js index 26483cc19af8..fba1a2ab1e0b 100644 --- a/cvat-core/src/session.js +++ b/cvat-core/src/session.js @@ -674,6 +674,11 @@ task: undefined, }; + let updatedFields = { + assignee: false, + status: false, + }; + for (const property in data) { if (Object.prototype.hasOwnProperty.call(data, property)) { if (property in initialData) { @@ -715,6 +720,7 @@ if (assignee !== null && !(assignee instanceof User)) { throw new ArgumentError('Value must be a user instance'); } + updatedFields.assignee = true; data.assignee = assignee; }, }, @@ -743,6 +749,7 @@ ); } + updatedFields.status = true; data.status = status; }, }, @@ -776,6 +783,12 @@ task: { get: () => data.task, }, + __updatedFields: { + get: () => updatedFields, + set: (fields) => { + updatedFields = fields; + }, + }, }), ); @@ -879,6 +892,13 @@ use_cache: undefined, }; + let updatedFields = { + name: false, + assignee: false, + bug_tracker: false, + labels: false, + }; + for (const property in data) { if (Object.prototype.hasOwnProperty.call(data, property) && property in initialData) { data[property] = initialData[property]; @@ -948,6 +968,7 @@ if (!value.trim().length) { throw new ArgumentError('Value must not be empty'); } + updatedFields.name = true; data.name = value; }, }, @@ -1006,6 +1027,7 @@ if (assignee !== null && !(assignee instanceof User)) { throw new ArgumentError('Value must be a user instance'); } + updatedFields.assignee = true; data.assignee = assignee; }, }, @@ -1039,6 +1061,7 @@ bugTracker: { get: () => data.bug_tracker, set: (tracker) => { + updatedFields.bug_tracker = true; data.bug_tracker = tracker; }, }, @@ -1145,6 +1168,7 @@ } } + updatedFields.labels = true; data.labels = [...labels]; }, }, @@ -1311,6 +1335,12 @@ dataChunkType: { get: () => data.data_compressed_chunk_type, }, + __updatedFields: { + get: () => updatedFields, + set: (fields) => { + updatedFields = fields; + }, + }, }), ); @@ -1443,12 +1473,30 @@ Job.prototype.save.implementation = async function () { // TODO: Add ability to change an assignee if (this.id) { - const jobData = { - status: this.status, - assignee_id: this.assignee ? this.assignee.id : null, - }; + const jobData = {}; + + for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { + if (isUpdated) { + switch (field) { + case 'status': + jobData.status = this.status; + break; + case 'assignee': + jobData.assignee_id = this.assignee ? this.assignee.id : null; + break; + default: + break; + } + } + } await serverProxy.jobs.saveJob(this.id, jobData); + + this.__updatedFields = { + status: false, + assignee: false, + }; + return this; } @@ -1653,14 +1701,38 @@ // TODO: Add ability to change an owner and an assignee if (typeof this.id !== 'undefined') { // If the task has been already created, we update it - const taskData = { - assignee_id: this.assignee ? this.assignee.id : null, - name: this.name, - bug_tracker: this.bugTracker, - labels: [...this.labels.map((el) => el.toJSON())], - }; + const taskData = {}; + + for (const [field, isUpdated] of Object.entries(this.__updatedFields)) { + if (isUpdated) { + switch (field) { + case 'assignee': + taskData.assignee_id = this.assignee ? this.assignee.id : null; + break; + case 'name': + taskData.name = this.name; + break; + case 'bug_tracker': + taskData.bug_tracker = this.bugTracker; + break; + case 'labels': + taskData.labels = [...this.labels.map((el) => el.toJSON())]; + break; + default: + break; + } + } + } await serverProxy.tasks.saveTask(this.id, taskData); + + this.updatedFields = { + assignee: false, + name: false, + bugTracker: false, + labels: false, + }; + return this; }