Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into dev
This commit is contained in:
commit
fb4a4cd3de
|
@ -0,0 +1,32 @@
|
|||
module.exports = function(Self) {
|
||||
Self.remoteMethodCtx('getConfig', {
|
||||
description: 'returns the information from UserConfig model for the active user',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'ctx',
|
||||
type: 'Object',
|
||||
http: {source: 'context'}
|
||||
}, {
|
||||
arg: 'tableCode',
|
||||
type: 'String',
|
||||
description: `Code of the table you ask its configuration`
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getConfig`,
|
||||
verb: 'get'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getConfig = async ctx => {
|
||||
let userView = await Self.app.models.UserConfigView.findOne({
|
||||
where: {tableCode: ctx.args.tableCode, userFk: ctx.req.accessToken.userId}
|
||||
});
|
||||
|
||||
return userView;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
module.exports = function(Self) {
|
||||
Self.remoteMethodCtx('save', {
|
||||
description: 'returns the information from UserConfig model for the active user',
|
||||
accepts: [{
|
||||
arg: 'config',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: `Code of the table you ask its configuration`,
|
||||
http: {source: 'body'}
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/save`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.save = async(ctx, config) => {
|
||||
let userView = await Self.app.models.UserConfigView.findOne({
|
||||
where: {tableCode: config.tableCode, userFk: ctx.req.accessToken.userId}
|
||||
});
|
||||
|
||||
if (userView)
|
||||
return userView.updateAttributes(config);
|
||||
|
||||
config.userFk = ctx.req.accessToken.userId;
|
||||
|
||||
return await Self.app.models.UserConfigView.create(config);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/user-config-view/getConfig')(Self);
|
||||
require('../methods/user-config-view/save')(Self);
|
||||
};
|
|
@ -9,7 +9,10 @@
|
|||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"type": "Number"
|
||||
},
|
||||
"userFk": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"tableCode": {
|
||||
|
@ -17,7 +20,7 @@
|
|||
"required": true
|
||||
},
|
||||
"configuration": {
|
||||
"type": "String"
|
||||
"type": "Object"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div>
|
||||
<div class="table">
|
||||
<vn-empty-rows ng-if="$ctrl.model && !$ctrl.model.data" translate>
|
||||
Enter a new search
|
||||
</vn-empty-rows>
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class Table {
|
|||
this.autoLoad = true;
|
||||
|
||||
$transclude($scope.$parent, clone => {
|
||||
angular.element($element[0].querySelector('div')).append(clone);
|
||||
angular.element($element[0].querySelector('.table')).append(clone);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@ import './visible-by';
|
|||
import './bind';
|
||||
import './repeat-last';
|
||||
import './title';
|
||||
import './uvc';
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<div style="position: relative;">
|
||||
<div style="position: absolute; top: 0; left: 0; padding: .5em; z-index: 1">
|
||||
<vn-icon-button
|
||||
icon="menu"
|
||||
style="font-size: .4em;"
|
||||
ng-click="$ctrl.showUvc($event)">
|
||||
</vn-icon-button>
|
||||
<vn-dialog
|
||||
class="modal-form"
|
||||
vn-id="uvc">
|
||||
<tpl-body>
|
||||
<vn-horizontal pad-medium class="header">
|
||||
<h5><span translate>Fields to show</span></h5>
|
||||
</vn-horizontal>
|
||||
<div pad-medium>
|
||||
<vn-horizontal ng-repeat="field in fields">
|
||||
<vn-check
|
||||
vn-one label="{{field}}"
|
||||
field="tableConfiguration.configuration[field]">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-button
|
||||
label="Save"
|
||||
ng-click="$ctrl.saveConfiguration(tableConfiguration)">
|
||||
</vn-button>
|
||||
</div>
|
||||
</tpl-body>
|
||||
</vn-dialog>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,95 @@
|
|||
import ngModule from '../module';
|
||||
import template from './uvc.html';
|
||||
|
||||
directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
|
||||
export function directive($http, $compile, vnApp, $translate) {
|
||||
function getHeaderList($element, $scope) {
|
||||
let allHeaders = $element[0].querySelectorAll(`vn-th[field], vn-th[th-id]`);
|
||||
let headerList = Array.from(allHeaders);
|
||||
let ids = [];
|
||||
|
||||
headerList.forEach(header => {
|
||||
ids.push(header.getAttribute('th-id') || header.getAttribute('field'));
|
||||
});
|
||||
|
||||
$scope.fields = ids;
|
||||
|
||||
return headerList;
|
||||
}
|
||||
|
||||
function getTableConfig(tableCode) {
|
||||
return $http.get(`/api/UserConfigViews/getConfig?tableCode=${tableCode}`);
|
||||
}
|
||||
|
||||
function createViewConfig(config, fields) {
|
||||
fields.forEach(field => {
|
||||
if (config.configuration[field] == null)
|
||||
config.configuration[field] = true;
|
||||
});
|
||||
}
|
||||
|
||||
function addHideClass($scope, headerList, userConfig) {
|
||||
let selectors = [];
|
||||
Object.keys(userConfig.configuration).forEach(key => {
|
||||
let index;
|
||||
if (userConfig.configuration[key] === false) {
|
||||
index = headerList.findIndex(el => {
|
||||
return (el.getAttribute('th-id') == key || el.getAttribute('field') == key);
|
||||
});
|
||||
|
||||
let baseSelector = `vn-table[vn-uvc=${userConfig.tableCode}] > div`;
|
||||
selectors.push(`${baseSelector} vn-thead > vn-tr > vn-th:nth-child(${index + 1})`);
|
||||
selectors.push(`${baseSelector} vn-tbody > vn-tr > vn-td:nth-child(${index + 1})`);
|
||||
selectors.push(`${baseSelector} vn-tbody > .vn-tr > vn-td:nth-child(${index + 1})`);
|
||||
}
|
||||
});
|
||||
|
||||
let rule = selectors.join(', ') + '{display: none;}';
|
||||
if ($scope.css)
|
||||
document.head.removeChild($scope.css);
|
||||
|
||||
$scope.css = document.createElement('style');
|
||||
document.head.appendChild($scope.css);
|
||||
$scope.css.appendChild(document.createTextNode(rule));
|
||||
}
|
||||
|
||||
function saveConfiguration(tableConfiguration) {
|
||||
tableConfiguration.configuration = JSON.parse(JSON.stringify(tableConfiguration.configuration));
|
||||
return $http.post(`/api/UserConfigViews/save`, tableConfiguration);
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: async function($scope, $element, $attrs) {
|
||||
let cTemplate = $compile(template)($scope)[0];
|
||||
$scope.$ctrl.showUvc = event => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
$scope.uvc.show();
|
||||
};
|
||||
|
||||
let tableCode = $attrs.vnUvc.trim();
|
||||
let headerList = getHeaderList($element, $scope);
|
||||
|
||||
let defaultConfigView = {tableCode: tableCode, configuration: {}};
|
||||
let userView = await getTableConfig(tableCode);
|
||||
let config = userView.data || defaultConfigView;
|
||||
|
||||
$scope.tableConfiguration = config;
|
||||
createViewConfig(config, $scope.fields);
|
||||
|
||||
addHideClass($scope, headerList, config);
|
||||
|
||||
let table = document.querySelector(`vn-table[vn-uvc=${tableCode}]`);
|
||||
|
||||
table.insertBefore(cTemplate, table.firstChild);
|
||||
$scope.$ctrl.saveConfiguration = async tableConfiguration => {
|
||||
let newConfig = await saveConfiguration(tableConfiguration);
|
||||
vnApp.showSuccess($translate.instant('Data saved!'));
|
||||
addHideClass($scope, headerList, newConfig.data);
|
||||
$scope.uvc.hide();
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
ngModule.directive('vnUvc', directive);
|
|
@ -38,4 +38,5 @@ October: Octubre
|
|||
November: Noviembre
|
||||
December: Diciembre
|
||||
Has delivery: Hay reparto
|
||||
Loading: Cargando
|
||||
Loading: Cargando
|
||||
Fields to show: Campos a mostrar
|
|
@ -10,7 +10,7 @@ class Controller {
|
|||
}
|
||||
|
||||
onSearch() {
|
||||
this.$scope.$$postDigest(() => {
|
||||
this.$scope.$applyAsync(() => {
|
||||
this.$scope.treeview.refresh();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class Controller {
|
|||
where: {itemFk: this.$stateParams.id}
|
||||
};
|
||||
|
||||
this.$scope.$$postDigest(() => {
|
||||
this.$scope.$applyAsync(() => {
|
||||
if (this.$stateParams.warehouseFk)
|
||||
this.warehouseFk = this.$stateParams.warehouseFk;
|
||||
else if (value)
|
||||
|
|
|
@ -69,23 +69,23 @@ describe('Item', () => {
|
|||
|
||||
describe('set item()', () => {
|
||||
it(`should set warehouseFk property based on itemType warehouseFk`, () => {
|
||||
spyOn(controller.$scope, '$$postDigest').and.callThrough();
|
||||
spyOn(controller.$scope, '$applyAsync').and.callThrough();
|
||||
controller.item = {id: 1, itemType: {warehouseFk: 1}};
|
||||
|
||||
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$digest();
|
||||
expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.warehouseFk).toEqual(1);
|
||||
expect(controller.item.id).toEqual(1);
|
||||
});
|
||||
|
||||
it(`should set warehouseFk property based on url query warehouseFk`, () => {
|
||||
spyOn(controller.$scope, '$$postDigest').and.callThrough();
|
||||
spyOn(controller.$scope, '$applyAsync').and.callThrough();
|
||||
controller.$stateParams.warehouseFk = 4;
|
||||
controller.item = {id: 1, itemType: {warehouseFk: 1}};
|
||||
|
||||
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$digest();
|
||||
expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.warehouseFk).toEqual(4);
|
||||
expect(controller.item.id).toEqual(1);
|
||||
|
|
|
@ -28,7 +28,7 @@ class Controller {
|
|||
|
||||
this._order = value;
|
||||
|
||||
this.$scope.$$postDigest(() => {
|
||||
this.$scope.$applyAsync(() => {
|
||||
let category;
|
||||
let type;
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@ describe('Order', () => {
|
|||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, _$state_, $rootScope) => {
|
||||
beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_, $rootScope) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$scope.search = {};
|
||||
|
@ -27,12 +29,14 @@ describe('Order', () => {
|
|||
}));
|
||||
|
||||
describe('order() setter', () => {
|
||||
it(`should call scope $$postDigest() method and apply filters from state params`, () => {
|
||||
spyOn(controller.$scope, '$$postDigest').and.callThrough();
|
||||
it(`should call scope $applyAsync() method and apply filters from state params`, () => {
|
||||
$httpBackend.expect('GET', `/item/api/ItemCategories/1/itemTypes`).respond();
|
||||
spyOn(controller.$scope, '$applyAsync').and.callThrough();
|
||||
controller.order = {id: 4};
|
||||
|
||||
expect(controller.$scope.$$postDigest).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$digest();
|
||||
expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$apply();
|
||||
|
||||
|
||||
expect(controller.category).toEqual({id: 1, value: 'My Category'});
|
||||
expect(controller.type).toEqual({id: 1, value: 'My type'});
|
||||
|
@ -96,28 +100,38 @@ describe('Order', () => {
|
|||
});
|
||||
|
||||
describe('applyFilters()', () => {
|
||||
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||
spyOn(controller.catalog.$scope.model, 'applyFilter');
|
||||
controller.order = {id: 4};
|
||||
$scope.$digest();
|
||||
it(`should call model applyFilter() method with a new filter`, () => {
|
||||
let model = controller.catalog.$scope.model;
|
||||
spyOn(model, 'applyFilter');
|
||||
controller._category = {id: 1, value: 'My Category'};
|
||||
controller._type = {id: 1, value: 'My type'};
|
||||
controller._order = {id: 4};
|
||||
|
||||
controller.applyFilters();
|
||||
|
||||
expect(controller.catalog.$scope.model.applyFilter).toHaveBeenCalledWith(
|
||||
expect(model.applyFilter).toHaveBeenCalledWith(
|
||||
{where: {categoryFk: 1, typeFk: 1}},
|
||||
{orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []});
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove()', () => {
|
||||
it(`should remove a filter from tags property and then call applyFilters()`, () => {
|
||||
spyOn(controller, 'applyFilters');
|
||||
controller.order = {id: 4};
|
||||
it(`should remove a tag from tags property`, () => {
|
||||
controller.tags = [{tagFk: 1, value: 'Blue'}, {tagFk: 2, value: '70'}];
|
||||
$scope.$digest();
|
||||
controller.remove(0);
|
||||
|
||||
expect(controller.tags.length).toEqual(1);
|
||||
expect(controller.tags[0].tagFk).toEqual(2);
|
||||
});
|
||||
|
||||
it(`should remove a tag from tags property and call applyFilters() if there's no more tags`, () => {
|
||||
spyOn(controller, 'applyFilters');
|
||||
controller._category = {id: 1, value: 'My Category'};
|
||||
controller._type = {id: 1, value: 'My type'};
|
||||
controller.tags = [{tagFk: 1, value: 'Blue'}];
|
||||
controller.remove(0);
|
||||
|
||||
expect(controller.tags.length).toEqual(0);
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
@ -125,10 +139,10 @@ describe('Order', () => {
|
|||
describe('updateStateParams()', () => {
|
||||
it(`should call state go() method passing category and type state params`, () => {
|
||||
spyOn(controller.$state, 'go');
|
||||
controller.order = {id: 4};
|
||||
$scope.$digest();
|
||||
|
||||
controller._category = {id: 1, value: 'My Category'};
|
||||
controller._type = {id: 1, value: 'My type'};
|
||||
let result = {category: '{"id":1,"value":"My Category"}', type: '{"id":1,"value":"My type"}'};
|
||||
controller.updateStateParams();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', result);
|
||||
});
|
||||
|
|
|
@ -35,6 +35,9 @@ class Controller {
|
|||
};
|
||||
this.$http.get(`/item/api/ItemTags?filter=${JSON.stringify(filter)}`).then(response => {
|
||||
this.tags = response.data;
|
||||
this.$.$applyAsync(() => {
|
||||
this.$.popover.relocate();
|
||||
});
|
||||
});
|
||||
}
|
||||
show(event, item) {
|
||||
|
@ -42,8 +45,8 @@ class Controller {
|
|||
this.prices = this.item.prices;
|
||||
this.getTags();
|
||||
this.$.popover.parent = event.target;
|
||||
this.$.popover.relocate();
|
||||
this.$.popover.show();
|
||||
this.$.popover.relocate();
|
||||
}
|
||||
clear() {
|
||||
this.item = {};
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
<vn-td>
|
||||
<a ui-sref="claim.card.basicData({id: sale.claimBeginning.claimFk})">
|
||||
<vn-icon
|
||||
ng-show="sale.claimBeginning.claimFk"
|
||||
icon="icon-claims"
|
||||
vn-tooltip="{{::$ctrl.$translate.instant('Claim')}}: {{::sale.claimBeginning.claimFk}}">
|
||||
</vn-icon>
|
||||
|
|
Loading…
Reference in New Issue