diff --git a/client/salix/src/components/index.js b/client/salix/src/components/index.js index afd469e89a..9e8b6f69be 100644 --- a/client/salix/src/components/index.js +++ b/client/salix/src/components/index.js @@ -4,3 +4,4 @@ import './main-menu/main-menu'; import './left-menu/left-menu'; import './left-menu/menu-item'; import './topbar/topbar'; +import './user-configuration-popover' diff --git a/client/salix/src/components/main-menu/main-menu.html b/client/salix/src/components/main-menu/main-menu.html index f7eb343bac..ba6cd66885 100644 --- a/client/salix/src/components/main-menu/main-menu.html +++ b/client/salix/src/components/main-menu/main-menu.html @@ -1,6 +1,8 @@
+ ng-click="$ctrl.openUserConfiguration($event)" + id="user" + class="unselectable">
{{currentUserName}}
+
+ + + + + \ No newline at end of file diff --git a/client/salix/src/components/main-menu/main-menu.js b/client/salix/src/components/main-menu/main-menu.js index ee2727f395..0912d394e9 100644 --- a/client/salix/src/components/main-menu/main-menu.js +++ b/client/salix/src/components/main-menu/main-menu.js @@ -34,6 +34,11 @@ export default class MainMenu { }); } + openUserConfiguration(event) { + this.$.popover.parent = event.target; + this.$.popover.show(); + } + onLogoutClick() { this.$window.location = '/logout'; } diff --git a/client/salix/src/components/user-configuration-popover/index.html b/client/salix/src/components/user-configuration-popover/index.html new file mode 100644 index 0000000000..c2255ca7d3 --- /dev/null +++ b/client/salix/src/components/user-configuration-popover/index.html @@ -0,0 +1,79 @@ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+
diff --git a/client/salix/src/components/user-configuration-popover/index.js b/client/salix/src/components/user-configuration-popover/index.js new file mode 100644 index 0000000000..8b084c11d5 --- /dev/null +++ b/client/salix/src/components/user-configuration-popover/index.js @@ -0,0 +1,90 @@ +import ngModule from '../../module'; +import './style.scss' + +class Controller { + constructor($scope, $http, $state, vnApp, $translate) { + this.$scope = $scope; + this.$http = $http; + this.$state = $state; + this.vnApp = vnApp; + this.$translate = $translate; + this.getUserConfig() + } + + set localBank(value) { + window.localStorage.localBank = value; + this.showOk(); + } + + get localBank() { + return parseInt(window.localStorage.localBank); + } + + set localWarehouse(value) { + window.localStorage.localWarehouse = value; + this.showOk(); + } + + get localWarehouse() { + return parseInt(window.localStorage.localWarehouse); + } + + set localCompany(value) { + window.localStorage.localCompany = value; + this.showOk(); + } + + get localCompany() { + return parseInt(window.localStorage.localCompany); + } + + set warehouseFk(value) { + this.warehouse = value; + this.setUserConfig('warehouseFk'); + } + + get warehouseFk () { + return this.warehouse; + } + + set companyFk(value) { + this.company = value; + this.setUserConfig('companyFk'); + } + + get companyFk () { + return this.company; + } + + showOk() { + this.vnApp.showSuccess(this.$translate.instant('Data saved!')); + } + + getUserConfig() { + this.$http.get('/api/UserConfigs/getUserConfig') + .then(res => { + if (res.data.response.warehouseFk) + this.warehouse = res.data.response.warehouseFk; + + if (res.data.response.companyFk) + this.company = res.data.response.companyFk; + }); + } + + setUserConfig(property) { + let params = {}; + params[property] = this[property]; + + this.$http.post('/api/UserConfigs/setUserConfig', params) + .then(() => { + this.showOk(); + }); + } +} + +Controller.$inject = ['$scope', '$http', '$state', 'vnApp', '$translate']; + +ngModule.component('vnUserConfigurationPopover', { + template: require('./index.html'), + controller: Controller +}); diff --git a/client/salix/src/components/user-configuration-popover/index.spec.js b/client/salix/src/components/user-configuration-popover/index.spec.js new file mode 100644 index 0000000000..250983ac59 --- /dev/null +++ b/client/salix/src/components/user-configuration-popover/index.spec.js @@ -0,0 +1,97 @@ +import './index.js'; + +describe('Salix', () => { + describe('Component vnUserConfigurationPopover', () => { + let $componentController; + let controller; + let $httpBackend; + let $scope; + + beforeEach(() => { + angular.mock.module('salix'); + }); + + beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, $rootScope) => { + $componentController = _$componentController_; + $httpBackend = _$httpBackend_; + $httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({}); + $scope = $rootScope.$new(); + controller = $componentController('vnUserConfigurationPopover', {$scope: $scope, $translate: null}); + })); + + describe('localBank() setter', () => { + it('should set window.localStorage.localBank and call showOk', () => { + spyOn(controller, 'showOk') + controller.localBank = 4; + + expect(window.localStorage.localBank).toBe('4'); + expect(controller.showOk).toHaveBeenCalledWith(); + }); + }); + + describe('localWarehouse() setter', () => { + it('should set window.localStorage.localWarehouse and call showOk', () => { + spyOn(controller, 'showOk') + controller.localWarehouse = 4; + + expect(window.localStorage.localWarehouse).toBe('4'); + expect(controller.showOk).toHaveBeenCalledWith(); + }); + }); + + describe('localCompany() setter', () => { + it('should set window.localStorage.localCompany and call showOk', () => { + spyOn(controller, 'showOk') + controller.localCompany = 4; + + expect(window.localStorage.localCompany).toBe('4'); + expect(controller.showOk).toHaveBeenCalledWith(); + }); + }); + + describe('warehouseFk() setter', () => { + it('should set warehouse and call setUserConfig', () => { + spyOn(controller, 'setUserConfig') + controller.warehouseFk = 4; + + expect(controller.warehouse).toBe(4); + expect(controller.setUserConfig).toHaveBeenCalledWith('warehouseFk'); + }); + }); + + describe('companyFk() setter', () => { + it('should set company and call setUserConfig', () => { + spyOn(controller, 'setUserConfig') + controller.companyFk = 4; + + expect(controller.company).toBe(4); + expect(controller.setUserConfig).toHaveBeenCalledWith('companyFk'); + }); + }); + + describe('getUserConfig()', () => { + it('should make a query, set company and not set warehouse if its not in the response', () => { + $httpBackend.when('GET', `/api/UserConfigs/getUserConfig`).respond({response: {companyFk: 2}}); + $httpBackend.expect('GET', `/api/UserConfigs/getUserConfig`); + controller.getUserConfig(); + $httpBackend.flush(); + + expect(controller.warehouse).toBeUndefined(); + expect(controller.company).toEqual(2); + }); + }); + + describe('setUserConfig()', () => { + it('should make a query with the property given and call showOk', () => { + spyOn(controller, 'showOk'); + controller.company = 1; + $httpBackend.when('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}).respond(200); + $httpBackend.expect('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}); + controller.setUserConfig('companyFk'); + $httpBackend.flush(); + + expect(controller.showOk).toHaveBeenCalledWith(); + }); + }); + }); +}); diff --git a/client/salix/src/components/user-configuration-popover/style.scss b/client/salix/src/components/user-configuration-popover/style.scss new file mode 100644 index 0000000000..d370cc2797 --- /dev/null +++ b/client/salix/src/components/user-configuration-popover/style.scss @@ -0,0 +1,12 @@ +@import 'colors'; + +vn-user-configuration-popover { + color: $main-font-color; + & > vn-vertical { + min-width: 250px; + } + .body { + padding: 16px 16px 6px 16px; + } + +} \ No newline at end of file diff --git a/services/loopback/common/methods/userConfig/getUserConfig.js b/services/loopback/common/methods/userConfig/getUserConfig.js new file mode 100644 index 0000000000..e3c9b59e13 --- /dev/null +++ b/services/loopback/common/methods/userConfig/getUserConfig.js @@ -0,0 +1,21 @@ +module.exports = function(Self) { + Self.remoteMethodCtx('getUserConfig', { + description: 'returns the information from UserConfig model for the active user', + accepts: [], + returns: { + arg: 'response', + type: 'object' + }, + http: { + path: `/getUserConfig`, + verb: 'get' + } + }); + + Self.getUserConfig = async(ctx) => { + let token = ctx.req.accessToken; + let currentUserId = token && token.userId; + + return await Self.app.models.UserConfig.findOne({userFk: currentUserId}); + } +}; diff --git a/services/loopback/common/methods/userConfig/setUserConfig.js b/services/loopback/common/methods/userConfig/setUserConfig.js new file mode 100644 index 0000000000..bd258b8325 --- /dev/null +++ b/services/loopback/common/methods/userConfig/setUserConfig.js @@ -0,0 +1,28 @@ +module.exports = function(Self) { + Self.remoteMethodCtx('setUserConfig', { + description: 'Change worker of tickets state', + accepts: [{ + arg: 'params', + type: 'object', + required: true, + description: 'warehouseFk, companyFk', + http: {source: 'body'} + }], + returns: { + arg: 'response', + type: 'object' + }, + http: { + path: `/setUserConfig`, + verb: 'post' + } + }); + + Self.setUserConfig = async(ctx, params) => { + let token = ctx.req.accessToken; + let currentUserId = token && token.userId; + params.userFk = currentUserId; + + return await Self.app.models.UserConfig.upsertWithWhere({userFk: currentUserId}, params); + } +}; diff --git a/services/loopback/common/models/user-config.js b/services/loopback/common/models/user-config.js new file mode 100644 index 0000000000..c6c26e00bd --- /dev/null +++ b/services/loopback/common/models/user-config.js @@ -0,0 +1,4 @@ +module.exports = Self => { + require('../methods/userConfig/setUserConfig')(Self); + require('../methods/userConfig/getUserConfig')(Self); +}; diff --git a/services/loopback/common/models/user-config.json b/services/loopback/common/models/user-config.json new file mode 100644 index 0000000000..4e4974bfb0 --- /dev/null +++ b/services/loopback/common/models/user-config.json @@ -0,0 +1,46 @@ +{ + "name": "UserConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "userConfig", + "database": "vn" + } + }, + "properties": { + "userFk": { + "id": true, + "type": "Number", + "required": true + }, + "warehouseFk": { + "type": "Number" + }, + "companyFk": { + "type": "Number" + }, + "created": { + "type": "Date" + }, + "updated": { + "type": "Date" + } + }, + "relations": { + "warehouse": { + "type": "belongsTo", + "model": "Warehouse", + "foreignKey": "warehouseFk" + }, + "company": { + "type": "belongsTo", + "model": "Company", + "foreignKey": "companyFk" + }, + "account": { + "type": "belongsTo", + "model": "Account", + "foreignKey": "userFk" + } + } +} diff --git a/services/loopback/server/model-config.json b/services/loopback/server/model-config.json index aed0a97f9f..1abca46435 100644 --- a/services/loopback/server/model-config.json +++ b/services/loopback/server/model-config.json @@ -42,6 +42,9 @@ "AgencyMode": { "dataSource": "vn" }, + "Bank": { + "dataSource": "vn" + }, "Client": { "dataSource": "vn" }, @@ -125,5 +128,8 @@ }, "DeliveryMethod": { "dataSource": "vn" + }, + "UserConfig": { + "dataSource": "vn" } }