From 9afb992225222b9f7254c85c8f39e2e1cbfd357b Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Tue, 3 Oct 2017 07:10:37 +0200 Subject: [PATCH 001/171] autocomplete changes on initialData --- client/core/src/autocomplete/autocomplete.js | 44 +++++++++++--------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index b87361fdc..4c2fa6e89 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -70,28 +70,36 @@ class Autocomplete extends Component { return this.multiple ? this._multiField : this._field; } set field(value) { - this.finding = true; - if (value && value.hasOwnProperty(this.valueField)) { - this._field = value[this.valueField]; - if (this.multiple) { - this.setMultiField(value[this.valueField]); + if (!angular.equals(value, this.field)) { + this.finding = true; + if (value && value.hasOwnProperty(this.valueField)) { + this._field = value[this.valueField]; + if (this.multiple) { + this.setMultiField(value[this.valueField]); + } + } else { + this.setValue(value); } - } else { - this.setValue(value); + + if (value && value.hasOwnProperty(this.showField)) + this.displayValue = value[this.showField]; + + this.finding = false; + + if (this.onChange) + this.onChange({item: this._field}); } - - if (value && value.hasOwnProperty(this.showField)) - this.displayValue = value[this.showField]; - - this.finding = false; - - if (this.onChange) - this.onChange({item: this._field}); } set initialData(value) { - if (value) { - this.field = value; + if (value && value.hasOwnProperty(this.valueField)) { + this._field = value[this.valueField]; + if (this.multiple) { + this._multiField = [value[this.valueField]] + } + if (value.hasOwnProperty(this.showField)) { + this.displayValue = value[this.showField]; + } } } @@ -204,7 +212,6 @@ class Autocomplete extends Component { this.getItems(); } } - getItems() { let filter = {}; @@ -234,7 +241,6 @@ class Autocomplete extends Component { } ); } - $onInit() { this.findMore = this.url && this.maxRow; this.mouseFocus = false; From 4e309b67f00b135d0d99eaab27d2cda7350e7766 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Tue, 3 Oct 2017 09:16:02 +0200 Subject: [PATCH 002/171] bug fixed on LoadMore action in autocomplete --- client/core/src/drop-down/drop-down.html | 9 ++++++++- client/core/src/drop-down/drop-down.js | 7 +++++++ client/core/src/locale/es.json | 3 ++- services/client/common/models/address.js | 17 +++++++++-------- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/client/core/src/drop-down/drop-down.html b/client/core/src/drop-down/drop-down.html index c65feac28..61a16921f 100644 --- a/client/core/src/drop-down/drop-down.html +++ b/client/core/src/drop-down/drop-down.html @@ -16,7 +16,14 @@
{{item.name}}
- + \ No newline at end of file diff --git a/client/core/src/drop-down/drop-down.js b/client/core/src/drop-down/drop-down.js index 465137070..7c332fd94 100644 --- a/client/core/src/drop-down/drop-down.js +++ b/client/core/src/drop-down/drop-down.js @@ -135,6 +135,13 @@ export default class DropDown { } } + loadItems() { + if (this.showLoadMore && this.loadMore) { + this.loadMore(); + } + this.show = true; + } + $onInit() { if (this.parent) this.parent.addEventListener('keydown', e => this.onKeydown(e)); diff --git a/client/core/src/locale/es.json b/client/core/src/locale/es.json index 3ce07bc50..8a44ead1c 100644 --- a/client/core/src/locale/es.json +++ b/client/core/src/locale/es.json @@ -6,5 +6,6 @@ "Save": "Guardar", "Add": "Añadir", "Search": "Buscar", - "Load More": "Cargar más" + "Show More": "Ver más", + "No more results" : "No hay más resultados" } \ No newline at end of file diff --git a/services/client/common/models/address.js b/services/client/common/models/address.js index 6e85ed7f2..569882208 100644 --- a/services/client/common/models/address.js +++ b/services/client/common/models/address.js @@ -1,7 +1,7 @@ module.exports = function(Address) { Address.validate('default',isEnabled,{message: 'No se puede poner predeterminado un consignatario desactivado'}); function isEnabled(err) { - if (!this.isEnabled && this.default) err(); + if (!this.isEnabled && this.isDefaultAddress) err(); } Address.beforeRemote('create',function(ctx, modelInstance, next){ @@ -10,10 +10,11 @@ module.exports = function(Address) { }); function create(data, next){ - if(data.default){ - removeAllDefault(data.client); - } - next(); + if(data.isDefaultAddress){ + removeAllDefault(data.client, next); + } else { + next(); + } } Address.beforeRemote('prototype.patchAttributes',function(ctx, modelInstance, next){ @@ -42,10 +43,10 @@ module.exports = function(Address) { } function callbackGetAddress(ctx, newData, oldData, next){ - if (newData.default){ + if (newData.isDefaultAddress){ removeAllDefault(oldData.client, next); } - else if (oldData.default && newData.hasOwnProperty('default') && !newData.default) + else if (oldData.isDefaultAddress && newData.hasOwnProperty('isDefaultAddress') && !newData.isDefaultAddress) next(generateErrorDefaultAddress()); else next(); @@ -59,7 +60,7 @@ module.exports = function(Address) { } function removeAllDefault(client, next){ - Address.updateAll({clientFk: client.id, default: true}, {default: false}, next); + Address.updateAll({clientFk: client.id, isDefaultAddress: true}, {isDefaultAddress: false}, next); } function generateErrorDefaultAddress(){ From 106d7d83647b4c4720ed25832f11cb379b01e488 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 3 Oct 2017 09:18:12 +0200 Subject: [PATCH 003/171] autocomplete client side unit test for findItems() with multiple --- client/core/src/autocomplete/autocomplete.spec.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/core/src/autocomplete/autocomplete.spec.js b/client/core/src/autocomplete/autocomplete.spec.js index 8999e25b0..0f31b5d96 100644 --- a/client/core/src/autocomplete/autocomplete.spec.js +++ b/client/core/src/autocomplete/autocomplete.spec.js @@ -171,7 +171,7 @@ describe('Component vnAutocomplete', () => { expect(controller.items.length).toEqual(2); }); - it(`should perform a query with the search value if the finding flag is false`, () => { + it(`should perform a search and store the result in controller items`, () => { let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); let search = 'The Joker'; let json = JSON.stringify({where: {name: {regexp: search}}}); @@ -183,18 +183,17 @@ describe('Component vnAutocomplete', () => { expect(controller.items[0]).toEqual({id: 3, name: 'The Joker'}); }); - it(`should perform a query with the search value if the finding flag is false`, () => { + it(`should perform a search with multiple true and store the result in controller items with the checked property defined`, () => { let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); - let search = 'The Joker'; + let search = 'Joker'; + controller.multiple = true; let json = JSON.stringify({where: {name: {regexp: search}}}); - $httpBackend.whenGET(`test.com?filter=${json}`).respond([{id: 3, name: 'The Joker'}]); + $httpBackend.whenGET(`test.com?filter=${json}`).respond([{id: 3, name: 'The Joker'}, {id: 4, name: 'Joker'}]); $httpBackend.expectGET(`test.com?filter=${json}`); controller.findItems(search); $httpBackend.flush(); - expect(controller.items[0]).toEqual({id: 3, name: 'The Joker'}); + expect(controller.items).toEqual([{id: 3, name: 'The Joker', checked: false}, {id: 4, name: 'Joker', checked: false}]); }); - - // siguiente test el de Multiple! }); }); From 1f5f0a0fda340c29724c88f07209a9709b1f62e2 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Tue, 3 Oct 2017 09:25:25 +0200 Subject: [PATCH 004/171] dropdown: new style in -no more results- --- client/core/src/drop-down/drop-down.html | 2 +- client/core/src/drop-down/style.scss | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/client/core/src/drop-down/drop-down.html b/client/core/src/drop-down/drop-down.html index 61a16921f..59a7622de 100644 --- a/client/core/src/drop-down/drop-down.html +++ b/client/core/src/drop-down/drop-down.html @@ -20,7 +20,7 @@ ng-if="$ctrl.loadMore" class="dropdown__loadMore" tabIndex="-1" - ng-class="{'active': $ctrl.itemsFiltered.length === $ctrl.activeOption}" + ng-class="{'active': $ctrl.itemsFiltered.length === $ctrl.activeOption, 'noMore' : !$ctrl.showLoadMore}" ng-click="$ctrl.loadItems()" translate="{{$ctrl.showLoadMore ? 'Show More' : 'No more results'}}" > diff --git a/client/core/src/drop-down/style.scss b/client/core/src/drop-down/style.scss index f66d23ea6..e65fd4e6e 100644 --- a/client/core/src/drop-down/style.scss +++ b/client/core/src/drop-down/style.scss @@ -39,6 +39,11 @@ vn-drop-down { color: rgb(255,171,64); font-weight: 700; } + &.dropdown__loadMore.noMore{ + color:#424242; + font-weight: 700; + opacity: 0.7; + } input[type=checkbox]{ float: left; margin: 5px 5px 0 0; From 57b03790a3d55b1ce0f037b19fac418c9c3b53ba Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 3 Oct 2017 11:32:25 +0200 Subject: [PATCH 005/171] Autocomplete client side unit tests finished --- .../src/autocomplete/autocomplete.spec.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/core/src/autocomplete/autocomplete.spec.js b/client/core/src/autocomplete/autocomplete.spec.js index 0f31b5d96..b554973dd 100644 --- a/client/core/src/autocomplete/autocomplete.spec.js +++ b/client/core/src/autocomplete/autocomplete.spec.js @@ -195,5 +195,24 @@ describe('Component vnAutocomplete', () => { expect(controller.items).toEqual([{id: 3, name: 'The Joker', checked: false}, {id: 4, name: 'Joker', checked: false}]); }); + + it(`should call getItems function if there's no search value`, () => { + let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); + spyOn(controller, 'getItems'); + controller.findItems(); + + expect(controller.getItems).toHaveBeenCalledWith(); + }); + }); + describe('getItem()', () => { + it(`should perfom a query to fill the items without filter`, () => { + let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); + $httpBackend.whenGET(`test.com?filter={"skip":0,"limit":10,"order":"name ASC"}`).respond([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]); + $httpBackend.expectGET(`test.com?filter={"skip":0,"limit":10,"order":"name ASC"}`); + controller.getItems(); + $httpBackend.flush(); + + expect(controller.items).toEqual([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]); + }); }); }); From 73964ac3871afa1570e8e7ccf8be3dd8f0268c43 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 3 Oct 2017 11:54:09 +0200 Subject: [PATCH 006/171] removed unsed files and commented code for deprecated date-picker.js --- client/core/src/components.js | 2 - client/core/src/date-picker/date-picker.js | 51 ------------------- .../core/src/date-picker/date-picker.mdl.html | 4 -- .../core/src/date-picker/date-picker.mdl.js | 14 ----- 4 files changed, 71 deletions(-) delete mode 100644 client/core/src/date-picker/date-picker.js delete mode 100644 client/core/src/date-picker/date-picker.mdl.html delete mode 100644 client/core/src/date-picker/date-picker.mdl.js diff --git a/client/core/src/components.js b/client/core/src/components.js index 04e5d7287..82a90196c 100644 --- a/client/core/src/components.js +++ b/client/core/src/components.js @@ -38,8 +38,6 @@ export {NAME as SUBMIT, directive as SubmitDirective} from './submit/submit'; export {NAME as SUBMIT_MDL, factory as submitMdl} from './submit/submit.mdl'; export {NAME as COMBO, directive as ComboDirective} from './combo/combo'; export {NAME as COMBO_MDL, factory as comboMdl} from './combo/combo.mdl'; -/* export {NAME as DATE_PICKER, directive as DatePickerDirective} from './date-picker/date-picker'; -export {NAME as DATE_PICKER_MDL, factory as datePickerMdl} from './date-picker/date-picker.mdl';*/ export {NAME as CARD, directive as CardDirective} from './card/card'; export {NAME as CARD_MDL, factory as cardMdl} from './card/card.mdl'; export {NAME as SWITCH, directive as SwitchDirective} from './switch/switch'; diff --git a/client/core/src/date-picker/date-picker.js b/client/core/src/date-picker/date-picker.js deleted file mode 100644 index b68d57fd2..000000000 --- a/client/core/src/date-picker/date-picker.js +++ /dev/null @@ -1,51 +0,0 @@ -import {module as _module} from '../module'; -import * as resolveFactory from '../lib/resolveDefaultComponents'; -import * as normalizerFactory from '../lib/inputAttrsNormalizer'; -import * as util from '../lib/util'; -import Flatpickr from 'vendor/src/flatpickr'; - -const _NAME = 'datePicker'; -export const NAME = util.getName(_NAME); - -directive.$inject = [resolveFactory.NAME, normalizerFactory.NAME, '$translate']; -export function directive(resolve, normalizer, $translate) { - return { - restrict: 'E', - template: function(_, attrs) { - normalizer.normalize(attrs); - return resolve.getTemplate(_NAME, attrs); - }, - link: function(scope, element, attrs) { - let input = element[0]; - let flatpickrInstance; - let initOptions = {}; - - if (attrs.iniOpts) - initOptions = scope.$eval(attrs.iniOpts); - - if (!initOptions.locale) - initOptions.locale = $translate.use(); - - /*if (!initOptions.dateFormat && initOptions.locale === 'es') - initOptions.dateFormat = 'd-m-Y';*/ - - if (!input.matches('input')) - input = input.querySelector('input'); - - if (input) - flatpickrInstance = new Flatpickr(input, initOptions); - - scope.$watch(attrs.model, () => { - let mdlField = element[0].firstChild.MaterialCheckbox; - if (mdlField) - mdlField.updateClasses_(); - }); - componentHandler.upgradeElement(element[0].firstChild); - - element.on('$destroy', function() { - flatpickrInstance.destroy(); - }); - } - }; -} -_module.directive(NAME, directive); diff --git a/client/core/src/date-picker/date-picker.mdl.html b/client/core/src/date-picker/date-picker.mdl.html deleted file mode 100644 index 292b43c09..000000000 --- a/client/core/src/date-picker/date-picker.mdl.html +++ /dev/null @@ -1,4 +0,0 @@ -
- - -
diff --git a/client/core/src/date-picker/date-picker.mdl.js b/client/core/src/date-picker/date-picker.mdl.js deleted file mode 100644 index 277b6331d..000000000 --- a/client/core/src/date-picker/date-picker.mdl.js +++ /dev/null @@ -1,14 +0,0 @@ -import {module} from '../module'; -import template from './date-picker.mdl.html'; - -export const NAME = 'vnDatePickerMdlFactory'; -export function factory() { - return { - template: template, - default: { - label: 'Label', - enabled: 'enabled' - } - }; -} -module.factory(NAME, factory); From bc8d3197145d96f228b95c0623ba6c8a56a9b570 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Tue, 3 Oct 2017 12:10:30 +0200 Subject: [PATCH 007/171] AutoLoad items with "scroll" (1st version) --- client/core/src/drop-down/drop-down.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/core/src/drop-down/drop-down.js b/client/core/src/drop-down/drop-down.js index 7c332fd94..1e9e76513 100644 --- a/client/core/src/drop-down/drop-down.js +++ b/client/core/src/drop-down/drop-down.js @@ -51,6 +51,10 @@ export default class DropDown { } this.$timeout(() => { this._activeOption = value; + // AutoLoad items with "scroll" (1st version): + if (value && value >= this.items.length - 3) { + this.loadItems(); + } }); } From c39b29128ccd845bb39dee57de44b59168cca7a8 Mon Sep 17 00:00:00 2001 From: Carlos Date: Tue, 3 Oct 2017 14:41:35 +0200 Subject: [PATCH 008/171] client side unit test for datePicker --- .../src/autocomplete/autocomplete.spec.js | 1 + client/core/src/datePicker/datePicker.js | 10 ++--- client/core/src/datePicker/datePicker.spec.js | 45 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 client/core/src/datePicker/datePicker.spec.js diff --git a/client/core/src/autocomplete/autocomplete.spec.js b/client/core/src/autocomplete/autocomplete.spec.js index b554973dd..619cba24d 100644 --- a/client/core/src/autocomplete/autocomplete.spec.js +++ b/client/core/src/autocomplete/autocomplete.spec.js @@ -204,6 +204,7 @@ describe('Component vnAutocomplete', () => { expect(controller.getItems).toHaveBeenCalledWith(); }); }); + describe('getItem()', () => { it(`should perfom a query to fill the items without filter`, () => { let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); diff --git a/client/core/src/datePicker/datePicker.js b/client/core/src/datePicker/datePicker.js index 70a6344b8..79d7d6cd9 100644 --- a/client/core/src/datePicker/datePicker.js +++ b/client/core/src/datePicker/datePicker.js @@ -48,9 +48,8 @@ class DatePicker extends Component { this._modelView = value; this.input.value = value; this._setModel(value); - this.$timeout( - () => { - this.mdlUpdate(); + this.$timeout(() => { + this.mdlUpdate(); }, 500); } onClear() { @@ -76,9 +75,8 @@ class DatePicker extends Component { return `${dates} ${hours}`.trim(); } else if (string.indexOf(':') !== -1) { // only time format return parts.join(':'); - } else { // only date format - return parts.join('-'); - } + } // only date format + return parts.join('-'); } _setModel(value) { diff --git a/client/core/src/datePicker/datePicker.spec.js b/client/core/src/datePicker/datePicker.spec.js new file mode 100644 index 000000000..ebea87ccf --- /dev/null +++ b/client/core/src/datePicker/datePicker.spec.js @@ -0,0 +1,45 @@ +import './datePicker.js'; + +describe('Component vnDatePicker', () => { + let $componentController; + let $scope; + let $timeout; + let $element; + let $translate; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$timeout_) => { + $componentController = _$componentController_; + $scope = $rootScope.$new(); + $timeout = _$timeout_; + $element = angular.element(`
`); + $translate = {}; + })); + + describe('_formatFlat2Angular()', () => { + it(`should format date from Y-m-d to yyyy-MM-dd`, () => { + let controller = $componentController('vnDatePicker', {$scope, $element, $translate, $timeout}); + let formatedDate = controller._formatFlat2Angular(`Y-m-d`); + + expect(formatedDate).toBe('yyyy-MM-dd'); + }); + + it(`should format date from d-m-Y to dd-MM-yyyy`, () => { + let controller = $componentController('vnDatePicker', {$scope, $element, $translate, $timeout}); + let formatedDate = controller._formatFlat2Angular(`d-m-Y`); + + expect(formatedDate).toBe('dd-MM-yyyy'); + }); + + it(`should split the given string into parts`, () => { + let controller = $componentController('vnDatePicker', {$scope, $element, $translate, $timeout}); + controller.iniOptions = {dateFormat: 'd/m/Y'}; + controller.model = '2017-12-23'; + + expect(controller.modelView).toBe('23-12-2017'); + }); + }); +}); From 666928b1a9ec924e5dee66d7156d4eb158456c31 Mon Sep 17 00:00:00 2001 From: Joan Date: Tue, 3 Oct 2017 14:44:11 +0200 Subject: [PATCH 009/171] Auth login json response --- services/auth/server/boot/routes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/auth/server/boot/routes.js b/services/auth/server/boot/routes.js index f9b690b6d..2bb25ef34 100644 --- a/services/auth/server/boot/routes.js +++ b/services/auth/server/boot/routes.js @@ -44,11 +44,11 @@ module.exports = function(app) { if (!loginUrl) loginUrl = applications.default; - res.send(JSON.stringify({ + res.json({ token: token.id, continue: query.continue, loginUrl: loginUrl - })); + }); } function findCb(err, instance) { if (!instance || instance.password !== md5(password)) { @@ -69,9 +69,9 @@ module.exports = function(app) { } function badLogin() { res.status(401); - res.send(JSON.stringify({ + res.json({ message: 'Login failed' - })); + }); } }); From 627d27ad51dc1b1e1f1319f44c3694184709d956 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 4 Oct 2017 08:18:31 +0200 Subject: [PATCH 010/171] validate client credit --- services/client/common/models/client.js | 62 +++++++++++++------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/services/client/common/models/client.js b/services/client/common/models/client.js index e457b1fef..106ccd2ef 100644 --- a/services/client/common/models/client.js +++ b/services/client/common/models/client.js @@ -2,7 +2,7 @@ var app = require('../../server/server'); module.exports = function(Client) { var models = app.models; - + var loopBackContext = require('loopback-context'); // Methods require('../methods/client/activate.js')(Client); @@ -69,20 +69,22 @@ module.exports = function(Client) { done(); }); } -/* + Client.validateAsync('credit', validateCredit, { message: 'No tienes privilegios para modificar el crédito' }); function validateCredit(err, done) { - // FIXME: Id del usuario actual - let userId = 1; - + let ctx = loopBackContext.getCurrentContext(); + let accessToken = ctx && ctx.get('accessToken'); + let userId = accessToken.userId; + let self = this; + // Comprueba si el rol del usuario puede asignar esa cantidad - + // para ello mira que roles pueden asignar la cantidad que el usuario ha indicado let filter = { fields: ['roleFk'], where: { - maxAmount: {gt: this.credit} + maxAmount: {gt: self.credit} } }; models.ClientCreditLimit.find(filter, @@ -102,47 +104,47 @@ module.exports = function(Client) { (_, res) => roleCb(_, res)); } function roleCb(_, count) { + //si el usuario no tiene alguno de los roles no continua if (!(count > 0)) { err(); done(); } else - validate(); + validate(); //si tiene el rol hay que validar que el último movimiento no fuese crédito 0 insertado por gerencia } // Si se puso a 0 por gerencia, solo gerencia puede aumentarlo - function validate() { - let query = 'SELECT MAX(created) created FROM ClientCredit WHERE clientFk = ?'; - Client.dataSource.connector.execute (query, [this.id], + let query = 'SELECT * FROM ClientCredit WHERE clientFk = ? ORDER BY created DESC LIMIT 1'; + Client.dataSource.connector.execute (query, [self.id], (_, res) => maxCb(_, res)); } + function maxCb(_, instances) { - if (instances.length !== 1) { + //console.log('maxCb', instances); + if (instances && (instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0)) { done(); return; } + + //el ultimo registro tiene valor 0, hay que comprobar que no fue editado por un gerente + let sql = `SELECT count(distinct r.id) as hasManagerRole + FROM ClientCredit cc + JOIN Employee em ON (em.id = cc.employeeFk) + JOIN Account ac ON (ac.id = em.userFk) + JOIN RoleMapping rm ON (rm.principalId = ac.id) + JOIN Role r on (r.id = rm.roleId) + WHERE rm.principalType = 'USER' + AND cc.employeeFk = ${instances[0].employeeFk} + AND r.\`name\` = 'manager'`; - let filter = { - fields: ['amount', 'employeeFk', 'employee'], - where: { - clientFk: this.id, - created: instances[0].created - }, - include: { - relation: 'employee', - scope: { - fields: ['userFk'] - } - } - }; - models.ClientCredit.findOne(filter, - (_, res) => clientCreditCb(_, res)); + Client.dataSource.connector.execute(sql, [], (_, res) => clientCreditCb(_, res)); } - function clientCreditCb(_, instance) { - if (instance.amount == 0 && instance.employee.userFk != userId) + + function clientCreditCb(_, instance) { + if (instance.length && instance[0].hasManagerRole > 0 ) err(); done(); } } -*/ + }; \ No newline at end of file From 8e5eca56296c16a183d243244f9f7600571b5766 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 4 Oct 2017 08:33:51 +0200 Subject: [PATCH 011/171] validation client credit - refact --- services/client/common/models/client.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/client/common/models/client.js b/services/client/common/models/client.js index 106ccd2ef..19c3969a9 100644 --- a/services/client/common/models/client.js +++ b/services/client/common/models/client.js @@ -121,7 +121,12 @@ module.exports = function(Client) { function maxCb(_, instances) { //console.log('maxCb', instances); - if (instances && (instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0)) { + if(!instances){ + err(); + return; + } + + if (instances.length !== 1 || instances[0].employeeFk == userId || instances[0].amount > 0) { done(); return; } @@ -141,7 +146,7 @@ module.exports = function(Client) { } function clientCreditCb(_, instance) { - if (instance.length && instance[0].hasManagerRole > 0 ) + if (!instance || (instance.length && instance[0].hasManagerRole > 0 )) err(); done(); } From 946d7f88249ffa945ea8d8bdb7094548550b9998 Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 4 Oct 2017 08:47:16 +0200 Subject: [PATCH 012/171] Autocomplete spec updated, icon-menu spec completed and small refactors in dialog, drop-down and icon-menu --- .../src/autocomplete/autocomplete.spec.js | 15 ++-- client/core/src/dialog/dialog.js | 8 +- client/core/src/drop-down/drop-down.js | 9 ++- client/core/src/icon-menu/icon-menu.js | 6 ++ client/core/src/icon-menu/icon-menu.spec.js | 74 +++++++++++++++++++ 5 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 client/core/src/icon-menu/icon-menu.spec.js diff --git a/client/core/src/autocomplete/autocomplete.spec.js b/client/core/src/autocomplete/autocomplete.spec.js index 619cba24d..5c920bba8 100644 --- a/client/core/src/autocomplete/autocomplete.spec.js +++ b/client/core/src/autocomplete/autocomplete.spec.js @@ -155,18 +155,17 @@ describe('Component vnAutocomplete', () => { }); describe('findItem()', () => { - it(`should return items array if the controller does not provide a url and nither it has items`, () => { - let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}); - controller.items = ['Batman', 'Bruce Wayne']; + it(`should return items empty array if the controller does not provide a url and have no items defined`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}); controller.findItems('some search value'); - expect(controller.items.length).toEqual(2); + expect(controller.items).not.toBeDefined(); }); - it(`should perform a query with the search value if the finding flag is false`, () => { - let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}); + it(`should return items array if the controller does not provide a url`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}); controller.items = ['Batman', 'Bruce Wayne']; - controller.findItems('Gotham'); + controller.findItems('some search value'); expect(controller.items.length).toEqual(2); }); @@ -205,7 +204,7 @@ describe('Component vnAutocomplete', () => { }); }); - describe('getItem()', () => { + describe('getItems()', () => { it(`should perfom a query to fill the items without filter`, () => { let controller = $componentController('vnAutocomplete', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); $httpBackend.whenGET(`test.com?filter={"skip":0,"limit":10,"order":"name ASC"}`).respond([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]); diff --git a/client/core/src/dialog/dialog.js b/client/core/src/dialog/dialog.js index 6f2c7d3c7..5c85ea14d 100644 --- a/client/core/src/dialog/dialog.js +++ b/client/core/src/dialog/dialog.js @@ -13,8 +13,7 @@ export default class Dialog extends Component { super($element); $element.addClass('vn-dialog'); this.dialog = $element[0].firstChild; - this.element.addEventListener('mousedown', - event => this.onBackgroundMouseDown(event)); + this.element.addEventListener('mousedown', event => this.onBackgroundMouseDown(event)); } /** * Displays the dialog to the user. @@ -66,12 +65,14 @@ export default class Dialog extends Component { cancel = this.onResponse({response: response}); return cancel; } + realHide() { this.element.style.display = 'none'; this.document.removeEventListener('keypress', this.keypressHandler); this.lastEvent = null; } + onButtonClick(event) { let buttonBar = this.element.querySelector('.button-bar'); let buttons = buttonBar.querySelector('tpl-buttons'); @@ -86,13 +87,16 @@ export default class Dialog extends Component { let cancel = this.fireResponse(response); if (cancel !== false) this.realHide(); } + onDialogMouseDown(event) { this.lastEvent = event; } + onBackgroundMouseDown(event) { if (event != this.lastEvent) this.hide(); } + onKeypress(event) { if (event.keyCode == 27) // Esc this.hide(); diff --git a/client/core/src/drop-down/drop-down.js b/client/core/src/drop-down/drop-down.js index 7c332fd94..e9c8c2346 100644 --- a/client/core/src/drop-down/drop-down.js +++ b/client/core/src/drop-down/drop-down.js @@ -16,6 +16,7 @@ export default class DropDown { get show() { return this._show; } + set show(value) { let oldValue = this.show; this._show = value; @@ -27,10 +28,12 @@ export default class DropDown { this._focusingFilter = false; }, 250); } - } + } + get search() { return this._search; } + set search(value) { let val = (value === undefined && value === '') ? null : value; this._search = val; @@ -40,9 +43,11 @@ export default class DropDown { else this.filterItems(); } + get activeOption() { return this._activeOption; } + set activeOption(value) { if (value < 0) { value = 0; @@ -117,6 +122,7 @@ export default class DropDown { } } } + setScrollPosition() { let dropdown = this.$element[0].querySelector('ul.dropdown'); let child = dropdown ? dropdown.childNodes[this.activeOption] : null; @@ -151,6 +157,7 @@ export default class DropDown { this.parent.removeEventListener('keydown', e => this.onKeydown(e)); } } + DropDown.$inject = ['$element', '$filter', '$timeout']; module.component('vnDropDown', { diff --git a/client/core/src/icon-menu/icon-menu.js b/client/core/src/icon-menu/icon-menu.js index 4ac9d2302..8a2bba8d8 100644 --- a/client/core/src/icon-menu/icon-menu.js +++ b/client/core/src/icon-menu/icon-menu.js @@ -11,12 +11,15 @@ export default class IconMenu { this.findMore = false; this.element = $element[0]; } + get showDropDown() { return this._showDropDown; } + set showDropDown(value) { this._showDropDown = value; } + findItems(search) { if (!this.url) return this.items ? this.items : []; @@ -40,6 +43,7 @@ export default class IconMenu { this.getItems(); } } + getItems() { let filter = {}; @@ -66,6 +70,7 @@ export default class IconMenu { } ); } + $onInit() { if (!this.items && this.url) { this.items = []; @@ -104,6 +109,7 @@ export default class IconMenu { this.$element.unbind('focusout'); } } + IconMenu.$inject = ['$element', '$http', '$timeout']; module.component('vnIconMenu', { diff --git a/client/core/src/icon-menu/icon-menu.spec.js b/client/core/src/icon-menu/icon-menu.spec.js new file mode 100644 index 000000000..ae229b017 --- /dev/null +++ b/client/core/src/icon-menu/icon-menu.spec.js @@ -0,0 +1,74 @@ +import './icon-menu.js'; + +describe('Component vnIconMenu', () => { + let $componentController; + let $element; + let $httpBackend; + let $timeout; + let $scope; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => { + $componentController = _$componentController_; + $httpBackend = _$httpBackend_; + $timeout = _$timeout_; + $scope = $rootScope.$new(); + $element = angular.element('
'); + })); + + describe('component vnIconMenu', () => { + describe('findItem()', () => { + it(`should return items empty array if the controller does not provide a url and have no items defined`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}); + controller.findItems('some search value'); + + expect(controller.items).not.toBeDefined(); + }); + + it(`should return items array if the controller does not provide a url`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}); + controller.items = ['Batman', 'Bruce Wayne']; + controller.findItems('some search value'); + + expect(controller.items.length).toEqual(2); + }); + + it(`should perform a search and store the result in controller items`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); + let search = 'The Joker'; + let json = JSON.stringify({where: {name: {regexp: search}}}); + $httpBackend.whenGET(`test.com?filter=${json}`).respond([{id: 3, name: 'The Joker'}]); + $httpBackend.expectGET(`test.com?filter=${json}`); + controller.findItems(search); + $httpBackend.flush(); + + expect(controller.items[0]).toEqual({id: 3, name: 'The Joker'}); + }); + + it(`should call getItems function if there's no search value`, () => { + let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); + spyOn(controller, 'getItems'); + controller.findItems(); + + expect(controller.getItems).toHaveBeenCalledWith(); + }); + }); + + // implementation pending. + + // describe('getItems()', () => { + // it(`should perfom a query to fill the items without filter`, () => { + // let controller = $componentController('vnIconMenu', {$scope, $element, $httpBackend, $timeout}, {url: 'test.com'}); + // $httpBackend.whenGET(`test.com?filter={}`).respond([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]); + // $httpBackend.expectGET(`test.com?filter={}`); + // controller.getItems(); + // $httpBackend.flush(); + + // expect(controller.items).toEqual([{id: 1, name: 'Batman'}, {id: 2, name: 'Bruce Wayne'}]); + // }); + // }); + }); +}); From 9fbc404aa15f9d71f92a1ade31a03ef4d007eec1 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 4 Oct 2017 09:07:14 +0200 Subject: [PATCH 013/171] bug fixed in formatCard function --- services/client/common/methods/client/card.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/client/common/methods/client/card.js b/services/client/common/methods/client/card.js index 752f7ce6a..4bfc66005 100644 --- a/services/client/common/methods/client/card.js +++ b/services/client/common/methods/client/card.js @@ -36,10 +36,11 @@ module.exports = function(Client) { function formatCard(card) { let cardFormated = JSON.parse(JSON.stringify(card)); - cardFormated.salesPerson = { - id: card.salesPerson().id, - name: `${card.salesPerson().name} ${card.salesPerson().surname}` - }; + if(cardFormated.salesPersonFk) + cardFormated.salesPerson = { + id: card.salesPerson().id, + name: `${card.salesPerson().name} ${card.salesPerson().surname}` + }; return cardFormated; } }; From 245112438ecc61661228182258f0c4ddf0a4c0d3 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 4 Oct 2017 10:54:29 +0200 Subject: [PATCH 014/171] bug fixed modified data object --- client/core/src/lib/modified.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/core/src/lib/modified.js b/client/core/src/lib/modified.js index 1b37f3af6..79f725633 100644 --- a/client/core/src/lib/modified.js +++ b/client/core/src/lib/modified.js @@ -5,7 +5,7 @@ export default function getModifiedData(object, objectOld) { var newObject = {}; for (var k in object) { var val = object[k]; - var valOld = objectOld[k]; + var valOld = objectOld[k] === undefined ? null : objectOld[k]; if (!isEqual(val, valOld)) { if (val instanceof Object) { From 9ebd705aea052a64c657996c3651506cbc593d5c Mon Sep 17 00:00:00 2001 From: Joan Date: Wed, 4 Oct 2017 13:27:38 +0200 Subject: [PATCH 015/171] =?UTF-8?q?Errores=20en=20servicio=20de=20autenfic?= =?UTF-8?q?aci=C3=B3n=20solucionados.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/auth/server/boot/routes.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/services/auth/server/boot/routes.js b/services/auth/server/boot/routes.js index 2bb25ef34..39864da20 100644 --- a/services/auth/server/boot/routes.js +++ b/services/auth/server/boot/routes.js @@ -10,7 +10,7 @@ module.exports = function(app) { }); app.post('/login', function(req, res) { - let user = req.body.user; + let user = req.body.user ? req.body.user : ""; let password = req.body.password; let syncOnFail = true; let usesEmail = user.indexOf('@') !== -1; @@ -38,15 +38,24 @@ module.exports = function(app) { return; } - let query = url.parse(req.body.location, true).query; - let loginUrl = applications[query.apiKey]; + let parsedLocation; + let loginUrl; + let shouldContinue = false; + if (req.body.location) + parsedLocation = url.parse(req.body.location, true); + + if (parsedLocation && parsedLocation.query) { + loginUrl = applications[parsedLocation.query.apiKey]; + shouldContinue = parsedLocation.query.continue; + } + if (!loginUrl) loginUrl = applications.default; res.json({ token: token.id, - continue: query.continue, + continue: shouldContinue, loginUrl: loginUrl }); } From 92e17545716a20dc2a504c8e8ddb31b97f6d8a3a Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 4 Oct 2017 13:27:39 +0200 Subject: [PATCH 016/171] client unit test for paging plus rly small refactors --- client/core/src/multi-check/multi-check.js | 8 +++ client/core/src/paging/paging.js | 9 ++- client/core/src/paging/paging.spec.js | 72 ++++++++++++++++++++++ client/core/src/watcher/watcher.js | 13 ++++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 client/core/src/paging/paging.spec.js diff --git a/client/core/src/multi-check/multi-check.js b/client/core/src/multi-check/multi-check.js index ba3f7b79f..3447e9b46 100644 --- a/client/core/src/multi-check/multi-check.js +++ b/client/core/src/multi-check/multi-check.js @@ -13,19 +13,24 @@ export default class MultiCheck { this.type = {}; this.showDropDown = false; } + get models() { return this._models; } + set models(value) { this._models = value; } + get checkAll() { return this._checkAll; } + set checkAll(value) { this._checkAll = value; this.switchChecks(); } + switchChecks() { if (this.models) this.models.forEach( @@ -47,10 +52,12 @@ export default class MultiCheck { } ); } + $onChanges() { this.type = {}; this.checkAll = 0; } + $doCheck() { if (this.type && this.type.id) { switch (this.type.id) { @@ -68,6 +75,7 @@ export default class MultiCheck { } } } + MultiCheck.$inject = []; module.component('vnMultiCheck', { diff --git a/client/core/src/paging/paging.js b/client/core/src/paging/paging.js index e04f9ee5e..02d1a7fc0 100644 --- a/client/core/src/paging/paging.js +++ b/client/core/src/paging/paging.js @@ -5,6 +5,7 @@ export default class Paging { get numPages() { return Math.ceil(this.numItems / this.numPerPage); } + constructor($http, $scope) { this.$http = $http; this.$scope = $scope; @@ -13,6 +14,7 @@ export default class Paging { this.numItems = 0; $scope.$watch('$ctrl.index.model.length', () => this.onModelUpdated()); } + $onChanges(changes) { if (!this.index) return; this.numPerPage = this.index.filter.size; @@ -20,14 +22,15 @@ export default class Paging { if (changes.total) this.numItems = changes.total.currentValue; } + onModelUpdated() { let index = this.index; let filter = index.filter; - if (filter.page >= this.numPages - && index.model.length >= this.numPerPage) + if (filter.page >= this.numPages && index.model.length >= this.numPerPage) this.numItems = filter.page * filter.size + 1; } + onPageChange(page) { this.index.filter.page = page; if (typeof this.pageChange === 'undefined') { @@ -37,6 +40,7 @@ export default class Paging { } } } + Paging.$inject = ['$http', '$scope']; export const NAME = 'vnPaging'; @@ -49,4 +53,5 @@ export const COMPONENT = { }, controller: Paging }; + module.component(NAME, COMPONENT); diff --git a/client/core/src/paging/paging.spec.js b/client/core/src/paging/paging.spec.js new file mode 100644 index 000000000..de13f183f --- /dev/null +++ b/client/core/src/paging/paging.spec.js @@ -0,0 +1,72 @@ +import './paging.js'; + +describe('Component vnPaging', () => { + let $componentController; + let $scope; + let $httpBackend; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => { + $componentController = _$componentController_; + $scope = $rootScope.$new(); + $httpBackend = _$httpBackend_; + })); + + describe('$onChanges()', () => { + it(`should define numberPage and currentPage based on index.filter properties`, () => { + let controller = $componentController('vnPaging', {$scope, $httpBackend}); + controller.index = {filter: {size: 'something', page: 'something else'}}; + controller.$onChanges({index: 'simpleChange', currentValue: 'current value', previousValue: 'previous value'}); + + expect(controller.numPerPage).toBe(controller.index.filter.size); + expect(controller.currentPage).toEqual(controller.index.filter.page); + }); + + it(`should define numItems based on changes.total.currentValue`, () => { + let controller = $componentController('vnPaging', {$scope, $httpBackend}); + controller.index = {filter: {size: 'something', page: 'something else'}}; + controller.$onChanges({total: {currentValue: 'current value'}}); + + expect(controller.numItems).toEqual('current value'); + }); + }); + + describe('onModelUpdated()', () => { + it(`should define controllers numItems as the result of page times size plus one`, () => { + let controller = $componentController('vnPaging', {$scope, $httpBackend}); + controller.numPerPage = 2; + controller.index = { + filter: {size: 10, page: 10}, + model: ['one mother..', 'another model..', 'last model..'] + }; + controller.onModelUpdated(); + + expect(controller.numItems).toBe(101); + }); + }); + + describe('onPageChange()', () => { + it(`should call accept() since pageChange property is undefined`, () => { + let myIndex = {accept: () => {}, filter: {page: 0}}; + let controller = $componentController('vnPaging', {$scope, $httpBackend}, {index: myIndex}); + spyOn(controller.index, 'accept'); + controller.onPageChange(100); + + expect(controller.index.accept).toHaveBeenCalledWith(); + }); + + it(`should call pageChange() since pageChange property isn't undefined`, () => { + let myIndex = {accept: () => {}, filter: {page: 0}}; + let controller = $componentController('vnPaging', {$scope, $httpBackend}, {index: myIndex}); + controller.pageChange = true; + spyOn(controller, 'pageChange'); + controller.onPageChange(100); + + expect(controller.pageChange).toHaveBeenCalledWith(); + }); + }); +}); + diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index 3ee1b5d4e..bf085db4e 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -24,6 +24,7 @@ export default class Watcher extends Component { transition => this.callback(transition)); this.copyData(); } + $onInit() { if (this.get && this.url) { this.fetchData(); @@ -31,14 +32,17 @@ export default class Watcher extends Component { throw new Error('Error: Parameter url ommitted'); } } + $onChanges(changes) { if (this.data) { this.copyData(); } } + $onDestroy() { this.deregisterCallback(); } + fetchData() { let id = this.data[this.idField]; // return new Promise((resolve, reject) => { @@ -120,6 +124,7 @@ export default class Watcher extends Component { ); }); } + writeData(json, resolve) { Object.keys(this.data).forEach( key => { @@ -130,21 +135,25 @@ export default class Watcher extends Component { this.copyData(); resolve(json); } + noChanges(resolve) { this.vnApp.showMessage( this.$translate.instant('No changes to save') ); resolve(); } + invalidForm(resolve) { this.vnApp.showMessage( this.$translate.instant('Some fields are invalid') ); resolve(); } + copyData() { this.orgData = this.copyObject(this.data); } + copyObject(data) { let copy = {}; if (data) { @@ -157,6 +166,7 @@ export default class Watcher extends Component { } return copy; } + callback(transition) { let dataChanged = this.dataChanged(); if (!this.state && dataChanged) { @@ -167,10 +177,12 @@ export default class Watcher extends Component { return true; } + dataChanged() { let newData = this.copyObject(this.data); return !isEqual(newData, this.orgData); } + onConfirmResponse(response) { if (response === 'ACCEPT') { this.data = this.copyObject(this.orgData); @@ -180,6 +192,7 @@ export default class Watcher extends Component { } } } + Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate']; module.component('vnWatcher', { From 0925451364a18072796a06e9299ac6a76b56466f Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Wed, 4 Oct 2017 13:32:26 +0200 Subject: [PATCH 017/171] spread equivalent tax in all addresses --- .../client/src/billing-data/billing-data.html | 14 ++++++ .../client/src/billing-data/billing-data.js | 33 +++++++++++++- client/client/src/billing-data/locale/es.json | 6 ++- .../methods/client/addressesPropagateRe.js | 43 +++++++++++++++++++ .../common/methods/client/before-save.js | 33 +++++++------- services/client/common/models/client.js | 1 + 6 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 services/client/common/methods/client/addressesPropagateRe.js diff --git a/client/client/src/billing-data/billing-data.html b/client/client/src/billing-data/billing-data.html index 47f982696..75aeb93be 100644 --- a/client/client/src/billing-data/billing-data.html +++ b/client/client/src/billing-data/billing-data.html @@ -59,4 +59,18 @@ + + + + + You changes the equivalent tax + Do you want to spread the change to their consignees? + + + + + + \ No newline at end of file diff --git a/client/client/src/billing-data/billing-data.js b/client/client/src/billing-data/billing-data.js index df281e8b3..a28aea963 100644 --- a/client/client/src/billing-data/billing-data.js +++ b/client/client/src/billing-data/billing-data.js @@ -20,6 +20,7 @@ export default class Controller { this.billData.discount = this.client.discount; this.billData.credit = this.client.credit; this.billData.creditInsurance = this.client.creditInsurance; + this.equalizationTax = this.client.equalizationTax; } } submit() { @@ -36,13 +37,41 @@ export default class Controller { } } ); - if (!equals) + + if (equals) { + this.checkREChanges(); + } else { this.$.sendMail.show(); + } } returnDialog(response) { if (response === 'ACCEPT') { this.$http.post(`/mailer/manuscript/payment-update/${this.client.id}`).then( - () => this.vnApp.showMessage(this.translate.instant('Notification sent!')) + () => { + this.vnApp.showMessage(this.translate.instant('Notification sent!')); + this.checkREChanges(); + } + ); + } else { + this.checkREChanges(); + } + } + + checkREChanges() { + let equals = this.equalizationTax == this.client.equalizationTax; + this.equalizationTax = this.client.equalizationTax; + + if (!equals) + this.$.propagateEqualizationTax.show(); + } + + returnDialogRE(response) { + if (response === 'ACCEPT') { + this.$http.patch(`/client/api/Clients/${this.client.id}/addressesPropagateRe`, {isEqualizated: this.client.equalizationTax}).then( + res => { + if (res.data) + this.vnApp.showMessage(this.translate.instant('Equivalent tax spreaded')); + } ); } } diff --git a/client/client/src/billing-data/locale/es.json b/client/client/src/billing-data/locale/es.json index f0b6a1213..5706db30e 100644 --- a/client/client/src/billing-data/locale/es.json +++ b/client/client/src/billing-data/locale/es.json @@ -4,5 +4,9 @@ "No": "No", "Yes, notify": "Sí, notificar", "Notification sent!": "¡Notificación enviada!", - "Notification error": "Error al enviar notificación" + "Notification error": "Error al enviar notificación", + "You changes the equivalent tax": "Has cambiado el recargo de equivalencia", + "Do you want to spread the change to their consignees?" : "¿Deseas propagar el cambio a sus consignatarios?", + "Yes, propagate": "Si, propagar", + "Equivalent tax spreaded": "Recargo de equivalencia propagado" } \ No newline at end of file diff --git a/services/client/common/methods/client/addressesPropagateRe.js b/services/client/common/methods/client/addressesPropagateRe.js new file mode 100644 index 000000000..b5aec246c --- /dev/null +++ b/services/client/common/methods/client/addressesPropagateRe.js @@ -0,0 +1,43 @@ +module.exports = function(Client) { + Client.remoteMethod('addressesPropagateRe', { + description: 'Change property isEqualizated in all client addresses', + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'string', + required: true, + description: 'Client id', + http: {source: 'path'} + }, + { + arg: 'data', + type: 'Object', + required: true, + description: 'data with new value', + http: {source: 'body'} + } + ], + returns: { + arg: 'data', + type: 'boolean', + root: true + }, + http: { + path: `/:id/addressesPropagateRe`, + verb: 'patch' + } + }); + + Client.addressesPropagateRe = (id, data, callback) => { + if(data.hasOwnProperty('isEqualizated')) { + Client.app.models.Address.updateAll({clientFk: id}, data, (err, info) => { + if (err) + return callback(err, null); + callback(null, true); + }); + } else { + callback(null, false); + } + }; +} \ No newline at end of file diff --git a/services/client/common/methods/client/before-save.js b/services/client/common/methods/client/before-save.js index 4d9c096ef..e8d892be8 100644 --- a/services/client/common/methods/client/before-save.js +++ b/services/client/common/methods/client/before-save.js @@ -3,18 +3,21 @@ module.exports = function(Client) { var CREDIT_CARD = 5; Client.observe('before save', function(ctx, next) { - if (ctx.instance) { - Object.assign(ctx.instance, doIfNullSalesPerson(ctx.instance)); + if (ctx.currentInstance) { + let dataChange = Object.assign({}, ctx.data); + Object.assign(ctx.data, doIfNullSalesPerson(ctx.currentInstance)); - if (!ctx.instance.dueDay) - ctx.instance.dueDay = 5; + if (!ctx.data.dueDay) + ctx.data.dueDay = 5; - if (ctx.instance.equalizationTax && !canMarkEqualizationTax(ctx.instance)) - generateErrorEqualizationTax(); + if (dataChange.hasOwnProperty('equalizationTax') && !canMarkEqualizationTax(ctx.data)) + next(generateErrorEqualizationTax()); + else + next(); - next(); } else { - Client.findById(ctx.where.id, (_, instance) => { + Client.findById(ctx.where.id, (_, instance) => { + Object.assign(ctx.data, doIfNullSalesPerson(instance)); if (instance @@ -22,13 +25,13 @@ module.exports = function(Client) { && instance.dueDay == ctx.data.dueDay) ctx.data.dueDay = 5; - if (instance.fi !== undefined && ctx.data.equalizationTax && !canMarkEqualizationTax(instance)) + if (instance.fi && ctx.data.equalizationTax && !canMarkEqualizationTax(instance)){ next(generateErrorEqualizationTax()); - - if (instance.equalizationTax !== undefined && instance.equalizationTax && ctx.data.fi && Boolean(canMarkEqualizationTax(ctx.data))) + } else if (instance.equalizationTax !== undefined && instance.equalizationTax && ctx.data.fi && canMarkEqualizationTax(ctx.data)){ next(generateErrorEqualizationTax()); - - next(); + } else { + next(); + } }); } }); @@ -44,8 +47,8 @@ module.exports = function(Client) { } function canMarkEqualizationTax(instance) { - var firstLetter = instance.fi.toUpperCase().charAt(0); - if (firstLetter != "A" && firstLetter != "B") + var firstLetter = (instance && instance.fi) ? instance.fi.toUpperCase().charAt(0) : ''; + if (firstLetter == "A" || firstLetter == "B") return false; return true; } diff --git a/services/client/common/models/client.js b/services/client/common/models/client.js index 19c3969a9..9236fdabb 100644 --- a/services/client/common/models/client.js +++ b/services/client/common/models/client.js @@ -14,6 +14,7 @@ module.exports = function(Client) { require('../methods/client/filter.js')(Client); require('../methods/client/roles.js')(Client); require('../methods/client/salesperson.js')(Client); + require('../methods/client/addressesPropagateRe.js')(Client); // Validations From 1b47d8582807159321a0d54d7d216b7e585da27d Mon Sep 17 00:00:00 2001 From: Carlos Date: Wed, 4 Oct 2017 16:02:53 +0200 Subject: [PATCH 018/171] client side unit test for textfield --- client/core/src/popover/popover.js | 15 +++++++ client/core/src/textfield/textfield.js | 3 +- client/core/src/textfield/textfield.spec.js | 47 +++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 client/core/src/textfield/textfield.spec.js diff --git a/client/core/src/popover/popover.js b/client/core/src/popover/popover.js index a1cac7112..a635ab002 100644 --- a/client/core/src/popover/popover.js +++ b/client/core/src/popover/popover.js @@ -13,6 +13,7 @@ export function directive(vnPopover) { } }; } + module.directive('vnPopover', directive); export class Popover { @@ -69,6 +70,7 @@ export class Popover { width = innerWidth - dblMargin; style.width = width + 'px'; } + if (height + dblMargin > innerHeight) { height = innerHeight - dblMargin; style.height = height + 'px'; @@ -82,11 +84,13 @@ export class Popover { if (left + width > innerWidth) left -= (left + width) - innerWidth + margin; + if (top + height > innerHeight) top -= height + parentNode.offsetHeight + spacing * 2; if (left < 0) left = screenMargin; + if (top < 0) top = screenMargin; @@ -102,6 +106,7 @@ export class Popover { } return popoverId; } + showComponent(childComponent, $scope, parent) { let childElement = this.document.createElement(childComponent); let id = 'popover-' + this.popOpens; @@ -111,12 +116,14 @@ export class Popover { this.show(childElement, parent, id); return childElement; } + _checkOpens() { this.popOpens = this.document.querySelectorAll('*[id^="popover-"]').length; if (this.popOpens === 0) { this._destroy(); } } + _removeElement(val) { if (!val) return; let element = angular.element(val); @@ -136,6 +143,7 @@ export class Popover { } this._checkOpens(); } + hideChilds(id) { let popovers = this.document.querySelectorAll('*[id^="popover-"]'); let idNumber = parseInt(id.split('-')[1], 10); @@ -147,6 +155,7 @@ export class Popover { ); this._checkOpens(); } + hideAll() { let popovers = this.document.querySelectorAll('*[id^="popover-"]'); popovers.forEach( @@ -156,6 +165,7 @@ export class Popover { ); this._checkOpens(); } + _findPopOver(node) { while (node != null) { if (node.id && node.id.startsWith('popover-')) { @@ -165,6 +175,7 @@ export class Popover { } return null; } + onDocMouseDown(event) { let targetId = this._findPopOver(event.target); if (targetId) { @@ -173,6 +184,7 @@ export class Popover { this.hideAll(); } } + onDocKeyDown(event) { if (event.keyCode === 27) { let targetId = this._findPopOver(this.lastTarget); @@ -184,9 +196,12 @@ export class Popover { this.lastTarget = null; } } + onPopoverMouseDown(event) { this.lastTarget = event.target; } } + Popover.$inject = ['$document', '$compile', '$transitions']; + module.service('vnPopover', Popover); diff --git a/client/core/src/textfield/textfield.js b/client/core/src/textfield/textfield.js index c7f61736f..09d65ab9d 100644 --- a/client/core/src/textfield/textfield.js +++ b/client/core/src/textfield/textfield.js @@ -36,7 +36,7 @@ export default class TextfieldController extends Component { this.hasValue = Boolean(this._value); this.mdlUpdate(); } - + mdlUpdate() { let mdlField = this.$element[0].firstChild.MaterialTextfield; if (mdlField) @@ -48,6 +48,7 @@ export default class TextfieldController extends Component { this.input.focus(); } } + TextfieldController.$inject = ['$element', '$scope', '$attrs', '$timeout', normalizerFactory.NAME]; module.component('vnTextfield', { diff --git a/client/core/src/textfield/textfield.spec.js b/client/core/src/textfield/textfield.spec.js new file mode 100644 index 000000000..5140bfab8 --- /dev/null +++ b/client/core/src/textfield/textfield.spec.js @@ -0,0 +1,47 @@ +import './textfield.js'; + +describe('Component vnTextfield', () => { + let $componentController; + let $scope; + let $attrs; + let $timeout; + let $element; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => { + $componentController = _$componentController_; + $scope = $rootScope.$new(); + $attrs = {}; + $timeout = _$timeout_; + $element = angular.element('
'); + })); + + describe('value() setter', () => { + it(`should set _value, input.value and hasValue properties to null, '' and false then call mdlUpdate()`, () => { + let controller = $componentController('vnTextfield', {$scope, $element, $attrs, $timeout}); + spyOn(controller, 'mdlUpdate'); + let testValue = ''; + controller.value = testValue; + + expect(controller._value).toEqual(null); + expect(controller.input.value).toEqual(testValue); + expect(controller.hasValue).toEqual(Boolean(testValue)); + expect(controller.mdlUpdate).toHaveBeenCalledWith(); + }); + + it(`should set _value, input.value and hasValue propertiest to test, test and true then call mdlUpdate()`, () => { + let controller = $componentController('vnTextfield', {$scope, $element, $attrs, $timeout}); + spyOn(controller, 'mdlUpdate'); + let testValue = 'test'; + controller.value = testValue; + + expect(controller._value).toEqual(testValue); + expect(controller.input.value).toEqual(testValue); + expect(controller.hasValue).toEqual(Boolean(testValue)); + expect(controller.mdlUpdate).toHaveBeenCalledWith(); + }); + }); +}); From 485ef528b7ae5ba39bcdf2ccbace5c3688a0120e Mon Sep 17 00:00:00 2001 From: Carlos Date: Thu, 5 Oct 2017 08:59:16 +0200 Subject: [PATCH 019/171] correct eslint errors in the commited files --- client/core/src/radio/radio.js | 6 +++--- client/core/src/radio/radio.mdl.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/core/src/radio/radio.js b/client/core/src/radio/radio.js index 77e388927..b23abdfd0 100644 --- a/client/core/src/radio/radio.js +++ b/client/core/src/radio/radio.js @@ -7,12 +7,12 @@ export const NAME = util.getName(_NAME); directive.$inject = [resolveFactory.NAME]; export function directive(resolve) { - return{ + return { restrict: 'E', template: function(_, attrs) { - return resolve.getTemplate(_NAME, attrs); + return resolve.getTemplate(_NAME, attrs); } - } + }; } _module.directive(NAME, directive); diff --git a/client/core/src/radio/radio.mdl.js b/client/core/src/radio/radio.mdl.js index 6c0ccc9f4..135c32538 100644 --- a/client/core/src/radio/radio.mdl.js +++ b/client/core/src/radio/radio.mdl.js @@ -15,7 +15,7 @@ export function factory() { enabled: 'true', className: DEFAULT_CLASS } - } + }; } _module.factory(NAME, factory); From 601cf6db25ce721e573b0abd5e05adde1396f3bd Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 09:20:40 +0200 Subject: [PATCH 020/171] refactor watcher --- client/client/routes.json | 12 ++++----- client/client/src/card/card.html | 6 ++--- client/client/src/card/card.js | 3 +-- client/core/src/lib/equals.js | 42 ++++++++++++++++++++++++++++++ client/core/src/watcher/watcher.js | 31 ++++++++++++++-------- 5 files changed, 72 insertions(+), 22 deletions(-) diff --git a/client/client/routes.json b/client/client/routes.json index fc931bd3f..aff34bc6f 100644 --- a/client/client/routes.json +++ b/client/client/routes.json @@ -22,7 +22,7 @@ "state": "clientCard.basicData", "component": "vn-client-basic-data", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Datos básicos", @@ -33,7 +33,7 @@ "state": "clientCard.fiscalData", "component": "vn-client-fiscal-data", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Datos fiscales", @@ -44,7 +44,7 @@ "state": "clientCard.billingData", "component": "vn-client-billing-data", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Datos facturación", @@ -60,7 +60,7 @@ "state": "clientCard.addresses.list", "component": "vn-client-addresses", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Consignatarios", @@ -79,7 +79,7 @@ "state": "clientCard.webAccess", "component": "vn-client-web-access", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Acceso web", @@ -95,7 +95,7 @@ "state": "clientCard.notes.list", "component": "vn-client-notes", "params": { - "client": "card.client" + "client": "$ctrl.client" }, "menu": { "description": "Notas", diff --git a/client/client/src/card/card.html b/client/client/src/card/card.html index 0319c72fd..e9ebd07a0 100644 --- a/client/client/src/card/card.html +++ b/client/client/src/card/card.html @@ -1,13 +1,13 @@ diff --git a/client/client/src/card/card.js b/client/client/src/card/card.js index 06689a697..b21c3f636 100644 --- a/client/client/src/card/card.js +++ b/client/client/src/card/card.js @@ -9,6 +9,5 @@ export default class Controller { ngModule.component('vnClientCard', { template: require('./card.html'), - controller: Controller, - controllerAs: 'card' + controller: Controller }); diff --git a/client/core/src/lib/equals.js b/client/core/src/lib/equals.js index 40b36cca0..2e211153e 100644 --- a/client/core/src/lib/equals.js +++ b/client/core/src/lib/equals.js @@ -1,6 +1,48 @@ import {module} from '../module'; const isEqual = angular.equals; + +export const myEqual = (objA, objB, estrict) => { + let equals = true; + let estrictMode = estrict || true; + + if (Object.keys(objA).length !== Object.keys(objB).length) { + return false; + } + + for (let k in objA) { + if (!objB.hasOwnProperty(k)) { + return false; + } + if (estrictMode) { + if (typeof objA[k] !== typeof objB[k]) { + return false; + } + if (typeof objA[k] !== 'object' && objA[k] !== objB[k]) { + return false; + } + if (typeof objA[k] === 'object') { + equals = myEqual(objA[k], objB[k], estrictMode); + if (!equals) { + return false; + } + } + } else { + if (typeof objA[k] !== 'object' && objA[k] != objB[k]) { + return false; + } + if (typeof objA[k] === 'object') { + equals = myEqual(objA[k], objB[k], estrictMode); + if (!equals) { + return false; + } + } + } + } + + return equals; +}; + export default isEqual; export const NAME = 'equalsObject'; diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index bf085db4e..87b3d552c 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -1,8 +1,8 @@ import {module} from '../module'; import Component from '../lib/component'; import getModifiedData from '../lib/modified'; -// import copyObject from '../lib/copy'; -import isEqual from '../lib/equals'; +import copyObject from '../lib/copy'; +import {myEqual} from '../lib/equals'; /** * Component that checks for changes on a specific model property and @@ -11,12 +11,13 @@ import isEqual from '../lib/equals'; * properties are provided. */ export default class Watcher extends Component { - constructor($element, $scope, $state, $transitions, $http, vnApp, $translate) { + constructor($element, $scope, $state, $transitions, $http, vnApp, $translate, $timeout) { super($element); this.$scope = $scope; this.$state = $state; this.$http = $http; this.$translate = $translate; + this.$timeout = $timeout; this.vnApp = vnApp; this.state = null; @@ -48,7 +49,7 @@ export default class Watcher extends Component { // return new Promise((resolve, reject) => { this.$http.get(`${this.url}/${id}`).then( json => { - this.data = this.copyObject(json.data); + this.data = copyObject(json.data); this.copyData(); } // json => reject(json) @@ -126,11 +127,13 @@ export default class Watcher extends Component { } writeData(json, resolve) { - Object.keys(this.data).forEach( + /* Object.keys(this.data).forEach( key => { this.data[key] = json.data[key]; } - ); + );*/ + + this.data = Object.assign(this.data, json.data); this.copyData(); resolve(json); @@ -159,8 +162,13 @@ export default class Watcher extends Component { if (data) { Object.keys(data).forEach( val => { - if (data[val] !== "" && data[val] !== undefined && data[val] !== null) - copy[val] = data[val]; + if (data[val] !== "" && data[val] !== undefined && data[val] !== null) { + if (typeof data[val] === 'object') { + copy[val] = this.copyObject(data[val]); + } else { + copy[val] = data[val]; + } + } } ); } @@ -180,20 +188,21 @@ export default class Watcher extends Component { dataChanged() { let newData = this.copyObject(this.data); - return !isEqual(newData, this.orgData); + return !myEqual(newData, this.orgData); } onConfirmResponse(response) { if (response === 'ACCEPT') { - this.data = this.copyObject(this.orgData); + Object.assign(this.data, this.orgData); this.$state.go(this.state); + } else { this.state = null; } } } -Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate']; +Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate', '$timeout']; module.component('vnWatcher', { template: require('./watcher.html'), From e2312d954de44714e2a9bfb0f3b92c2d58d825d2 Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 09:31:28 +0200 Subject: [PATCH 021/171] watcher renamed properties --- client/core/src/watcher/watcher.js | 35 ++++++++++++------------------ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index 87b3d552c..ec541f21d 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -23,7 +23,7 @@ export default class Watcher extends Component { this.state = null; this.deregisterCallback = $transitions.onStart({}, transition => this.callback(transition)); - this.copyData(); + this.updateOriginalData(); } $onInit() { @@ -36,7 +36,7 @@ export default class Watcher extends Component { $onChanges(changes) { if (this.data) { - this.copyData(); + this.updateOriginalData(); } } @@ -50,7 +50,7 @@ export default class Watcher extends Component { this.$http.get(`${this.url}/${id}`).then( json => { this.data = copyObject(json.data); - this.copyData(); + this.updateOriginalData(); } // json => reject(json) ); @@ -127,15 +127,8 @@ export default class Watcher extends Component { } writeData(json, resolve) { - /* Object.keys(this.data).forEach( - key => { - this.data[key] = json.data[key]; - } - );*/ - - this.data = Object.assign(this.data, json.data); - - this.copyData(); + Object.assign(this.data, json.data); + this.updateOriginalData(); resolve(json); } @@ -153,26 +146,26 @@ export default class Watcher extends Component { resolve(); } - copyData() { - this.orgData = this.copyObject(this.data); + updateOriginalData() { + this.orgData = this.copyInNewObject(this.data); } - copyObject(data) { - let copy = {}; - if (data) { + copyInNewObject(data) { + let newCopy = {}; + if (data && typeof data === 'object') { Object.keys(data).forEach( val => { if (data[val] !== "" && data[val] !== undefined && data[val] !== null) { if (typeof data[val] === 'object') { - copy[val] = this.copyObject(data[val]); + newCopy[val] = this.copyInNewObject(data[val]); } else { - copy[val] = data[val]; + newCopy[val] = data[val]; } } } ); } - return copy; + return newCopy; } callback(transition) { @@ -187,7 +180,7 @@ export default class Watcher extends Component { } dataChanged() { - let newData = this.copyObject(this.data); + let newData = this.copyInNewObject(this.data); return !myEqual(newData, this.orgData); } From c4d6fd91db9a16390eb6b5d70bd3197083162736 Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 09:51:27 +0200 Subject: [PATCH 022/171] removed unnecessary function in equals.js --- client/core/src/lib/equals.js | 41 ------------------------------ client/core/src/watcher/watcher.js | 4 +-- 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/client/core/src/lib/equals.js b/client/core/src/lib/equals.js index 2e211153e..061d3f7c3 100644 --- a/client/core/src/lib/equals.js +++ b/client/core/src/lib/equals.js @@ -2,47 +2,6 @@ import {module} from '../module'; const isEqual = angular.equals; -export const myEqual = (objA, objB, estrict) => { - let equals = true; - let estrictMode = estrict || true; - - if (Object.keys(objA).length !== Object.keys(objB).length) { - return false; - } - - for (let k in objA) { - if (!objB.hasOwnProperty(k)) { - return false; - } - if (estrictMode) { - if (typeof objA[k] !== typeof objB[k]) { - return false; - } - if (typeof objA[k] !== 'object' && objA[k] !== objB[k]) { - return false; - } - if (typeof objA[k] === 'object') { - equals = myEqual(objA[k], objB[k], estrictMode); - if (!equals) { - return false; - } - } - } else { - if (typeof objA[k] !== 'object' && objA[k] != objB[k]) { - return false; - } - if (typeof objA[k] === 'object') { - equals = myEqual(objA[k], objB[k], estrictMode); - if (!equals) { - return false; - } - } - } - } - - return equals; -}; - export default isEqual; export const NAME = 'equalsObject'; diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index ec541f21d..1c6df4bfa 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -2,7 +2,7 @@ import {module} from '../module'; import Component from '../lib/component'; import getModifiedData from '../lib/modified'; import copyObject from '../lib/copy'; -import {myEqual} from '../lib/equals'; +import isEqual from '../lib/equals'; /** * Component that checks for changes on a specific model property and @@ -181,7 +181,7 @@ export default class Watcher extends Component { dataChanged() { let newData = this.copyInNewObject(this.data); - return !myEqual(newData, this.orgData); + return !isEqual(newData, this.orgData); } onConfirmResponse(response) { From 5b100e502cc11adaff6e9f18dd2035d89596b1c0 Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 09:53:40 +0200 Subject: [PATCH 023/171] watcher: removed unnecessary injection --- client/core/src/watcher/watcher.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index 1c6df4bfa..625fd5a82 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -11,13 +11,12 @@ import isEqual from '../lib/equals'; * properties are provided. */ export default class Watcher extends Component { - constructor($element, $scope, $state, $transitions, $http, vnApp, $translate, $timeout) { + constructor($element, $scope, $state, $transitions, $http, vnApp, $translate) { super($element); this.$scope = $scope; this.$state = $state; this.$http = $http; this.$translate = $translate; - this.$timeout = $timeout; this.vnApp = vnApp; this.state = null; @@ -195,7 +194,7 @@ export default class Watcher extends Component { } } -Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate', '$timeout']; +Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate']; module.component('vnWatcher', { template: require('./watcher.html'), From 28909da94e72553b119deb86cad8c7dbde8cfb24 Mon Sep 17 00:00:00 2001 From: Carlos Date: Thu, 5 Oct 2017 09:58:15 +0200 Subject: [PATCH 024/171] client side unit test for column-header --- .../src/column-header/column-header.spec.js | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 client/core/src/column-header/column-header.spec.js diff --git a/client/core/src/column-header/column-header.spec.js b/client/core/src/column-header/column-header.spec.js new file mode 100644 index 000000000..247b75993 --- /dev/null +++ b/client/core/src/column-header/column-header.spec.js @@ -0,0 +1,68 @@ +import './column-header.js'; + +describe('Component vnColumnHeader', () => { + let $componentController; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject(_$componentController_ => { + $componentController = _$componentController_; + })); + + describe('onClick()', () => { + it(`should change the ordenation to DESC (descendant) if it was ASC (ascendant)`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {selectColum: () => {}}}); + controller.order = 'ASC'; + controller.onClick(); + + expect(controller.order).toEqual('DESC'); + }); + + it(`should change the ordenation to ASC (ascendant) if it wasnt ASC`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {selectColum: () => {}}}); + controller.order = 'DESC or any other value that might occur'; + controller.onClick(); + + expect(controller.order).toEqual('ASC'); + }); + + it(`should call the selectColum() function after changing a value`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {selectColum: () => {}}}); + controller.order = 'Change me!'; + spyOn(controller.gridHeader, 'selectColum'); + controller.onClick(); + + expect(controller.gridHeader.selectColum).toHaveBeenCalledWith(controller); + }); + }); + + describe('showArrow()', () => { + it(`should return true when the type is DESC and MouseIsOver`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {selectColum: () => {}}}); + controller.mouseIsOver = true; + let result = controller.showArrow('DESC'); + + expect(result).toEqual(true); + }); + + it(`should return true if many conditions are true`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {currentColumn: {field: 'fields should be identical'}}}); + controller.field = 'fields should be identical'; + controller.order = 'ASC'; + let result = controller.showArrow('ASC'); + + expect(result).toEqual(true); + }); + + it(`should return false without type being DESC or any other values being true`, () => { + let controller = $componentController('vnColumnHeader', {}, {gridHeader: {currentColumn: {field: 'this field isnt the same as controllers field'}}}); + controller.field = 'I am the controllers field'; + controller.order = 'ASC'; + let result = controller.showArrow('ASC'); + + expect(result).toEqual(false); + }); + }); +}); From 562ffed388cdde056fb591d6078778464d959cea Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 11:04:22 +0200 Subject: [PATCH 025/171] bug fixed autocomplete and width dropdown --- client/core/src/autocomplete/autocomplete.js | 8 ++++---- client/core/src/watcher/watcher.js | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index 4c2fa6e89..09ee9c453 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -33,6 +33,10 @@ class Autocomplete extends Component { this._preLoad = true; this.getItems(); } + if (value && !this.width) { + let rectangle = this.$element[0].getBoundingClientRect(); + this.width = Math.round(rectangle.width) - 10; + } this._showDropDown = value; } @@ -271,9 +275,6 @@ class Autocomplete extends Component { this.showDropDown = this.mouseFocus; }); }); - - let rectangle = this.$element[0].getBoundingClientRect(); - this.width = Math.round(rectangle.width) - 10; } $onDestroy() { @@ -301,7 +302,6 @@ module.component('vnAutocomplete', { itemAs: '@?', field: '=', label: '@', - itemTemplate: '@?', multiple: '@?' }, transclude: { diff --git a/client/core/src/watcher/watcher.js b/client/core/src/watcher/watcher.js index 625fd5a82..bb6b753b2 100644 --- a/client/core/src/watcher/watcher.js +++ b/client/core/src/watcher/watcher.js @@ -187,7 +187,6 @@ export default class Watcher extends Component { if (response === 'ACCEPT') { Object.assign(this.data, this.orgData); this.$state.go(this.state); - } else { this.state = null; } From 4d487e79803f0016d05c450af88652aed400ddf7 Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 12:38:28 +0200 Subject: [PATCH 026/171] estructure for new module route --- client/modules.json | 8 +++++++ client/route/index.js | 1 + client/route/routes.json | 13 +++++++++++ client/route/src/index/index.html | 23 ++++++++++++++++++ client/route/src/index/index.js | 18 ++++++++++++++ client/route/src/index/item-route.js | 0 client/route/src/index/style.css | 0 client/route/src/locale/es.json | 3 +++ client/route/src/module.js | 5 ++++ client/route/src/route.js | 4 ++++ client/salix/src/configroutes.js | 2 +- gulpfile.js | 35 ++++------------------------ spliting/import.tpl.js | 1 - spliting/modules.json | 7 ------ spliting/require.tpl.js | 11 --------- 15 files changed, 80 insertions(+), 51 deletions(-) create mode 100644 client/modules.json create mode 100644 client/route/index.js create mode 100644 client/route/routes.json create mode 100644 client/route/src/index/index.html create mode 100644 client/route/src/index/index.js create mode 100644 client/route/src/index/item-route.js create mode 100644 client/route/src/index/style.css create mode 100644 client/route/src/locale/es.json create mode 100644 client/route/src/module.js create mode 100644 client/route/src/route.js delete mode 100644 spliting/import.tpl.js delete mode 100644 spliting/modules.json delete mode 100644 spliting/require.tpl.js diff --git a/client/modules.json b/client/modules.json new file mode 100644 index 000000000..6dbad069d --- /dev/null +++ b/client/modules.json @@ -0,0 +1,8 @@ +{ + "salix": [], + "auth": [], + "core": [], + "client": [], + "production": [], + "route": [] +} diff --git a/client/route/index.js b/client/route/index.js new file mode 100644 index 000000000..eadbde870 --- /dev/null +++ b/client/route/index.js @@ -0,0 +1 @@ +export * from './src/route'; diff --git a/client/route/routes.json b/client/route/routes.json new file mode 100644 index 000000000..e6da8754f --- /dev/null +++ b/client/route/routes.json @@ -0,0 +1,13 @@ +{ + "module": "route", + "name": "Route", + + "validations" : false, + "routes": [ + { + "url": "/routes", + "state": "routes", + "component": "vn-route-index" + } + ] +} \ No newline at end of file diff --git a/client/route/src/index/index.html b/client/route/src/index/index.html new file mode 100644 index 000000000..6cdc1a1d8 --- /dev/null +++ b/client/route/src/index/index.html @@ -0,0 +1,23 @@ +< +
+
+ + + + + + + + + + +
+ + + +
diff --git a/client/route/src/index/index.js b/client/route/src/index/index.js new file mode 100644 index 000000000..c8dc8ffd6 --- /dev/null +++ b/client/route/src/index/index.js @@ -0,0 +1,18 @@ +import ngModule from '../module'; +import './style.css'; +import './item-route'; + +export default class Controller { + constructor() { + this.model = {}; + } + search(index) { + index.filter.search = this.model.search; + index.accept(); + } +} + +ngModule.component('vnRouteIndex', { + template: require('./index.html'), + controller: Controller +}); diff --git a/client/route/src/index/item-route.js b/client/route/src/index/item-route.js new file mode 100644 index 000000000..e69de29bb diff --git a/client/route/src/index/style.css b/client/route/src/index/style.css new file mode 100644 index 000000000..e69de29bb diff --git a/client/route/src/locale/es.json b/client/route/src/locale/es.json new file mode 100644 index 000000000..0db3279e4 --- /dev/null +++ b/client/route/src/locale/es.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/client/route/src/module.js b/client/route/src/module.js new file mode 100644 index 000000000..779683e38 --- /dev/null +++ b/client/route/src/module.js @@ -0,0 +1,5 @@ +import {ng} from 'vendor'; +import 'core'; + +const ngModule = ng.module('route', []); +export default ngModule; diff --git a/client/route/src/route.js b/client/route/src/route.js new file mode 100644 index 000000000..69a09db10 --- /dev/null +++ b/client/route/src/route.js @@ -0,0 +1,4 @@ +export * from './module'; + +// import components +import './index/index'; diff --git a/client/salix/src/configroutes.js b/client/salix/src/configroutes.js index 734931316..8a3bdd156 100644 --- a/client/salix/src/configroutes.js +++ b/client/salix/src/configroutes.js @@ -1,5 +1,5 @@ import './spliting'; -import deps from 'spliting/modules.json'; +import deps from 'client/modules.json'; import ngModule from './module'; import {splitingRegister} from 'core'; diff --git a/gulpfile.js b/gulpfile.js index 866a65599..fd2b4a893 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,7 +17,8 @@ var srcDir = './client'; var buildDir = './services/nginx/static'; var langs = ['es', 'en']; -var modules = require('./spliting/modules.json'); +var modules = require('./client/modules.json'); + var webpackConfig = require('./webpack.config.js'); // Main tasks @@ -69,36 +70,9 @@ gulp.task('install', () => { })); }); -// Spliting - -var splitingFiles = './spliting/*'; - -gulp.task('spliting', function(cb) { - var importTpl = fs.readFileSync('./spliting/import.tpl.js', 'utf8'); - var requireTpl = fs.readFileSync('./spliting/require.tpl.js', 'utf8'); - - for (var modName in modules) { - var deps = modules[modName]; - var splitFile = `${srcDir}/${modName}/src/spliting.js`; - - try { - fs.unlinkSync(splitFile); - } catch (e) {} - - fs.appendFileSync(splitFile, importTpl); - - var i = deps.length; - while (i--) - fs.appendFileSync(splitFile, - requireTpl.replace(/\$module/g, deps[i])); - } - - cb(); -}); - // Webpack -gulp.task('webpack', ['spliting'], function(cb) { +gulp.task('webpack', function(cb) { var configCopy = Object.create(webpackConfig); var compiler = webpack(configCopy); @@ -109,7 +83,7 @@ gulp.task('webpack', ['spliting'], function(cb) { }); }); -gulp.task('webpack-dev-server', ['spliting'], function() { +gulp.task('webpack-dev-server', function() { var configCopy = Object.create(webpackConfig); for (var entry in configCopy.entry) { @@ -170,7 +144,6 @@ gulp.task('routes', function() { // Watch gulp.task('watch', function() { - gulp.watch(splitingFiles, ['spliting']); gulp.watch(routeFiles, ['routes']); gulp.watch(localeFiles, ['locales']); }); diff --git a/spliting/import.tpl.js b/spliting/import.tpl.js deleted file mode 100644 index 86ad3e68b..000000000 --- a/spliting/import.tpl.js +++ /dev/null @@ -1 +0,0 @@ -import * as core from 'core'; diff --git a/spliting/modules.json b/spliting/modules.json deleted file mode 100644 index 3efb5f977..000000000 --- a/spliting/modules.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "salix": ["client", "production"], - "auth": [], - "core": [], - "client": [], - "production": [] -} diff --git a/spliting/require.tpl.js b/spliting/require.tpl.js deleted file mode 100644 index d3fe92000..000000000 --- a/spliting/require.tpl.js +++ /dev/null @@ -1,11 +0,0 @@ - -export const $module = () => { - return new Promise(resolve => { - require.ensure([], () => { - require('$module'); - resolve('$module'); - }, '$module'); - }); -}; - -core.splitingRegister.register('$module', $module); From 431032177c3276a2ba5d7b4175cac08f8f4ce81a Mon Sep 17 00:00:00 2001 From: dherrero Date: Thu, 5 Oct 2017 14:26:04 +0200 Subject: [PATCH 027/171] new micro-service route: need reinstall all dependencies --- gulpfile.js | 3 +- services/nginx/conf-dev.conf | 3 + services/nginx/conf-prod.conf | 3 + services/route/.editorconfig | 13 ++++ services/route/.eslintignore | 1 + services/route/.eslintrc | 3 + services/route/.gitignore | 19 ++++++ services/route/.yo-rc.json | 3 + services/route/Dockerfile | 13 ++++ services/route/README.md | 3 + services/route/common/models/route.json | 29 +++++++++ services/route/package.json | 33 ++++++++++ services/route/server/boot/authentication.js | 6 ++ services/route/server/boot/root.js | 4 ++ services/route/server/component-config.json | 5 ++ services/route/server/config.json | 22 +++++++ services/route/server/datasources.json | 36 +++++++++++ services/route/server/datasources.test.json | 36 +++++++++++ .../route/server/middleware.development.json | 10 ++++ services/route/server/middleware.json | 60 +++++++++++++++++++ .../route/server/middleware/currentUser.js | 13 ++++ services/route/server/model-config.json | 50 ++++++++++++++++ services/route/server/server.js | 29 +++++++++ 23 files changed, 396 insertions(+), 1 deletion(-) create mode 100644 services/route/.editorconfig create mode 100644 services/route/.eslintignore create mode 100644 services/route/.eslintrc create mode 100644 services/route/.gitignore create mode 100644 services/route/.yo-rc.json create mode 100644 services/route/Dockerfile create mode 100644 services/route/README.md create mode 100644 services/route/common/models/route.json create mode 100644 services/route/package.json create mode 100644 services/route/server/boot/authentication.js create mode 100644 services/route/server/boot/root.js create mode 100644 services/route/server/component-config.json create mode 100644 services/route/server/config.json create mode 100644 services/route/server/datasources.json create mode 100644 services/route/server/datasources.test.json create mode 100644 services/route/server/middleware.development.json create mode 100644 services/route/server/middleware.json create mode 100644 services/route/server/middleware/currentUser.js create mode 100644 services/route/server/model-config.json create mode 100644 services/route/server/server.js diff --git a/gulpfile.js b/gulpfile.js index fd2b4a893..0383a1215 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -42,7 +42,8 @@ gulp.task('services', function() { 'auth', 'salix', 'client', - 'production' + 'production', + 'route' ]; for (var service of lbServices) diff --git a/services/nginx/conf-dev.conf b/services/nginx/conf-dev.conf index f5af8b9f6..e36a5a82a 100644 --- a/services/nginx/conf-dev.conf +++ b/services/nginx/conf-dev.conf @@ -40,6 +40,9 @@ http { location ~ ^/production(?:/(.*))?$ { proxy_pass http://127.0.0.1:3004/$1$is_args$args; } + location ~ ^/route(?:/(.*))?$ { + proxy_pass http://127.0.0.1:3005/$1$is_args$args; + } # Este tiene que ser el último location ~ ^(?:/(.*))?$ { proxy_pass http://127.0.0.1:3001/$1$is_args$args; diff --git a/services/nginx/conf-prod.conf b/services/nginx/conf-prod.conf index a1204c7a5..32d749780 100644 --- a/services/nginx/conf-prod.conf +++ b/services/nginx/conf-prod.conf @@ -35,6 +35,9 @@ http { location ~ ^/production(?:/(.*))?$ { proxy_pass http://production:3004/$1$is_args$args; } + location ~ ^/route(?:/(.*))?$ { + proxy_pass http://route:3005/$1$is_args$args; + } # Este tiene que ser el último location ~ ^(?:/(.*))?$ { proxy_pass http://salix:3001/$1$is_args$args; diff --git a/services/route/.editorconfig b/services/route/.editorconfig new file mode 100644 index 000000000..3ee22e5d3 --- /dev/null +++ b/services/route/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/services/route/.eslintignore b/services/route/.eslintignore new file mode 100644 index 000000000..44f397018 --- /dev/null +++ b/services/route/.eslintignore @@ -0,0 +1 @@ +/client/ \ No newline at end of file diff --git a/services/route/.eslintrc b/services/route/.eslintrc new file mode 100644 index 000000000..a6e52975a --- /dev/null +++ b/services/route/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "loopback" +} \ No newline at end of file diff --git a/services/route/.gitignore b/services/route/.gitignore new file mode 100644 index 000000000..aff1045b4 --- /dev/null +++ b/services/route/.gitignore @@ -0,0 +1,19 @@ +*.csv +*.dat +*.iml +*.log +*.out +*.pid +*.seed +*.sublime-* +*.swo +*.swp +*.tgz +*.xml +.DS_Store +.idea +.project +.strong-pm +coverage +node_modules +npm-debug.log diff --git a/services/route/.yo-rc.json b/services/route/.yo-rc.json new file mode 100644 index 000000000..02f3fc17b --- /dev/null +++ b/services/route/.yo-rc.json @@ -0,0 +1,3 @@ +{ + "generator-loopback": {} +} \ No newline at end of file diff --git a/services/route/Dockerfile b/services/route/Dockerfile new file mode 100644 index 000000000..0a4749712 --- /dev/null +++ b/services/route/Dockerfile @@ -0,0 +1,13 @@ +FROM node:6.9.1 + +COPY . /app + +WORKDIR /app + +RUN npm install + +RUN npm -g install pm2 + +CMD ["pm2-docker", "."] + +EXPOSE 3005 diff --git a/services/route/README.md b/services/route/README.md new file mode 100644 index 000000000..866baed5e --- /dev/null +++ b/services/route/README.md @@ -0,0 +1,3 @@ +# My Application + +The project is generated by [LoopBack](http://loopback.io). \ No newline at end of file diff --git a/services/route/common/models/route.json b/services/route/common/models/route.json new file mode 100644 index 000000000..a9525aaa5 --- /dev/null +++ b/services/route/common/models/route.json @@ -0,0 +1,29 @@ +{ + "name": "Route", + "base": "MyModel", + "validateUpsert": true, + "properties": { + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "date": { + "type": "date" + } + }, + "acls": [ + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }, + { + "accessType": "WRITE", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "DENY" + } + ] +} \ No newline at end of file diff --git a/services/route/package.json b/services/route/package.json new file mode 100644 index 000000000..3e8498bd7 --- /dev/null +++ b/services/route/package.json @@ -0,0 +1,33 @@ +{ + "name": "vn-route", + "version": "1.0.0", + "main": "server/server.js", + "scripts": { + "lint": "eslint .", + "start": "node .", + "posttest": "npm run lint && nsp check" + }, + "dependencies": { + "compression": "^1.0.3", + "cors": "^2.5.2", + "helmet": "^1.3.0", + "i18n": "^0.8.3", + "loopback": "^3.8.0", + "loopback-boot": "^2.24.0", + "loopback-component-explorer": "^4.2.0", + "loopback-connector-mysql": "^3.0.0", + "loopback-connector-remote": "^3.1.1", + "loopback-context": "^3.1.0", + "serve-favicon": "^2.0.1", + "strong-error-handler": "^2.1.0" + }, + "devDependencies": { + "nsp": "^2.1.0" + }, + "repository": { + "type": "git", + "url": "https://git.verdnatura.es/salix" + }, + "license": "GPL-3.0", + "description": "vn-route" +} diff --git a/services/route/server/boot/authentication.js b/services/route/server/boot/authentication.js new file mode 100644 index 000000000..8e88d4b55 --- /dev/null +++ b/services/route/server/boot/authentication.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function enableAuthentication(server) { + // enable authentication + server.enableAuth(); +}; diff --git a/services/route/server/boot/root.js b/services/route/server/boot/root.js new file mode 100644 index 000000000..a158fdfe5 --- /dev/null +++ b/services/route/server/boot/root.js @@ -0,0 +1,4 @@ + +module.exports = function(server) { + require ('../../../service/boot/root.js')(server); +}; diff --git a/services/route/server/component-config.json b/services/route/server/component-config.json new file mode 100644 index 000000000..f36959a48 --- /dev/null +++ b/services/route/server/component-config.json @@ -0,0 +1,5 @@ +{ + "loopback-component-explorer": { + "mountPath": "/explorer" + } +} diff --git a/services/route/server/config.json b/services/route/server/config.json new file mode 100644 index 000000000..383a2d909 --- /dev/null +++ b/services/route/server/config.json @@ -0,0 +1,22 @@ +{ + "restApiRoot": "/api", + "host": "0.0.0.0", + "port": 3005, + "remoting": { + "context": false, + "rest": { + "normalizeHttpPath": false, + "xml": false + }, + "json": { + "strict": false, + "limit": "100kb" + }, + "urlencoded": { + "extended": true, + "limit": "100kb" + }, + "cors": false, + "handleErrors": false + } +} diff --git a/services/route/server/datasources.json b/services/route/server/datasources.json new file mode 100644 index 000000000..7b160e957 --- /dev/null +++ b/services/route/server/datasources.json @@ -0,0 +1,36 @@ +{ + "db": { + "name": "db", + "connector": "memory", + "file": "db.json" + }, + "auth": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "vn": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "client": { + "name": "client", + "connector": "remote", + "url": "http://localhost:3002/api" + } +} diff --git a/services/route/server/datasources.test.json b/services/route/server/datasources.test.json new file mode 100644 index 000000000..6e81700ce --- /dev/null +++ b/services/route/server/datasources.test.json @@ -0,0 +1,36 @@ +{ + "db": + { + "name": "db", + "connector": "memory", + "file": "db.json" + }, + "auth": + { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "" + }, + "vn": { + "name": "mysql", + "connector": "mysql", + "database": "salix", + "debug": false, + "host": "localhost", + "port": 3306, + "username": "root", + "password": "", + "connectTimeout": 20000, + "acquireTimeout": 20000 + }, + "client": { + "name": "client", + "connector": "remote", + "url": "http://localhost:3002/api" + } +} diff --git a/services/route/server/middleware.development.json b/services/route/server/middleware.development.json new file mode 100644 index 000000000..071c11a30 --- /dev/null +++ b/services/route/server/middleware.development.json @@ -0,0 +1,10 @@ +{ + "final:after": { + "strong-error-handler": { + "params": { + "debug": true, + "log": true + } + } + } +} diff --git a/services/route/server/middleware.json b/services/route/server/middleware.json new file mode 100644 index 000000000..810050770 --- /dev/null +++ b/services/route/server/middleware.json @@ -0,0 +1,60 @@ +{ + "initial:before": { + "loopback#favicon": {} + }, + "initial": { + "compression": {}, + "cors": { + "params": { + "origin": true, + "credentials": true, + "maxAge": 86400 + } + }, + "helmet#xssFilter": {}, + "helmet#frameguard": { + "params": [ + "deny" + ] + }, + "helmet#hsts": { + "params": { + "maxAge": 0, + "includeSubdomains": true + } + }, + "helmet#hidePoweredBy": {}, + "helmet#ieNoOpen": {}, + "helmet#noSniff": {}, + "helmet#noCache": { + "enabled": false + }, + "loopback-context#per-request": { + "params": { + "enableHttpContext": true + } + } + }, + "session": {}, + "auth": { + "loopback#token": {} + }, + "auth:after": { + "./middleware/currentUser": {} + }, + "parse": {}, + "routes": { + "loopback#rest": { + "paths": [ + "${restApiRoot}" + ] + } + }, + "files": {}, + "final": { + "loopback#urlNotFound": {} + }, + "final:after": { + "strong-error-handler": {} + } +} diff --git a/services/route/server/middleware/currentUser.js b/services/route/server/middleware/currentUser.js new file mode 100644 index 000000000..6024b442e --- /dev/null +++ b/services/route/server/middleware/currentUser.js @@ -0,0 +1,13 @@ +module.exports = function(options) { + return function storeCurrentUser(req, res, next) { + if (!req.accessToken) { + return next(); + } + let LoopBackContext = require('loopback-context'); + let loopbackContext = LoopBackContext.getCurrentContext(); + if (loopbackContext) { + loopbackContext.set('currentUser', req.accessToken.userId); + } + next(); + }; +}; diff --git a/services/route/server/model-config.json b/services/route/server/model-config.json new file mode 100644 index 000000000..b75a5d0fe --- /dev/null +++ b/services/route/server/model-config.json @@ -0,0 +1,50 @@ +{ + "_meta": { + "sources": [ + "loopback/common/models", + "loopback/server/models", + "../../service/models", + "../common/models", + "./models" + ], + "mixins": [ + "loopback/common/mixins", + "loopback/server/mixins", + "../common/mixins", + "./mixins" + ] + }, + "user": { + "dataSource": "auth" + }, + "AccessToken": { + "dataSource": "auth", + "relations": { + "user": { + "type": "belongsTo", + "model": "user", + "foreignKey": "userId" + } + } + }, + "ACL": { + "dataSource": "auth", + "public": false + }, + "RoleMapping": { + "dataSource": "auth", + "public": false + }, + "Role": { + "dataSource": "auth", + "public": false + }, + "Account": { + "dataSource": "auth" + }, + "Route": { + "dataSource": "vn", + "public": true + } + +} diff --git a/services/route/server/server.js b/services/route/server/server.js new file mode 100644 index 000000000..ef738abce --- /dev/null +++ b/services/route/server/server.js @@ -0,0 +1,29 @@ +'use strict'; + +var loopback = require('loopback'); +var boot = require('loopback-boot'); + +var app = module.exports = loopback(); + +app.start = function() { + // start the web server + return app.listen(function() { + app.emit('started'); + var baseUrl = app.get('url').replace(/\/$/, ''); + console.log('Web server listening at: %s', baseUrl); + if (app.get('loopback-component-explorer')) { + var explorerPath = app.get('loopback-component-explorer').mountPath; + console.log('Browse your REST API at %s%s', baseUrl, explorerPath); + } + }); +}; + +// Bootstrap the application, configure models, datasources and middleware. +// Sub-apps like REST API are mounted via boot scripts. +boot(app, __dirname, function(err) { + if (err) throw err; + + // start the server if `$ node server.js` + if (require.main === module) + app.start(); +}); From de9d9e53e29614102492416800039bfd25f98b24 Mon Sep 17 00:00:00 2001 From: Carlos Date: Thu, 5 Oct 2017 14:28:57 +0200 Subject: [PATCH 028/171] client side unit test for dialog --- client/core/src/dialog/dialog.js | 18 +++--- client/core/src/dialog/dialog.spec.js | 91 +++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 client/core/src/dialog/dialog.spec.js diff --git a/client/core/src/dialog/dialog.js b/client/core/src/dialog/dialog.js index 5c85ea14d..3e4ac3eb5 100644 --- a/client/core/src/dialog/dialog.js +++ b/client/core/src/dialog/dialog.js @@ -20,13 +20,13 @@ export default class Dialog extends Component { */ show() { let style = this.dialog.style; - let screenMargin = 20; - let window = this.window; let innerWidth = window.innerWidth; let innerHeight = window.innerHeight; let width = this.dialog.offsetWidth; let height = this.dialog.offsetHeight; + let screenMargin = 20; + let dblMargin = screenMargin * 2; if (width + screenMargin > innerWidth) { width = innerWidth - dblMargin; @@ -37,10 +37,8 @@ export default class Dialog extends Component { style.height = height + 'px'; } - this.keypressHandler = - event => this.onKeypress(event); - this.document.addEventListener('keypress', - this.keypressHandler); + this.keypressHandler = event => this.onKeypress(event); + this.document.addEventListener('keypress', this.keypressHandler); this.element.style.display = 'block'; if (this.onOpen) @@ -68,12 +66,12 @@ export default class Dialog extends Component { realHide() { this.element.style.display = 'none'; - this.document.removeEventListener('keypress', - this.keypressHandler); + this.document.removeEventListener('keypress', this.keypressHandler); this.lastEvent = null; } onButtonClick(event) { + console.log(event); let buttonBar = this.element.querySelector('.button-bar'); let buttons = buttonBar.querySelector('tpl-buttons'); let node = event.target; @@ -111,8 +109,8 @@ module.component('vnDialog', { tplButtons: 'tplButtons' }, bindings: { - onOpen: '&', - onResponse: '&' + onOpen: '&?', + onResponse: '&?' }, controller: Dialog }); diff --git a/client/core/src/dialog/dialog.spec.js b/client/core/src/dialog/dialog.spec.js new file mode 100644 index 000000000..25df231a7 --- /dev/null +++ b/client/core/src/dialog/dialog.spec.js @@ -0,0 +1,91 @@ +import './dialog.js'; + +describe('Component vnDialog', () => { + let $componentController; + let $element; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject(_$componentController_ => { + $componentController = _$componentController_; + $element = angular.element('
'); + })); + + describe('show()', () => { + it(`should define keypressHandler function, call addEventListener function and define element.style.display to block then call onOpen function`, () => { + window.innerHeight = 600; + window.innerWidth = 800; + let controller = $componentController('vnDialog', {$element}, {onOpen: () => {}, dialog: {style: {}, offsetWidth: 780, offsetHeight: 581}}); + spyOn(controller.document, 'addEventListener'); + spyOn(controller, 'onOpen'); + controller.show(); + + expect(controller.keypressHandler).toBeDefined(); + expect(controller.document.addEventListener).toHaveBeenCalledWith('keypress', controller.keypressHandler); + expect(controller.element.style.display).toEqual('block'); + expect(controller.onOpen).toHaveBeenCalledWith(); + }); + + it(`should define keypressHandler function, call addEventListener function and define element.style.display to block and never call onOpen function`, () => { + window.innerHeight = 600; + window.innerWidth = 800; + let controller = $componentController('vnDialog', {$element}, {dialog: {style: {}, offsetWidth: 781, offsetHeight: 581}}); + spyOn(controller.document, 'addEventListener'); + controller.show(); + + expect(controller.keypressHandler).toBeDefined(); + expect(controller.document.addEventListener).toHaveBeenCalledWith('keypress', controller.keypressHandler); + expect(controller.element.style.display).toEqual('block'); + expect(controller.onOpen).not.toBeDefined(); + }); + }); + + describe('hide()', () => { + it(`should call fireResponse() and realHide()`, () => { + let controller = $componentController('vnDialog', {$element}); + spyOn(controller, 'fireResponse'); + spyOn(controller, 'realHide'); + controller.hide(); + + expect(controller.fireResponse).toHaveBeenCalledWith(); + expect(controller.realHide).toHaveBeenCalledWith(); + }); + }); + + describe('fireResponse()', () => { + it(`should return cancel as false`, () => { + let controller = $componentController('vnDialog', {$element}); + let result = controller.fireResponse('I am the answer!'); + + expect(controller.onResponse).not.toBeDefined(); + expect(result).toEqual(false); + }); + + it(`should return onResponse()`, () => { + let text = 'I am the answer!'; + let controller = $componentController('vnDialog', {$element}, {onResponse: () => { + return {response: text}; + }}); + let result = controller.fireResponse(text); + + expect(result.response).toEqual(text); + }); + }); + + describe('realHide()', () => { + it(`should set element.style.display and lastEvent properties and call removeEvenListener()`, () => { + let controller = $componentController('vnDialog', {$element}); + spyOn(controller.document, 'removeEventListener'); + + expect(controller.element.style.display).not.toEqual('none'); + expect(controller.lastEvent).not.toBeDefined(); + controller.realHide(); + + expect(controller.element.style.display).toEqual('none'); + expect(controller.document.removeEventListener).toHaveBeenCalledWith('keypress', controller.keypressHandler); + expect(controller.lastEvent).toEqual(null); + }); + }); +}); From e6acc57faec2d1b4caa93aa8ca39a29e6ac4fa88 Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 6 Oct 2017 15:33:21 +0200 Subject: [PATCH 029/171] client side unit test for dialog onButtonClick() --- client/core/src/dialog/dialog.js | 2 -- client/core/src/dialog/dialog.spec.js | 34 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/client/core/src/dialog/dialog.js b/client/core/src/dialog/dialog.js index 3e4ac3eb5..a8d33b4ca 100644 --- a/client/core/src/dialog/dialog.js +++ b/client/core/src/dialog/dialog.js @@ -71,11 +71,9 @@ export default class Dialog extends Component { } onButtonClick(event) { - console.log(event); let buttonBar = this.element.querySelector('.button-bar'); let buttons = buttonBar.querySelector('tpl-buttons'); let node = event.target; - while (node.parentNode != buttons) { if (node == buttonBar) return; node = node.parentNode; diff --git a/client/core/src/dialog/dialog.spec.js b/client/core/src/dialog/dialog.spec.js index 25df231a7..68d32177a 100644 --- a/client/core/src/dialog/dialog.spec.js +++ b/client/core/src/dialog/dialog.spec.js @@ -88,4 +88,38 @@ describe('Component vnDialog', () => { expect(controller.lastEvent).toEqual(null); }); }); + + describe('onButtonClick()', () => { + it(`should call realHide if cancel isn't false`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + controller.element.className = 'tpl-buttons'; + let childElement = document.createElement('div'); + childElement.className = 'button-bar'; + controller.element.appendChild(childElement); + let event = {target: controller.element, attribute: true}; + spyOn(controller, 'realHide'); + spyOn(controller, 'fireResponse').and.returnValue(true); + controller.onButtonClick(event); + + expect(controller.realHide).toHaveBeenCalledWith(); + }); + + it(`should call fireResponse with the value of response`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + controller.element.className = 'tpl-buttons'; + let childElement = document.createElement('div'); + childElement.className = 'button-bar'; + controller.element.appendChild(childElement); + let event = {target: controller.element}; + let attribute = document.createAttribute('response'); + attribute.value = 'I am the response!'; + controller.element.setAttributeNode(attribute); + spyOn(controller, 'fireResponse'); + controller.onButtonClick(event); + + expect(controller.fireResponse).toHaveBeenCalledWith('I am the response!'); + }); + }); }); From 022450000e7ed42ef290dc1d1d6579d4fe9a5866 Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 6 Oct 2017 15:36:25 +0200 Subject: [PATCH 030/171] micro-refactor on spec file --- client/core/src/dialog/dialog.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/core/src/dialog/dialog.spec.js b/client/core/src/dialog/dialog.spec.js index 68d32177a..fc6152508 100644 --- a/client/core/src/dialog/dialog.spec.js +++ b/client/core/src/dialog/dialog.spec.js @@ -112,11 +112,11 @@ describe('Component vnDialog', () => { let childElement = document.createElement('div'); childElement.className = 'button-bar'; controller.element.appendChild(childElement); - let event = {target: controller.element}; let attribute = document.createAttribute('response'); attribute.value = 'I am the response!'; controller.element.setAttributeNode(attribute); spyOn(controller, 'fireResponse'); + let event = {target: controller.element}; controller.onButtonClick(event); expect(controller.fireResponse).toHaveBeenCalledWith('I am the response!'); From aec32f5e4a2f0df89c5d73e92d687e317c5d7185 Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 6 Oct 2017 16:30:51 +0200 Subject: [PATCH 031/171] client side unit test for dialog onBackgroundMouseDown() --- client/core/src/dialog/dialog.spec.js | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/client/core/src/dialog/dialog.spec.js b/client/core/src/dialog/dialog.spec.js index fc6152508..15396399f 100644 --- a/client/core/src/dialog/dialog.spec.js +++ b/client/core/src/dialog/dialog.spec.js @@ -122,4 +122,40 @@ describe('Component vnDialog', () => { expect(controller.fireResponse).toHaveBeenCalledWith('I am the response!'); }); }); + + describe('onDialogMouseDown()', () => { + it(`should set controller's lastEvent property`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + let event = {target: controller.element}; + controller.onDialogMouseDown(event); + + expect(controller.lastEvent).toEqual(event); + }); + }); + + describe('onBackgroundMouseDown()', () => { + it(`shouldn't call hide() function as event equals lastEvent`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + let event = {target: controller.element}; + controller.lastEvent = event; + spyOn(controller, 'hide'); + controller.onBackgroundMouseDown(event); + + expect(controller.hide).not.toHaveBeenCalledWith(); + }); + + it(`should call hide() function as event doesn't equal lastEvent`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + let event = {target: controller.element}; + controller.lastEvent = event; + controller.lastEvent = 'the singularity event!'; + spyOn(controller, 'hide'); + controller.onBackgroundMouseDown(event); + + expect(controller.hide).toHaveBeenCalledWith(); + }); + }); }); From c34100948938f72f71fe346a60ed2b731c6a5ce4 Mon Sep 17 00:00:00 2001 From: Carlos Date: Mon, 9 Oct 2017 14:30:23 +0200 Subject: [PATCH 032/171] CLient side unit test for dialog onKeypress() --- client/core/src/dialog/dialog.spec.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/client/core/src/dialog/dialog.spec.js b/client/core/src/dialog/dialog.spec.js index 15396399f..5102966d4 100644 --- a/client/core/src/dialog/dialog.spec.js +++ b/client/core/src/dialog/dialog.spec.js @@ -158,4 +158,28 @@ describe('Component vnDialog', () => { expect(controller.hide).toHaveBeenCalledWith(); }); }); + + describe('onKeypress()', () => { + it(`should call hide() if the key pressed equal the code 27`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + let event = {target: controller.element}; + event.keyCode = 27; + spyOn(controller, 'hide'); + controller.onKeypress(event); + + expect(controller.hide).toHaveBeenCalledWith(); + }); + + it(`should't call hide() as the key pressed equal the code 999`, () => { + let controller = $componentController('vnDialog', {$element}); + controller.element = document.createElement('div'); + let event = {target: controller.element}; + event.keyCode = 999; + spyOn(controller, 'hide'); + controller.onKeypress(event); + + expect(controller.hide).not.toHaveBeenCalledWith(); + }); + }); }); From 48cac24d88b6e762cd3e6ad9beb2b7090b8b1837 Mon Sep 17 00:00:00 2001 From: Vicente Falco Date: Tue, 10 Oct 2017 11:09:47 +0200 Subject: [PATCH 033/171] Jenkins y routes --- Jenkinsfile | 91 +++++++------------ .../mailer/application/config/app.test.json | 9 ++ .../mailer/application/config/mysql.test.json | 7 ++ .../mailer/application/config/smtp.test.json | 14 +++ .../common/methods/fake-production/route.js | 3 +- 5 files changed, 66 insertions(+), 58 deletions(-) create mode 100644 services/mailer/application/config/app.test.json create mode 100644 services/mailer/application/config/mysql.test.json create mode 100644 services/mailer/application/config/smtp.test.json diff --git a/Jenkinsfile b/Jenkinsfile index ce91d8649..59d63fb9f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,31 +1,19 @@ #!/usr/bin/env groovy -import groovy.json.*; - -def image; def branchName = "${env.BRANCH_NAME}"; -def branchNameTest = "preprod"; -def branchNameProd = "master"; -def prefixDocker = "test"; -def dockerNginxName = ["nginx", "-p 80:80 --privileged --link test-auth:auth --link test-salix:salix --link test-client:client --link test-mailer:mailer --link test-production:production"] -def dockerAuthName = ["auth", "-p 3000:3000"] -def dockerSalixName = ["salix", "-p 3001:3001"] -def dockerClientName = ["client", "-p 3002:3002"] -def dockerMailerName = ["mailer", "-p 3003:3003"] -def dockerProductionName = ["production", "-p 3004:3004"] - def buildNumber = "${env.BUILD_NUMBER}"; +def branchProduction = "master" +def branchTest = "test"; +def dockerHost = "${env.DOCKER_HOST}"; -def dockers = [dockerAuthName, dockerSalixName, dockerClientName, dockerMailerName, dockerProductionName, dockerNginxName] -node { - - if (branchName == branchNameProd) - prefixDocker = "prod"; +if (branchName == branchProduction) + dockerHost = "tcp://172.16.255.29:2375"; +node +{ stage ('Checkout') { checkout scm - } stage ('install modules'){ sh "npm install" @@ -35,47 +23,36 @@ node { sh "gulp build" } - for (int i = 0; i < dockers.size(); i++) + + stage ("docker ${element}") { - def element = dockers[i][0] - def ports = dockers[i][1] - - stage ("docker ${element}") + stage ("Stopping ${prefixDocker}-${element} actual") { - stage ("Stopping ${prefixDocker}-${element} actual") + try { - try - { - def returnDocker = sh (script: "docker stop ${prefixDocker}-${element}", returnStdout: true).trim(); - echo "${returnDocker}"; - returnDocker = sh (script: "docker rm ${prefixDocker}-${element}", returnStdout: false).trim(); - //echo "${returnDocker}"; - returnDocker = sh (script: "docker rmi ${prefixDocker}-${element}:${buildNumber-3}", returnStdout: true).trim(); - echo "borran ${prefixDocker}-${element}:${buildNumber-3}"; - //echo "${returnDocker}"; - }catch(Exception _){ - echo "Error Stage Stopping" - } - } - stage ("Create Docker Image ${element}") { - dir("./services/${element}"){ - stage ("Install modules service ${element}"){ - if (fileExists('./package.json')) - sh "npm i" - } - stage("Build image ${element}"){ - image = docker.build("${prefixDocker}-${element}:${buildNumber}", ".") - } - } - } - stage ("Run Docker ${element}"){ - image.run ("${ports} --name ${prefixDocker}-${element}") - } - /* - stage('docker registry'){ - docker.withServer('tcp://harbor.verdnatura.es','docker-registry') - } - */ + def returnDocker = sh (script: "docker stop ${prefixDocker}-${element}", returnStdout: true).trim(); + echo "${returnDocker}"; + returnDocker = sh (script: "docker rm ${prefixDocker}-${element}", returnStdout: false).trim(); + //echo "${returnDocker}"; + returnDocker = sh (script: "docker rmi ${prefixDocker}-${element}:${buildNumber-3}", returnStdout: true).trim(); + echo "borran ${prefixDocker}-${element}:${buildNumber-3}"; + //echo "${returnDocker}"; + }catch(Exception _){ + echo "Error Stage Stopping" + } } + + stage ("Generar dockers") + { + stage ("build dockers") + { + sh "docker-compose build " + } + + stage ("up dockers") + { + sh "docker-compose up -d" + } + } } } \ No newline at end of file diff --git a/services/mailer/application/config/app.test.json b/services/mailer/application/config/app.test.json new file mode 100644 index 000000000..c9ec4174b --- /dev/null +++ b/services/mailer/application/config/app.test.json @@ -0,0 +1,9 @@ +{ + "name": "MailServer", + "version": "1.0.0", + "port": 3003, + "debug": false, + "defaultLanguage": "es", + "senderMail": "noreply@localhost", + "senderName": "" +} \ No newline at end of file diff --git a/services/mailer/application/config/mysql.test.json b/services/mailer/application/config/mysql.test.json new file mode 100644 index 000000000..dee7b6929 --- /dev/null +++ b/services/mailer/application/config/mysql.test.json @@ -0,0 +1,7 @@ +{ + "host": "localhost", + "port": 3306, + "user": "rot", + "password": "", + "database": "vn" +} \ No newline at end of file diff --git a/services/mailer/application/config/smtp.test.json b/services/mailer/application/config/smtp.test.json new file mode 100644 index 000000000..8ce24c53e --- /dev/null +++ b/services/mailer/application/config/smtp.test.json @@ -0,0 +1,14 @@ +{ + "host": "smtp.verdnatura.es", + "port": 465, + "secure": true, + "auth": { + "id": 10240, + "user": "nocontestar", + "pass": "ub606cux7op" + }, + "tls": { + "rejectUnauthorized": false + }, + "pool": true +} \ No newline at end of file diff --git a/services/production/common/methods/fake-production/route.js b/services/production/common/methods/fake-production/route.js index 313c1e0d4..cd89819d5 100644 --- a/services/production/common/methods/fake-production/route.js +++ b/services/production/common/methods/fake-production/route.js @@ -12,7 +12,8 @@ module.exports = function(FakeProduction) { }); FakeProduction.routeList = function(ctx, cb) { - var query = `select routeFk from FakeProduction where routeFk is not null group by RouteFk order by routeFk`; + // var query = `select routeFk from FakeProduction where routeFk is not null group by RouteFk order by routeFk`; + let query = `call salix.production_control_source(1,1)`; var params = []; FakeProduction.rawSql(query, params, cb) .then(function(response){ From 96235a6752f4686708c2f32ccf975b20f331d696 Mon Sep 17 00:00:00 2001 From: dherrero Date: Tue, 10 Oct 2017 11:14:35 +0200 Subject: [PATCH 034/171] route service models --- client/core/src/autocomplete/autocomplete.js | 1 - client/core/src/drop-down/drop-down.js | 2 +- services/production/common/models/route.json | 18 ++++++++++-------- services/route/common/models/route.json | 18 ++++++++++-------- services/route/server/datasources.json | 5 +++++ services/route/server/model-config.json | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index 09ee9c453..ae31bff8c 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -299,7 +299,6 @@ module.component('vnAutocomplete', { initialData: ' Date: Tue, 10 Oct 2017 12:37:52 +0200 Subject: [PATCH 035/171] textfield: icons position changed --- client/core/src/textfield/textfield.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/core/src/textfield/textfield.html b/client/core/src/textfield/textfield.html index b62b18f7e..3b8f24e1e 100644 --- a/client/core/src/textfield/textfield.html +++ b/client/core/src/textfield/textfield.html @@ -16,8 +16,8 @@ ng-readonly="$ctrl.readonly" />
- clear info_outline + clear
From 1bc3a0bdd721b7a1f419f4666d8c0f33c49f5eda Mon Sep 17 00:00:00 2001 From: dherrero Date: Tue, 10 Oct 2017 12:56:03 +0200 Subject: [PATCH 036/171] autocomplete bug fixed in loadMore button --- client/core/src/autocomplete/autocomplete.html | 1 + client/core/src/autocomplete/autocomplete.js | 11 +++++++++-- client/core/src/drop-down/drop-down.html | 2 +- client/core/src/drop-down/drop-down.js | 3 ++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/client/core/src/autocomplete/autocomplete.html b/client/core/src/autocomplete/autocomplete.html index 65150f09c..962798629 100644 --- a/client/core/src/autocomplete/autocomplete.html +++ b/client/core/src/autocomplete/autocomplete.html @@ -7,6 +7,7 @@ filter="true" load-more="$ctrl.getItems()" show-load-more="$ctrl.maxRow" + remove-load-more="$ctrl.removeLoadMore" filter-action="$ctrl.findItems(search)" item-width="$ctrl.width" multiple="$ctrl.multiple" diff --git a/client/core/src/autocomplete/autocomplete.js b/client/core/src/autocomplete/autocomplete.js index ae31bff8c..f0e6eb304 100644 --- a/client/core/src/autocomplete/autocomplete.js +++ b/client/core/src/autocomplete/autocomplete.js @@ -23,6 +23,7 @@ class Autocomplete extends Component { this.displayValueMultiCheck = []; this._multiField = []; this.readonly = true; + this.removeLoadMore = false; } get showDropDown() { @@ -229,9 +230,11 @@ class Autocomplete extends Component { let json = JSON.stringify(filter); + this.removeLoadMore = false; + this.$http.get(`${this.url}?filter=${json}`).then( json => { - if (json.data.length) + if (json.data.length) { json.data.forEach( el => { if (this.multiple) { @@ -240,8 +243,12 @@ class Autocomplete extends Component { this.items.push(el); } ); - else + if (filter.skip === 0 && this.maxRow && json.data.length < this.maxRow) { + this.removeLoadMore = true; + } + } else { this.maxRow = false; + } } ); } diff --git a/client/core/src/drop-down/drop-down.html b/client/core/src/drop-down/drop-down.html index 59a7622de..9bab06069 100644 --- a/client/core/src/drop-down/drop-down.html +++ b/client/core/src/drop-down/drop-down.html @@ -17,7 +17,7 @@
{{item.name}}