From 3792a80ad53259be8c9035eeab044511d0bfd605 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 29 Dec 2022 14:24:32 +0100 Subject: [PATCH 1/9] =?UTF-8?q?refs=20#4925=20feat:=20a=C3=B1adido=20back?= =?UTF-8?q?=20para=20editar=20tags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/changes/230201/00-ACL_tag_update.sql | 3 + .../core/components/crud-model/crud-model.js | 47 +++++----- modules/item/back/methods/tag/onSubmit.js | 94 +++++++++++++++++++ modules/item/back/models/item-tag.js | 4 +- modules/item/back/models/tag.js | 1 + modules/item/front/tags/index.html | 9 +- modules/item/front/tags/index.js | 11 ++- 7 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 db/changes/230201/00-ACL_tag_update.sql create mode 100644 modules/item/back/methods/tag/onSubmit.js diff --git a/db/changes/230201/00-ACL_tag_update.sql b/db/changes/230201/00-ACL_tag_update.sql new file mode 100644 index 000000000..3c103e990 --- /dev/null +++ b/db/changes/230201/00-ACL_tag_update.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES + ('Tag', 'onSubmit', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/front/core/components/crud-model/crud-model.js b/front/core/components/crud-model/crud-model.js index 16b837d6a..10414daa3 100644 --- a/front/core/components/crud-model/crud-model.js +++ b/front/core/components/crud-model/crud-model.js @@ -147,28 +147,17 @@ export default class CrudModel extends ModelProxy { this.moreRows = null; } - /** - * Saves current changes on the server. - * - * @return {Promise} The save request promise - */ - save() { - if (!this.isChanged) - return this.$q.resolve(); + getChanges() { + if (!this.isChanged) return null; - let deletes = []; - let updates = []; - let creates = []; - let orgDeletes = []; - let orgUpdates = []; - let orgCreates = []; + const deletes = []; + const updates = []; + const creates = []; - let pk = this.primaryKey; + const pk = this.primaryKey; - for (let row of this.removed) { + for (let row of this.removed) deletes.push(row.$orgRow[pk]); - orgDeletes.push(row); - } for (let row of this.data) { if (row.$isNew) { @@ -178,7 +167,6 @@ export default class CrudModel extends ModelProxy { data[prop] = row[prop]; } creates.push(row); - orgCreates.push(row); } else if (row.$oldData) { let data = {}; for (let prop in row.$oldData) @@ -187,7 +175,6 @@ export default class CrudModel extends ModelProxy { data, where: {[pk]: row.$orgRow[pk]} }); - orgUpdates.push(row); } } @@ -198,8 +185,20 @@ export default class CrudModel extends ModelProxy { changes[prop] = undefined; } - if (!changes) - return this.$q.resolve(); + return changes; + } + + /** + * Saves current changes on the server. + * + * @return {Promise} The save request promise + */ + save() { + const pk = this.primaryKey; + const changes = this.getChanges(); + if (!changes) return this.$q.resolve(); + + const creates = changes.creates; let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`; return this.$http.post(url, changes) @@ -207,8 +206,8 @@ export default class CrudModel extends ModelProxy { const created = res.data; // Apply new data to created instances - for (let i = 0; i < orgCreates.length; i++) { - const row = orgCreates[i]; + for (let i = 0; i < creates.length; i++) { + const row = creates[i]; row[pk] = created[i][pk]; for (let prop in row) { diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js new file mode 100644 index 000000000..1bd33d3d4 --- /dev/null +++ b/modules/item/back/methods/tag/onSubmit.js @@ -0,0 +1,94 @@ + +module.exports = function(Self) { + Self.remoteMethodCtx('onSubmit', { + description: 'Creates client address updating default address', + accessType: 'WRITE', + accepts: [ + { + arg: 'creates', + type: ['object'], + description: 'The itemTags records to create' + }, { + arg: 'deletes', + type: ['number'], + description: 'The itemTags ids to delete' + }, { + arg: 'updates', + type: ['object'], + description: 'The itemTags records to update' + }, { + arg: 'maxPriority', + type: 'number', + description: 'The maxPriority value' + } + ], + returns: { + root: true, + type: 'object' + }, + http: { + verb: 'PATCH', + path: '/onSubmit' + } + }); + + Self.onSubmit = async(ctx, options) => { + const models = Self.app.models; + const args = ctx.args; + let tx; + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const promises = []; + + if (args.deletes) { + for (const itemTagId of args.deletes) { + const itemTagDeleted = await models.ItemTag.destroyById(itemTagId, myOptions); + promises.push(itemTagDeleted); + } + } + + if (args.updates) { + console.log('args.updates', args.updates); + for (const row of args.updates) { + if (row.data.priority) { + const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); + const itemTagUpdatedPriority = await itemTag.updateAttributes({ + priority: row.data.priority + args.maxPriority + }, myOptions); + promises.push(itemTagUpdatedPriority); + } + } + for (const row of args.updates) { + const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); + const itemTagUpdated = await itemTag.updateAttributes(row.data, myOptions); + promises.push(itemTagUpdated); + } + } + + if (args.creates) { + for (const itemTag of args.creates) { + const newItemTag = await models.ItemTag.create(itemTag, myOptions); + promises.push(newItemTag); + } + } + + const resolvedPromises = await Promise.all(promises); + + if (tx) await tx.commit(); + + return resolvedPromises; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/item/back/models/item-tag.js b/modules/item/back/models/item-tag.js index 5b7163913..4fd44270a 100644 --- a/modules/item/back/models/item-tag.js +++ b/modules/item/back/models/item-tag.js @@ -4,8 +4,8 @@ module.exports = Self => { require('../methods/item-tag/filterItemTags')(Self); Self.rewriteDbError(function(err) { - if (err.code === 'ER_DUP_ENTRY') - return new UserError(`The tag or priority can't be repeated for an item`); + // if (err.code === 'ER_DUP_ENTRY') + // return new UserError(`The tag or priority can't be repeated for an item`); if (err.code === 'ER_BAD_NULL_ERROR') return new UserError(`Tag value cannot be blank`); return err; diff --git a/modules/item/back/models/tag.js b/modules/item/back/models/tag.js index 43fbc0db3..92760e34f 100644 --- a/modules/item/back/models/tag.js +++ b/modules/item/back/models/tag.js @@ -1,3 +1,4 @@ module.exports = Self => { require('../methods/tag/filterValue')(Self); + require('../methods/tag/onSubmit')(Self); }; diff --git a/modules/item/front/tags/index.html b/modules/item/front/tags/index.html index c040b9984..471a53634 100644 --- a/modules/item/front/tags/index.html +++ b/modules/item/front/tags/index.html @@ -19,7 +19,7 @@ data="tags" auto-load="true"> -
+ - - + -
\ No newline at end of file + diff --git a/modules/item/front/tags/index.js b/modules/item/front/tags/index.js index 3b3cd58ef..b5c1fa7f9 100644 --- a/modules/item/front/tags/index.js +++ b/modules/item/front/tags/index.js @@ -29,8 +29,15 @@ class Controller extends Section { } onSubmit() { - this.$.watcher.check(); - this.$.model.save().then(() => { + const changes = this.$.model.getChanges(); + console.log(changes); + const data = { + creates: changes.creates, + deletes: changes.deletes, + updates: changes.updates, + maxPriority: this.getHighestPriority() + }; + this.$http.patch(`Tags/onSubmit`, data).then(() => { this.$.watcher.notifySaved(); this.$.watcher.updateOriginalData(); this.card.reload(); From 22d0da273e3e027b0d59c5195de013d698af19a9 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:21:51 +0100 Subject: [PATCH 2/9] =?UTF-8?q?refs=20#4925=20fix:=20coge=20=C3=BAnicament?= =?UTF-8?q?e=20los=20=C3=BAltimos=20cambios=20aplicados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/item/front/tags/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/item/front/tags/index.js b/modules/item/front/tags/index.js index b5c1fa7f9..bfa1f3f46 100644 --- a/modules/item/front/tags/index.js +++ b/modules/item/front/tags/index.js @@ -30,7 +30,6 @@ class Controller extends Section { onSubmit() { const changes = this.$.model.getChanges(); - console.log(changes); const data = { creates: changes.creates, deletes: changes.deletes, @@ -38,9 +37,9 @@ class Controller extends Section { maxPriority: this.getHighestPriority() }; this.$http.patch(`Tags/onSubmit`, data).then(() => { + this.$.model.refresh(); this.$.watcher.notifySaved(); this.$.watcher.updateOriginalData(); - this.card.reload(); }); } } From fec965a8ddb79ba35c0d1800e9be2a32531a2a75 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:29:27 +0100 Subject: [PATCH 3/9] =?UTF-8?q?refs=204925=20refactor:=20borrados=20consol?= =?UTF-8?q?e.log=20y=20actualizada=20descripci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/item/back/methods/tag/onSubmit.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js index 1bd33d3d4..b80b80d90 100644 --- a/modules/item/back/methods/tag/onSubmit.js +++ b/modules/item/back/methods/tag/onSubmit.js @@ -1,7 +1,7 @@ module.exports = function(Self) { Self.remoteMethodCtx('onSubmit', { - description: 'Creates client address updating default address', + description: 'Save model changes', accessType: 'WRITE', accepts: [ { @@ -57,7 +57,6 @@ module.exports = function(Self) { } if (args.updates) { - console.log('args.updates', args.updates); for (const row of args.updates) { if (row.data.priority) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); From 21a62a0fab016623b0993be5b7ade9e3cddc8940 Mon Sep 17 00:00:00 2001 From: vicent Date: Tue, 3 Jan 2023 13:29:44 +0100 Subject: [PATCH 4/9] refactor --- modules/item/back/models/item-tag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/item/back/models/item-tag.js b/modules/item/back/models/item-tag.js index 4fd44270a..5b7163913 100644 --- a/modules/item/back/models/item-tag.js +++ b/modules/item/back/models/item-tag.js @@ -4,8 +4,8 @@ module.exports = Self => { require('../methods/item-tag/filterItemTags')(Self); Self.rewriteDbError(function(err) { - // if (err.code === 'ER_DUP_ENTRY') - // return new UserError(`The tag or priority can't be repeated for an item`); + if (err.code === 'ER_DUP_ENTRY') + return new UserError(`The tag or priority can't be repeated for an item`); if (err.code === 'ER_BAD_NULL_ERROR') return new UserError(`Tag value cannot be blank`); return err; From 3edc0403ba3a744b11ea2c618227709de72c322b Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:42 +0100 Subject: [PATCH 5/9] fix --- front/core/components/crud-model/crud-model.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/front/core/components/crud-model/crud-model.js b/front/core/components/crud-model/crud-model.js index 10414daa3..421a79f9b 100644 --- a/front/core/components/crud-model/crud-model.js +++ b/front/core/components/crud-model/crud-model.js @@ -178,7 +178,7 @@ export default class CrudModel extends ModelProxy { } } - let changes = {deletes, updates, creates}; + const changes = {deletes, updates, creates}; for (let prop in changes) { if (changes[prop].length === 0) @@ -198,8 +198,7 @@ export default class CrudModel extends ModelProxy { const changes = this.getChanges(); if (!changes) return this.$q.resolve(); - const creates = changes.creates; - + const creates = changes.creates || []; let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`; return this.$http.post(url, changes) .then(res => { From fd9ca3a4c13d7283dc6be959c9fb1999ee06a700 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:49 +0100 Subject: [PATCH 6/9] add test --- .../back/methods/tag/specs/onSubmit.spec.js | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 modules/item/back/methods/tag/specs/onSubmit.spec.js diff --git a/modules/item/back/methods/tag/specs/onSubmit.spec.js b/modules/item/back/methods/tag/specs/onSubmit.spec.js new file mode 100644 index 000000000..a8077db67 --- /dev/null +++ b/modules/item/back/methods/tag/specs/onSubmit.spec.js @@ -0,0 +1,100 @@ +const models = require('vn-loopback/server/server').models; + +describe('tag onSubmit()', () => { + it('should delete a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const deletes = [40]; + const ctx = { + args: { + deletes: deletes + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should update a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const updates = [{data: {value: 'Container Test'}, where: {id: 36}}]; + const ctx = { + args: { + updates: updates + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should create a tag', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const creates = [{ + 'itemFk': '6', + 'priority': 8, + '$orgIndex': null, + '$oldData': null, + '$isNew': true, + 'tagFk': 3, + 'value': 'madera' + }]; + const ctx = { + args: { + creates: creates + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(1); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should swap priority for two tags', async() => { + const tx = await models.Item.beginTransaction({}); + const options = {transaction: tx}; + + try { + const updates = [ + {data: {priority: 2}, where: {id: 36}}, + {data: {priority: 1}, where: {id: 37}} + ]; + const ctx = { + args: { + updates: updates, + maxPriority: 7, + + } + }; + const result = await models.Tag.onSubmit(ctx, options); + + expect(result.length).toEqual(4); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); From 3abbfc4fa7c9fa3c595caffed38aa5633f1fc096 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 5 Jan 2023 10:35:55 +0100 Subject: [PATCH 7/9] refacotr --- CHANGELOG.md | 1 + modules/item/front/tags/index.html | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7073dc53..4e45bb760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - [General] Al utilizar el traductor de Google se descuadraban los iconos +- [Artículos](Etiquetas) Permite intercambiar la relevancia entre dos etiquetas. ### Removed - [Tickets](Control clientes) Eliminada sección diff --git a/modules/item/front/tags/index.html b/modules/item/front/tags/index.html index 471a53634..f9b5370fa 100644 --- a/modules/item/front/tags/index.html +++ b/modules/item/front/tags/index.html @@ -73,10 +73,10 @@ - - + From e4603a06f2d9e92f95e0198c9918ee6e752167e1 Mon Sep 17 00:00:00 2001 From: vicent Date: Thu, 12 Jan 2023 08:59:24 +0100 Subject: [PATCH 8/9] refacotor: borrados los await para que devuelva la promesa --- modules/item/back/methods/tag/onSubmit.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/item/back/methods/tag/onSubmit.js b/modules/item/back/methods/tag/onSubmit.js index b80b80d90..aec67e92a 100644 --- a/modules/item/back/methods/tag/onSubmit.js +++ b/modules/item/back/methods/tag/onSubmit.js @@ -51,7 +51,7 @@ module.exports = function(Self) { if (args.deletes) { for (const itemTagId of args.deletes) { - const itemTagDeleted = await models.ItemTag.destroyById(itemTagId, myOptions); + const itemTagDeleted = models.ItemTag.destroyById(itemTagId, myOptions); promises.push(itemTagDeleted); } } @@ -60,7 +60,7 @@ module.exports = function(Self) { for (const row of args.updates) { if (row.data.priority) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdatedPriority = await itemTag.updateAttributes({ + const itemTagUpdatedPriority = itemTag.updateAttributes({ priority: row.data.priority + args.maxPriority }, myOptions); promises.push(itemTagUpdatedPriority); @@ -68,14 +68,14 @@ module.exports = function(Self) { } for (const row of args.updates) { const itemTag = await models.ItemTag.findById(row.where.id, null, myOptions); - const itemTagUpdated = await itemTag.updateAttributes(row.data, myOptions); + const itemTagUpdated = itemTag.updateAttributes(row.data, myOptions); promises.push(itemTagUpdated); } } if (args.creates) { for (const itemTag of args.creates) { - const newItemTag = await models.ItemTag.create(itemTag, myOptions); + const newItemTag = models.ItemTag.create(itemTag, myOptions); promises.push(newItemTag); } } From c77f1b17a60b72f0ec7d0dfde4803742ca9f17b1 Mon Sep 17 00:00:00 2001 From: vicent Date: Fri, 20 Jan 2023 08:32:18 +0100 Subject: [PATCH 9/9] movida sql a nueva carpeta changes --- db/changes/{230201 => 230401}/00-ACL_tag_update.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/changes/{230201 => 230401}/00-ACL_tag_update.sql (100%) diff --git a/db/changes/230201/00-ACL_tag_update.sql b/db/changes/230401/00-ACL_tag_update.sql similarity index 100% rename from db/changes/230201/00-ACL_tag_update.sql rename to db/changes/230401/00-ACL_tag_update.sql