From 9694a353432e4b6cd50b4375240d6776c92e1dbc Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 20 Apr 2023 19:46:57 +0200 Subject: [PATCH] refs #5517 Added: Tests, filter panel, model and props titles --- .../core/components/json-value/index.spec.js | 79 +++++++++++++++ front/core/components/json-value/style.scss | 3 +- front/core/styles/variables.scss | 1 - front/salix/components/layout/style.scss | 6 +- front/salix/components/log/index.html | 87 ++++++++++++++++- front/salix/components/log/index.js | 66 ++++++++++++- front/salix/components/log/index.spec.js | 97 +++++++++++++++++++ front/salix/components/log/style.scss | 4 + .../front/fixed-price-search-panel/style.scss | 2 +- modules/travel/front/search-panel/style.scss | 2 +- 10 files changed, 329 insertions(+), 18 deletions(-) create mode 100644 front/core/components/json-value/index.spec.js create mode 100644 front/salix/components/log/index.spec.js diff --git a/front/core/components/json-value/index.spec.js b/front/core/components/json-value/index.spec.js new file mode 100644 index 000000000..078080d27 --- /dev/null +++ b/front/core/components/json-value/index.spec.js @@ -0,0 +1,79 @@ +import './index'; + +describe('Salix Component vnLog', () => { + let controller; + let $scope; + let $element; + let el; + + beforeEach(ngModule('vnCore')); + + beforeEach(inject(($componentController, $rootScope) => { + $scope = $rootScope.$new(); + $element = angular.element(''); + controller = $componentController('vnJsonValue', {$element, $scope}); + el = controller.element; + })); + + describe('set value()', () => { + it('should display null symbol when value is null equivalent', () => { + controller.value = null; + + expect(el.textContent).toEqual('∅'); + expect(el.className).toContain('json-null'); + }); + + it('should display ballot when value is false', () => { + controller.value = false; + + expect(el.textContent).toEqual('✗'); + expect(el.className).toContain('json-false'); + }); + + it('should display check when value is true', () => { + controller.value = true; + + expect(el.textContent).toEqual('✓'); + expect(el.className).toContain('json-true'); + }); + + it('should display string when value is an string', () => { + controller.value = 'Foo'; + + expect(el.textContent).toEqual('Foo'); + expect(el.className).toContain('json-string'); + }); + + it('should display only date when value is date with time set to zero', () => { + const date = Date.vnNew(); + date.setHours(0, 0, 0, 0); + controller.value = date; + + expect(el.textContent).toEqual('01/01/2001'); + expect(el.className).toContain('json-object'); + }); + + it('should display full date without time when value is date with time', () => { + const date = Date.vnNew(); + date.setHours(15, 45); + controller.value = date; + + expect(el.textContent).toEqual('01/01/2001 15:45:00'); + expect(el.className).toContain('json-object'); + }); + + it('should display object when value is an object', () => { + controller.value = {foo: 'bar'}; + + expect(el.textContent).toEqual('[object Object]'); + expect(el.className).toContain('json-object'); + }); + + it('should display number when value is a number', () => { + controller.value = 2050; + + expect(el.textContent).toEqual('2050'); + expect(el.className).toContain('json-number'); + }); + }); +}); diff --git a/front/core/components/json-value/style.scss b/front/core/components/json-value/style.scss index 2d6c4023c..009a13d40 100644 --- a/front/core/components/json-value/style.scss +++ b/front/core/components/json-value/style.scss @@ -5,8 +5,7 @@ vn-json-value { color: #d172cc; } &.json-object { - /*color: #d1a572;*/ - color: #d172cc; + color: #d1a572; } &.json-number { color: #85d0ff; diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index c280838ca..bcc9fab66 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -2,7 +2,6 @@ $font-size: 11pt; $menu-width: 256px; -$right-menu-width: 318px; $topbar-height: 56px; $mobile-width: 800px; $float-spacing: 20px; diff --git a/front/salix/components/layout/style.scss b/front/salix/components/layout/style.scss index 6697bb1b0..612366228 100644 --- a/front/salix/components/layout/style.scss +++ b/front/salix/components/layout/style.scss @@ -88,13 +88,13 @@ vn-layout { } &.right-menu { & > vn-topbar > .end { - width: 80px + $right-menu-width; + width: 80px + $menu-width; } & > .main-view { - padding-right: $right-menu-width; + padding-right: $menu-width; } [fixed-bottom-right] { - right: $right-menu-width; + right: $menu-width; } } & > .main-view { diff --git a/front/salix/components/log/index.html b/front/salix/components/log/index.html index 14a3fbe61..3d3a3f8dc 100644 --- a/front/salix/components/log/index.html +++ b/front/salix/components/log/index.html @@ -6,6 +6,7 @@ where="{changedModel: $ctrl.changedModel, changedModelId: $ctrl.changedModelId}" data="$ctrl.logs" + order="creationDate DESC, id DESC" limit="20" auto-load="true"> @@ -38,13 +39,16 @@ - - {{::log.changedModel}} + + {{::log.changedModelI18n}} {{::log.changedModelValue}} - + #{{::log.changedModelId}} @@ -73,13 +77,19 @@ class="attributes"> - {{::prop.name}}: + + {{::prop.nameI18n}}: + ,
- {{::prop.name}}: + + {{::prop.nameI18n}}: + @@ -105,5 +115,72 @@ + +
+ + + + + + +
{{nickname}}
+
{{name}}
+
+
+
+ + + + + + + + +
+ + + + + + + + + +
+
diff --git a/front/salix/components/log/index.js b/front/salix/components/log/index.js index 8c75664c8..7c01b8ac3 100644 --- a/front/salix/components/log/index.js +++ b/front/salix/components/log/index.js @@ -19,6 +19,11 @@ export default class Controller extends Section { delete: 'alert', select: 'notice' }; + + $.filter = {}; + $.$watch('filter.actions', () => this.applyFilter(), true); + $.$watch('filter.from', () => $.filter.to = $.filter.from); + this.filter = { include: [{ relation: 'user', @@ -33,6 +38,7 @@ export default class Controller extends Section { }, }], }; + this.dateFilter = this.$filter('date'); this.lang = this.$translate.use(); this.today = Date.vnNew(); @@ -52,7 +58,7 @@ export default class Controller extends Section { const oldValues = log.oldInstance || empty; const newValues = log.newInstance || empty; const locale = validations[log.changedModel]?.locale || empty; - log.changedModel = locale.name ? locale.name : log.changedModel + log.changedModelI18n = locale.name || log.changedModel; let props = Object.keys(oldValues).concat(Object.keys(newValues)); props = [...new Set(props)]; @@ -60,9 +66,10 @@ export default class Controller extends Section { log.props = []; for (const prop of props) { log.props.push({ - name: locale.columns?.[prop] || prop, - old: this.castValue(oldValues[prop]), - new: this.castValue(newValues[prop]) + name: prop, + nameI18n: locale.columns?.[prop] || prop, + old: this.castJsonValue(oldValues[prop]), + new: this.castJsonValue(newValues[prop]) }); } } @@ -72,7 +79,7 @@ export default class Controller extends Section { return !(this.changedModel && this.changedModelId); } - castValue(value) { + castJsonValue(value) { return typeof value === 'string' && validDate.test(value) ? new Date(value) : value; @@ -88,6 +95,7 @@ export default class Controller extends Section { } relativeDate(dateVal) { + if (dateVal == null) return ''; const date = new Date(dateVal); const dateZeroTime = new Date(dateVal); dateZeroTime.setHours(0, 0, 0, 0); @@ -112,6 +120,54 @@ export default class Controller extends Section { if (!workerId) return; this.$.workerDescriptor.show(event.target, workerId); } + + applyFilter() { + const filter = this.$.filter; + + function getParam(prop, value) { + if (value == null || value == '') return null; + switch (prop) { + case 'actions': + const inq = []; + for (const action in value) { + if (value[action]) + inq.push(action); + } + return inq.length ? {action: {inq}} : null; + case 'from': + return {creationDate: {gte: value}}; + case 'to': + const to = new Date(value); + to.setHours(23, 59, 59, 999); + return {creationDate: {lte: to}}; + default: + return {[prop]: value}; + } + } + + const and = []; + for (const prop in filter) { + const param = getParam(prop, filter[prop]); + if (param) and.push(param); + } + this.$.model.applyFilter(and.length ? {where: {and}} : null); + } + + removeFilter() { + this.$.filter = {}; + this.applyFilter(); + } + + searchUser(search) { + if (/^[0-9]+$/.test(search)) { + return {id: search}; + } else { + return {or: [ + {name: search}, + {nickname: {like: `%${search}%`}} + ]} + } + } } ngModule.vnComponent('vnLog', { diff --git a/front/salix/components/log/index.spec.js b/front/salix/components/log/index.spec.js new file mode 100644 index 000000000..d01a08967 --- /dev/null +++ b/front/salix/components/log/index.spec.js @@ -0,0 +1,97 @@ +import './index'; + +describe('Salix Component vnLog', () => { + let controller; + let $scope; + let $element; + + beforeEach(ngModule('salix')); + + beforeEach(inject(($componentController, $rootScope) => { + $scope = $rootScope.$new(); + $element = angular.element(''); + controller = $componentController('vnLog', {$element, $scope}); + })); + + describe('relativeDate()', () => { + let date; + + beforeEach(() => { + date = Date.vnNew(); + }); + + it('should return empty string when date is null', () => { + const ret = controller.relativeDate(null); + + expect(ret).toEqual(''); + }); + + it('should return empty string when date is undefined', () => { + const ret = controller.relativeDate(undefined); + + expect(ret).toEqual(''); + }); + + it('should return today and time when date is today', () => { + const ret = controller.relativeDate(date); + + expect(ret).toEqual('today 12:00'); + }); + + it('should return yesterday and time when date is yesterday', () => { + date.setDate(date.getDate() - 1); + const ret = controller.relativeDate(date); + + expect(ret).toEqual('yesterday 12:00'); + }); + + it('should return abreviated weekday name and time when date is on past week', () => { + date.setDate(date.getDate() - 3); + const ret = controller.relativeDate(date); + + expect(ret).toEqual('Fri 12:00'); + }); + + it('should return abreviated month name, day number and time when date is on this year', () => { + date.setDate(date.getDate() + 20); + const ret = controller.relativeDate(date); + + expect(ret).toEqual('21 Jan 12:00'); + }); + + it('should return abreviated month name, day number, year and time when date is on different year', () => { + date.setDate(date.getDate() - 20); + const ret = controller.relativeDate(date); + + expect(ret).toEqual('12/12/2000 12:00'); + }); + + it('should convert to date and return string when date is not a Date class instance', () => { + const ret = controller.relativeDate(date.toJSON()); + + expect(ret).toEqual('today 12:00'); + }); + }); + + describe('castJsonValue()', () => { + it('should return date when string has valid JSON date format', () => { + const now = Date.vnNew(); + + const ret = controller.castJsonValue(now.toJSON()); + + expect(ret).toBeInstanceOf(Date); + }); + + it('should return same value when is string with invalid JSON date format', () => { + const ret = controller.castJsonValue('Foo'); + + expect(ret).toEqual('Foo'); + }); + + it('should return same value when is not an string', () => { + const ret = controller.castJsonValue(1001); + + expect(ret).toEqual(1001); + }); + }); +}); diff --git a/front/salix/components/log/style.scss b/front/salix/components/log/style.scss index 1573218f4..ea228e1fb 100644 --- a/front/salix/components/log/style.scss +++ b/front/salix/components/log/style.scss @@ -64,6 +64,9 @@ vn-log { } } } + .model-name { + text-transform: capitalize; + } .model-value { font-style: italic; color: #c7bd2b; @@ -130,4 +133,5 @@ vn-log { } } } + .filter {} } diff --git a/modules/item/front/fixed-price-search-panel/style.scss b/modules/item/front/fixed-price-search-panel/style.scss index a63f84f3b..e386033dd 100644 --- a/modules/item/front/fixed-price-search-panel/style.scss +++ b/modules/item/front/fixed-price-search-panel/style.scss @@ -2,7 +2,7 @@ vn-fixed-price-search-panel vn-side-menu { .menu { - min-width: $right-menu-width; + min-width: $menu-width; } & > div { .input { diff --git a/modules/travel/front/search-panel/style.scss b/modules/travel/front/search-panel/style.scss index 94fe7b239..0da52408a 100644 --- a/modules/travel/front/search-panel/style.scss +++ b/modules/travel/front/search-panel/style.scss @@ -2,7 +2,7 @@ vn-travel-search-panel vn-side-menu { .menu { - min-width: $right-menu-width; + min-width: $menu-width; } & > div { .input {