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"
}
}