Merge branch '2076-item_tags_refactor' of verdnatura/salix into dev
gitea/salix/dev This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2020-02-06 12:50:40 +00:00 committed by Gitea
commit 652e0e6071
6 changed files with 101 additions and 34 deletions

View File

@ -255,13 +255,13 @@ export default {
fourthRemoveTagButton: 'vn-item-tags vn-horizontal:nth-child(4) vn-icon-button[icon="delete"]',
fifthTag: 'vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete[ng-model="itemTag.tagFk"]',
fifthValue: 'vn-item-tags vn-horizontal:nth-child(5) vn-textfield[ng-model="itemTag.value"]',
fifthRelevancy: 'vn-item-tags vn-horizontal:nth-child(5) vn-textfield[ng-model="itemTag.priority"]',
fifthRelevancy: 'vn-item-tags vn-horizontal:nth-child(5) vn-input-number[ng-model="itemTag.priority"]',
sixthTag: 'vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete[ng-model="itemTag.tagFk"]',
sixthValue: 'vn-item-tags vn-horizontal:nth-child(6) vn-textfield[ng-model="itemTag.value"]',
sixthRelevancy: 'vn-item-tags vn-horizontal:nth-child(6) vn-textfield[ng-model="itemTag.priority"]',
sixthRelevancy: 'vn-item-tags vn-horizontal:nth-child(6) vn-input-number[ng-model="itemTag.priority"]',
seventhTag: 'vn-item-tags vn-horizontal:nth-child(7) > vn-autocomplete[ng-model="itemTag.tagFk"]',
seventhValue: 'vn-item-tags vn-horizontal:nth-child(7) vn-textfield[ng-model="itemTag.value"]',
seventhRelevancy: 'vn-item-tags vn-horizontal:nth-child(7) vn-textfield[ng-model="itemTag.priority"]',
seventhRelevancy: 'vn-item-tags vn-horizontal:nth-child(7) vn-input-number[ng-model="itemTag.priority"]',
addItemTagButton: 'vn-item-tags vn-icon-button[icon="add_circle"]',
submitItemTagsButton: 'vn-item-tags button[type=submit]'
},

View File

@ -9,6 +9,7 @@ export default class Button extends FormInput {
this.initTabIndex();
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
this.button = this.element.querySelector('button');
}
$onInit() {
@ -21,6 +22,8 @@ export default class Button extends FormInput {
switch (event.key) {
case ' ':
case 'Enter':
if (this.button)
return this.button.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)
return null;
let deletes = [];
let updates = [];
let creates = [];
let orgDeletes = [];
let orgUpdates = [];
let orgCreates = [];
let 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) {
for (let row of this.data) {
if (row.$isNew) {
let data = {};
for (let prop in row) {
if (prop.charAt(0) !== '$')
data[prop] = row[prop];
}
creates.push(data);
creates.push(row);
orgCreates.push(row);
} else if (row.$oldData) {
let data = {};
for (let prop in row.$oldData)
@ -161,6 +167,7 @@ export default class CrudModel extends ModelProxy {
data,
where: {[pk]: row.$orgRow[pk]}
});
orgUpdates.push(row);
}
}
@ -171,23 +178,25 @@ export default class CrudModel extends ModelProxy {
changes[prop] = undefined;
}
return changes;
}
/**
* Saves current changes on the server.
*
* @return {Promise} The save request promise
*/
save() {
let changes = this.getChanges();
if (!changes)
return this.$q.resolve();
let url = this.saveUrl ? this.saveUrl : `${this._url}/crud`;
return this.$http.post(url, changes)
.then(() => {
.then(res => {
const created = res.data;
// 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];
}
}
this.applyChanges();
super.save();
});

View File

@ -0,0 +1,50 @@
describe('Component vnCrudModel', () => {
let $httpBackend;
let controller;
let $element;
beforeEach(ngModule('vnCore'));
beforeEach(inject(($compile, $rootScope, _$httpBackend_) => {
$element = $compile(`<vn-crud-model></vn-crud-model>`)($rootScope);
$httpBackend = _$httpBackend_;
controller = $element.controller('vnCrudModel');
controller.orgData = [
{id: 1, value: 'My item 1'},
{id: 2, value: 'My item 2'}
];
controller.data = [
{id: 1, value: 'My item 1'},
{id: 2, value: 'My item 2'}
];
controller._url = 'Model';
}));
afterEach(() => {
$element.remove();
});
describe('save()', () => {
it(`should make an HTTP post query and then update the original rows with the returned values`, () => {
spyOn(controller, 'applyChanges');
controller.insert({value: 'My new item 1'});
controller.insert({value: 'My new item 2'});
$httpBackend.when('POST', 'Model/crud').respond([
{id: 3, value: 'My new item 1'},
{id: 4, value: 'My modified item 2'}
]);
controller.save();
$httpBackend.flush();
const thirdRow = controller.data[2];
const fourthRow = controller.data[3];
expect(thirdRow.id).toEqual(3);
expect(fourthRow.id).toEqual(4);
expect(fourthRow.value).toEqual('My modified item 2');
expect(controller.applyChanges).toHaveBeenCalledWith();
});
});
});

View File

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

View File

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