2076 - Item tags refactor
gitea/salix/2076-item_tags_refactor This commit looks good Details

This commit is contained in:
Joan Sanchez 2020-02-06 07:41:51 +01:00
parent 5a90c9a2d8
commit e3b1a4b58a
4 changed files with 63 additions and 33 deletions

View File

@ -9,6 +9,7 @@ export default class Button extends FormInput {
this.initTabIndex(); this.initTabIndex();
this.element.addEventListener('keyup', e => this.onKeyup(e)); this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e)); this.element.addEventListener('click', e => this.onClick(e));
this.button = this.element.querySelector('button');
} }
$onInit() { $onInit() {
@ -21,6 +22,8 @@ export default class Button extends FormInput {
switch (event.key) { switch (event.key) {
case ' ': case ' ':
case 'Enter': case 'Enter':
if (this.button)
return this.button.click();
return this.element.click(); return this.element.click();
} }
} }

View File

@ -128,31 +128,37 @@ export default class CrudModel extends ModelProxy {
} }
/** /**
* Returns an object with the unsaved changes made to the model. * Saves current changes on the server.
* *
* @return {Object} The current changes * @return {Promise} The save request promise
*/ */
getChanges() { save() {
if (!this.isChanged) if (!this.isChanged)
return null; return null;
let deletes = []; let deletes = [];
let updates = []; let updates = [];
let creates = []; let creates = [];
let orgDeletes = [];
let orgUpdates = [];
let orgCreates = [];
let pk = this.primaryKey; let pk = this.primaryKey;
for (let row of this.removed) for (let row of this.removed) {
deletes.push(row.$orgRow[pk]); deletes.push(row.$orgRow[pk]);
orgDeletes.push(row);
}
for (let row of this._data) { for (let row of this.data) {
if (row.$isNew) { if (row.$isNew) {
let data = {}; let data = {};
for (let prop in row) { for (let prop in row) {
if (prop.charAt(0) !== '$') if (prop.charAt(0) !== '$')
data[prop] = row[prop]; data[prop] = row[prop];
} }
creates.push(data); creates.push(row);
orgCreates.push(row);
} else if (row.$oldData) { } else if (row.$oldData) {
let data = {}; let data = {};
for (let prop in row.$oldData) for (let prop in row.$oldData)
@ -161,6 +167,7 @@ export default class CrudModel extends ModelProxy {
data, data,
where: {[pk]: row.$orgRow[pk]} where: {[pk]: row.$orgRow[pk]}
}); });
orgUpdates.push(row);
} }
} }
@ -171,23 +178,36 @@ export default class CrudModel extends ModelProxy {
changes[prop] = undefined; changes[prop] = undefined;
} }
return changes;
}
/**
* Saves current changes on the server.
*
* @return {Promise} The save request promise
*/
save() {
let changes = this.getChanges();
if (!changes) if (!changes)
return this.$q.resolve(); return this.$q.resolve();
let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`; let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`;
return this.$http.post(url, changes) return this.$http.post(url, changes)
.then(() => { .then(res => {
const newData = res.data;
const created = newData.created;
const updated = newData.updated;
// Apply new data to created instances
for (let i = 0; i < orgCreates.length; i++) {
const row = orgCreates[i];
row[pk] = created[i][pk];
for (let prop in row) {
if (prop.charAt(0) !== '$')
row[prop] = created[i][prop];
}
}
// Apply new data to updated instances
for (let i = 0; i < orgUpdates.length; i++) {
const row = orgUpdates[i];
for (let prop in row) {
if (prop.charAt(0) !== '$')
row[prop] = updated[i][prop];
}
}
this.applyChanges(); this.applyChanges();
super.save(); super.save();
}); });

View File

@ -50,7 +50,11 @@ module.exports = function(Self) {
description: `Instances to create`, description: `Instances to create`,
type: ['Object'] type: ['Object']
} }
] ],
returns: {
type: ['object'],
root: true
}
}); });
}, },
@ -60,27 +64,34 @@ module.exports = function(Self) {
try { try {
let options = {transaction: tx}; let options = {transaction: tx};
let deleted;
if (deletes) { if (deletes) {
let promises = []; let promises = [];
for (let id of deletes) for (let id of deletes)
promises.push(this.destroyById(id, options)); promises.push(this.destroyById(id, options));
await Promise.all(promises); deleted = await Promise.all(promises);
} }
let updated;
if (updates) { if (updates) {
let promises = []; let promises = [];
for (let update of updates) for (let update of updates)
promises.push(this.upsertWithWhere(update.where, update.data, options)); promises.push(this.upsertWithWhere(update.where, update.data, options));
await Promise.all(promises); updated = await Promise.all(promises);
} }
let created;
if (creates && creates.length) { if (creates && creates.length) {
try { try {
await this.create(creates, options); created = await this.create(creates, options);
} catch (error) { } catch (error) {
throw error[error.length - 1]; throw error[error.length - 1];
} }
} }
await tx.commit(); await tx.commit();
return {deleted, created, updated};
} catch (error) { } catch (error) {
await tx.rollback(); await tx.rollback();
throw error; throw error;

View File

@ -22,16 +22,14 @@
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md"> <form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal ng-repeat="itemTag in $ctrl.itemTags"> <vn-horizontal ng-repeat="itemTag in $ctrl.itemTags">
<vn-autocomplete <vn-autocomplete vn-one vn-id="tag" vn-focus
vn-one
vn-id="tag"
label="Tag" label="Tag"
initial-data="itemTag.tag" initial-data="itemTag.tag"
ng-model="itemTag.tagFk" ng-model="itemTag.tagFk"
data="tags" data="tags"
on-change="$ctrl.getSourceTable(tag)" on-change="$ctrl.getSourceTable(tag)"
show-field="name" show-field="name"
vn-focus> rule>
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
ng-show="tag.selection.isFree || tag.selection.isFree == undefined" ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
@ -41,24 +39,22 @@
ng-model="itemTag.value" ng-model="itemTag.value"
rule> rule>
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete vn-three
ng-show="tag.selection.isFree === false" ng-show="tag.selection.isFree === false"
vn-three
url="{{$ctrl.sourceTables[itemTag.id].url}}" url="{{$ctrl.sourceTables[itemTag.id].url}}"
search-function="{name: {like: '%'+ $search +'%'}}" search-function="{name: {like: '%'+ $search +'%'}}"
label="Value" label="Value"
ng-model="itemTag.value" ng-model="itemTag.value"
show-field="{{$ctrl.sourceTables[itemTag.id].field}}" show-field="{{$ctrl.sourceTables[itemTag.id].field}}"
value-field="{{$ctrl.sourceTables[itemTag.id].field}}"> value-field="{{$ctrl.sourceTables[itemTag.id].field}}"
rule>
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-input-number vn-one
tab-index="-1"
vn-one
type="number" type="number"
label="Relevancy" label="Relevancy"
ng-model="itemTag.priority" ng-model="itemTag.priority"
rule> rule>
</vn-textfield> </vn-input-number>
<vn-none> <vn-none>
<vn-icon-button <vn-icon-button
vn-tooltip="Remove tag" vn-tooltip="Remove tag"