diff --git a/CHANGELOG.md b/CHANGELOG.md index 6908d764a..a7797f810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,82 @@ +# Version 25.00 - 2025-01-14 + +### Added 🆕 + +- chore: refs #7056 move test by:jorgep +- feat: refs #7050 7050 add object check by:Jtubau +- feat: refs #7050 7050 add test to isEmpty() by:Jtubau +- feat: refs #7056 add tests in FormModel by:jorgep +- feat: refs #7056 update route meta information and add FormModel tests by:jorgep +- feat: refs #7074 tests for fns setData(), parseDms() and showFormDialog() (7074-makeFrontTestToVnDmsList) by:Jtubau +- feat: refs #7079 created VnLocation front test by:provira +- feat: refs #7189 add Accept-Language header to axios requests by:jorgep +- feat: refs #7924 add custom inspection checkbox and localization support by:jgallego +- feat: refs #7924 update custom inspection label for clarity in English and Spanish locales by:jgallego +- feat: refs #8004 enhance FetchedTags component with column support and styling updates by:pablone +- feat: refs #8004 hide rightFilter by:pablone +- feat: refs #8246 added new field in list by:Jon +- feat: refs #8266 added descriptor to item name by:jtubau +- feat: refs #8293 add zone filter by:Jtubau +- feat: refs #8293 include zone data in each record by:Jtubau +- fix: refs #8004 more list style issues by:pablone +- fix: refs #8004 some style issues on all list by:pablone +- style: refs #8004 update layout and styling in FetchedTags and ItemList components by:pablone +- style: update CustomerBalance.vue to set label color by:jgallego + +### Changed 📦 + +- perf: order by:alexm +- perf: redirect transition list to card by:alexm +- perf: refs #8201 onDataSaved fetch by:Jon +- perf: revert processData by:alexm +- perf: simplify if by:alexm +- perf: simplify if (perf_redirectTransition) by:alexm +- refactor: item fixedPrice by:Jon +- refactor: refs #7050 refactorize by:jtubau +- refactor: refs #7050 removed blank spaces by:jtubau +- refactor: refs #7052 move EditTableCellValueForm tests to a new location and enhance test coverage by:jgallego +- refactor: refs #7052 remove unnecessary console logs from EditTableCellValueForm tests by:jgallego +- refactor: refs #7074 move dms constant to global scope by:Jtubau +- refactor: refs #7079 removed useless code by:provira +- refactor: refs #7924 simplify custom inspection icon rendering in ExtraCommunity.vue by:jgallego +- refactor: refs #8004 remove console log from CardSummary component on mount by:pablone +- refactor: refs #8004 remove consoleLogs by:pablone +- refactor: refs #8004 remove unused stateStore import in InvoiceInList.vue by:pablone +- refactor: refs #8004 remove unused travelFilterRef and chip definition in TravelList.vue by:pablone +- refactor: refs #8004 replace VnSelect with VnSelectWorker in CustomerList component by:pablone +- refactor: refs #8201 added onMounted to stablish the value to show icons by:Jon +- refactor: refs #8201 deleted condition by:Jon +- refactor: refs #8201 deleted log by:Jon +- refactor: refs #8201 deleted logs by:Jon +- refactor: refs #8266 8266 change expedition item name by:Jtubau +- refactor: refs #8266 change expedition label by:Jtubau +- refactor: refs #8293 remove redundant attributes by:Jtubau +- refactor: refs #8320 changed folder names from "specs" to "**tests**" by:provira +- refactor: refs #8320 moved front tests to their respective sections by:provira +- refactor: refs #8813 removed unused class property by:provira + +### Fixed 🛠️ + +- fix: discount class by:PAU ROVIRA ROSALENY +- fix: duplicate transalation after test to dev by:alexm +- fix: fix translations by:carlossa +- fix: redirect to sales when confirming lines by:Jon +- fix: refs #7050 delete import added by mistake by:Jtubau +- fix: refs #7133 handleSalesModelValue function to handle empty input by:jorgep +- fix: refs #7189 update user language on sessionStorage by:jorgep +- fix: refs #7935 remove unused 'companyFk' column from InvoiceInList component by:jorgep +- fix: refs #8004 more list style issues by:pablone +- fix: refs #8004 some style issues on all list by:pablone +- fix: refs #8004 update label for daysOnward in TravelFilter component and add translations by:pablone +- fix: refs #8004 vnTable card with and add permanent labels by:pablone +- fix: refs #8201 added onDataSaved emi to refetch when cahnges are made by:Jon +- fix: refs #8201 use arrayData to fix the error by:Jon +- fix: refs #8314 space between label and value by:jtubau +- fix: refs #8813 fixed ClaimLines format by:provira +- fix: update button sizes in ExtraCommunity.vue for better visibility by:jgallego +- perf: revert processData by:alexm +- refactor: item fixedPrice by:Jon + # Version 24.52 - 2024-01-07 ### Added 🆕 diff --git a/package.json b/package.json index cdd61435b..6259f4acd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "24.52.0", + "version": "25.02.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", diff --git a/test/vitest/__tests__/boot/axios.spec.js b/src/boot/__tests__/axios.spec.js similarity index 97% rename from test/vitest/__tests__/boot/axios.spec.js rename to src/boot/__tests__/axios.spec.js index 19d396ec5..b3b6f98c6 100644 --- a/test/vitest/__tests__/boot/axios.spec.js +++ b/src/boot/__tests__/axios.spec.js @@ -1,4 +1,3 @@ -import { Notify } from 'quasar'; import { onRequest, onResponseError } from 'src/boot/axios'; import { describe, expect, it, vi } from 'vitest'; @@ -27,6 +26,7 @@ describe('Axios boot', () => { expect(resultConfig).toEqual( expect.objectContaining({ headers: { + 'Accept-Language': 'en-US', Authorization: 'DEFAULT_TOKEN', }, }) diff --git a/src/boot/axios.js b/src/boot/axios.js index aee38e887..3f9fadee5 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -3,12 +3,12 @@ import { useSession } from 'src/composables/useSession'; import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; import { useStateQueryStore } from 'src/stores/useStateQueryStore'; +import { i18n } from 'src/boot/i18n'; const session = useSession(); const { notify } = useNotify(); const stateQuery = useStateQueryStore(); const baseUrl = '/api/'; - axios.defaults.baseURL = baseUrl; const axiosNoError = axios.create({ baseURL: baseUrl }); @@ -16,6 +16,7 @@ const onRequest = (config) => { const token = session.getToken(); if (token.length && !config.headers.Authorization) { config.headers.Authorization = token; + config.headers['Accept-Language'] = i18n.global.locale.value; } stateQuery.add(config); return config; diff --git a/src/boot/i18n.js b/src/boot/i18n.js index b23b6d5fd..85d0772a3 100644 --- a/src/boot/i18n.js +++ b/src/boot/i18n.js @@ -1,9 +1,11 @@ import { boot } from 'quasar/wrappers'; import { createI18n } from 'vue-i18n'; import messages from 'src/i18n'; +import { useState } from 'src/composables/useState'; +const user = useState().getUser(); const i18n = createI18n({ - locale: navigator.language || navigator.userLanguage, + locale: user.value.lang || navigator.language || navigator.userLanguage, fallbackLocale: 'en', globalInjection: true, messages, diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue index 7fdb54bc4..940b72ff0 100644 --- a/src/components/CrudModel.vue +++ b/src/components/CrudModel.vue @@ -127,7 +127,7 @@ function resetData(data) { originalData.value = JSON.parse(JSON.stringify(data)); formData.value = JSON.parse(JSON.stringify(data)); - if (watchChanges.value) watchChanges.value(); //destoy watcher + if (watchChanges.value) watchChanges.value(); //destroy watcher watchChanges.value = watch(formData, () => (hasChanges.value = true), { deep: true }); } @@ -270,10 +270,8 @@ function getChanges() { function isEmpty(obj) { if (obj == null) return true; - if (obj === undefined) return true; - if (Object.keys(obj).length === 0) return true; - - if (obj.length > 0) return false; + if (Array.isArray(obj)) return !obj.length; + return !Object.keys(obj).length; } async function reload(params) { diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index c569f2553..ea1ea53f2 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -1,7 +1,7 @@ - - - -en: - Go to Salix: Go to Salix -es: - Go to Salix: Ir a Salix - diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue index 810f63044..a0ef73a1f 100644 --- a/src/components/UserPanel.vue +++ b/src/components/UserPanel.vue @@ -87,10 +87,10 @@ async function saveDarkMode(value) { async function saveLanguage(value) { const query = `/VnUsers/${user.value.id}`; try { - await axios.patch(query, { - lang: value, - }); + await axios.patch(query, { lang: value }); + user.value.lang = value; + useState().setUser(user.value); onDataSaved(); } catch (error) { onDataError(); diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 3839ff0c2..07992f616 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -150,6 +150,7 @@ const tableModes = [ disable: $props.disableOption?.card, }, ]; + onBeforeMount(() => { const urlParams = route.query[$props.searchUrl]; hasParams.value = urlParams && Object.keys(urlParams).length !== 0; @@ -383,7 +384,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) { :class="col.headerClass" >
@@ -425,7 +426,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) { - + obj.country?.name, ]; -const formatLocation = (obj, properties) => { +const formatLocation = (obj, properties = locationProperties) => { const parts = properties.map((prop) => { if (typeof prop === 'string') { return obj[prop]; diff --git a/test/vitest/__tests__/components/common/VnChangePassword.spec.js b/src/components/common/__tests__/VnChangePassword.spec.js similarity index 100% rename from test/vitest/__tests__/components/common/VnChangePassword.spec.js rename to src/components/common/__tests__/VnChangePassword.spec.js diff --git a/test/vitest/__tests__/components/common/VnDiscount.spec.js b/src/components/common/__tests__/VnDiscount.spec.js similarity index 100% rename from test/vitest/__tests__/components/common/VnDiscount.spec.js rename to src/components/common/__tests__/VnDiscount.spec.js diff --git a/src/components/common/__tests__/VnDmsList.spec.js b/src/components/common/__tests__/VnDmsList.spec.js new file mode 100644 index 000000000..9649943a2 --- /dev/null +++ b/src/components/common/__tests__/VnDmsList.spec.js @@ -0,0 +1,87 @@ +import { createWrapper, axios } from 'app/test/vitest/helper'; +import VnDmsList from 'src/components/common/VnDmsList.vue'; +import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; + +describe('VnDmsList', () => { + let vm; + const dms = { + userFk: 1, + name: 'DMS 1' + }; + + beforeAll(() => { + vi.spyOn(axios, 'get').mockResolvedValue({ data: [] }); + vm = createWrapper(VnDmsList, { + props: { + model: 'WorkerDms/1110/filter', + defaultDmsCode: 'hhrrData', + filter: 'wd.workerFk', + updateModel: 'Workers', + deleteModel: 'WorkerDms', + downloadModel: 'WorkerDms' + } + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('setData()', () => { + const data = [ + { + userFk: 1, + name: 'Jessica', + lastName: 'Jones', + file: '4.jpg', + created: '2021-07-28 21:00:00' + }, + { + userFk: 2, + name: 'Bruce', + lastName: 'Banner', + created: '2022-07-28 21:00:00', + dms: { + userFk: 2, + name: 'Bruce', + lastName: 'BannerDMS', + created: '2022-07-28 21:00:00', + file: '4.jpg', + } + }, + { + userFk: 3, + name: 'Natasha', + lastName: 'Romanoff', + file: '4.jpg', + created: '2021-10-28 21:00:00' + } + ] + + it('Should replace objects that contain the "dms" property with the value of the same and sort by creation date', () => { + vm.setData(data); + expect([vm.rows][0][0].lastName).toEqual('BannerDMS'); + expect([vm.rows][0][1].lastName).toEqual('Romanoff'); + + }); + }); + + describe('parseDms()', () => { + const resultDms = { ...dms, userId:1}; + + it('Should add properties that end with "Fk" by changing the suffix to "Id"', () => { + const parsedDms = vm.parseDms(dms); + expect(parsedDms).toEqual(resultDms); + }); + }); + + describe('showFormDialog()', () => { + const resultDms = { ...dms, userId:1}; + + it('should call fn parseDms() and set show true if dms is defined', () => { + vm.showFormDialog(dms); + expect(vm.formDialog.show).toEqual(true); + expect(vm.formDialog.dms).toEqual(resultDms); + }); + }); +}); \ No newline at end of file diff --git a/src/components/common/__tests__/VnLocation.spec.js b/src/components/common/__tests__/VnLocation.spec.js new file mode 100644 index 000000000..65fdae960 --- /dev/null +++ b/src/components/common/__tests__/VnLocation.spec.js @@ -0,0 +1,91 @@ +import { createWrapper } from 'app/test/vitest/helper'; +import VnLocation from 'components/common/VnLocation.vue'; +import { vi, afterEach, expect, it, beforeEach, describe } from 'vitest'; + +function buildComponent(data) { + return createWrapper(VnLocation, { + global: { + props: { + location: data + } + }, + }).vm; +} + +afterEach(() => { + vi.clearAllMocks(); +}); + +describe('formatLocation', () => { + let locationBase; + + beforeEach(() => { + locationBase = { + postcode: '46680', + city: 'Algemesi', + province: { name: 'Valencia' }, + country: { name: 'Spain' } + }; + }); + + it('should return the postcode, city, province and country', () => { + const location = { ...locationBase }; + const vm = buildComponent(location); + expect(vm.formatLocation(location)).toEqual('46680, Algemesi(Valencia), Spain'); + }); + + it('should return the postcode and country', () => { + const location = { ...locationBase, city: undefined }; + const vm = buildComponent(location); + expect(vm.formatLocation(location)).toEqual('46680, Spain'); + }); + + it('should return the city, province and country', () => { + const location = { ...locationBase, postcode: undefined }; + const vm = buildComponent(location); + expect(vm.formatLocation(location)).toEqual('Algemesi(Valencia), Spain'); + }); + + it('should return the country', () => { + const location = { ...locationBase, postcode: undefined, city: undefined, province: undefined }; + const vm = buildComponent(location); + expect(vm.formatLocation(location)).toEqual('Spain'); + }); +}); + +describe('showLabel', () => { + let locationBase; + + beforeEach(() => { + locationBase = { + code: '46680', + town: 'Algemesi', + province: 'Valencia', + country: 'Spain' + }; + }); + + it('should show the label with postcode, city, province and country', () => { + const location = { ...locationBase }; + const vm = buildComponent(location); + expect(vm.showLabel(location)).toEqual('46680, Algemesi(Valencia), Spain'); + }); + + it('should show the label with postcode and country', () => { + const location = { ...locationBase, town: undefined }; + const vm = buildComponent(location); + expect(vm.showLabel(location)).toEqual('46680, Spain'); + }); + + it('should show the label with city, province and country', () => { + const location = { ...locationBase, code: undefined }; + const vm = buildComponent(location); + expect(vm.showLabel(location)).toEqual('Algemesi(Valencia), Spain'); + }); + + it('should show the label with country', () => { + const location = { ...locationBase, code: undefined, town: undefined, province: undefined }; + const vm = buildComponent(location); + expect(vm.showLabel(location)).toEqual('Spain'); + }); +}); \ No newline at end of file diff --git a/test/vitest/__tests__/components/common/VnLog.spec.js b/src/components/common/__tests__/VnLog.spec.js similarity index 100% rename from test/vitest/__tests__/components/common/VnLog.spec.js rename to src/components/common/__tests__/VnLog.spec.js diff --git a/test/vitest/__tests__/components/common/VnSmsDialog.spec.js b/src/components/common/__tests__/VnSmsDialog.spec.js similarity index 100% rename from test/vitest/__tests__/components/common/VnSmsDialog.spec.js rename to src/components/common/__tests__/VnSmsDialog.spec.js diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue index cf8859a35..8395dfd73 100644 --- a/src/components/ui/CardSummary.vue +++ b/src/components/ui/CardSummary.vue @@ -1,10 +1,10 @@ - - diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index c5d5df394..a9e9bc0fc 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -30,7 +30,7 @@ onBeforeMount(async () => { .data; if (!channel) channel = defaultChannel; - phone.value = await parsePhone(props.phoneNumber, props.country.toLowerCase()); + phone.value = await parsePhone(props.phoneNumber, props.country?.toLowerCase()); config[ type ].url = `${url}?customerIdentity=%2B${phone.value}&channelId=${channel}`; diff --git a/src/components/ui/VnLv.vue b/src/components/ui/VnLv.vue index ff65f759b..a198c9c05 100644 --- a/src/components/ui/VnLv.vue +++ b/src/components/ui/VnLv.vue @@ -39,7 +39,7 @@ const val = computed(() => $props.value);