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 39d49519b..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", @@ -25,6 +25,7 @@ "axios": "^1.4.0", "chromium": "^3.0.3", "croppie": "^2.6.5", + "moment": "^2.30.1", "pinia": "^2.1.3", "quasar": "^2.14.5", "validator": "^13.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83dfa0469..7bf640347 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ dependencies: croppie: specifier: ^2.6.5 version: 2.6.5 + moment: + specifier: ^2.30.1 + version: 2.30.1 pinia: specifier: ^2.1.3 version: 2.1.7(typescript@5.5.4)(vue@3.4.19) @@ -832,8 +835,8 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 10.0.0 - '@intlify/shared': 10.0.0 + '@intlify/message-compiler': 11.0.0-rc.1 + '@intlify/shared': 11.0.0-rc.1 jsonc-eslint-parser: 1.4.1 source-map: 0.6.1 vue-i18n: 9.9.1(vue@3.4.19) @@ -847,11 +850,11 @@ packages: '@intlify/message-compiler': 9.9.1 '@intlify/shared': 9.9.1 - /@intlify/message-compiler@10.0.0: - resolution: {integrity: sha512-OcaWc63NC/9p1cMdgoNKBj4d61BH8sUW1Hfs6YijTd9656ZR4rNqXAlRnBrfS5ABq0vjQjpa8VnyvH9hK49yBw==} + /@intlify/message-compiler@11.0.0-rc.1: + resolution: {integrity: sha512-TGw2uBfuTFTegZf/BHtUQBEKxl7Q/dVGLoqRIdw8lFsp9g/53sYn5iD+0HxIzdYjbWL6BTJMXCPUHp9PxDTRPw==} engines: {node: '>= 16'} dependencies: - '@intlify/shared': 10.0.0 + '@intlify/shared': 11.0.0-rc.1 source-map-js: 1.0.2 dev: true @@ -862,8 +865,8 @@ packages: '@intlify/shared': 9.9.1 source-map-js: 1.0.2 - /@intlify/shared@10.0.0: - resolution: {integrity: sha512-6ngLfI7DOTew2dcF9WMJx+NnMWghMBhIiHbGg+wRvngpzD5KZJZiJVuzMsUQE1a5YebEmtpTEfUrDp/NqVGdiw==} + /@intlify/shared@11.0.0-rc.1: + resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==} engines: {node: '>= 16'} dev: true @@ -887,7 +890,7 @@ packages: optional: true dependencies: '@intlify/bundle-utils': 4.0.0(vue-i18n@9.9.1) - '@intlify/shared': 10.0.0 + '@intlify/shared': 11.0.0-rc.1 '@rollup/pluginutils': 4.2.1 '@vue/compiler-sfc': 3.4.19 debug: 4.3.4(supports-color@8.1.1) @@ -4960,6 +4963,10 @@ packages: uuid: 8.3.2 dev: true + /moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + dev: false + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 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/boot/qformMixin.js b/src/boot/qformMixin.js index 187ca6dbc..97d80c670 100644 --- a/src/boot/qformMixin.js +++ b/src/boot/qformMixin.js @@ -31,7 +31,7 @@ export default { console.error(error); } form.addEventListener('keyup', function (evt) { - if (evt.key === 'Enter') { + if (evt.key === 'Enter' && !that.$attrs['prevent-submit']) { const input = evt.target; if (input.type == 'textarea' && evt.shiftKey) { evt.preventDefault(); 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/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 58b7667d2..b78c99b8a 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -113,8 +113,15 @@ const $props = defineProps({ }); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; -const { optionLabel, optionValue, optionFilter, optionFilterValue, options, modelValue } = - toRefs($props); +const { + optionLabel, + optionValue, + optionCaption, + optionFilter, + optionFilterValue, + options, + modelValue, +} = toRefs($props); const myOptions = ref([]); const myOptionsOriginal = ref([]); const vnSelectRef = ref(); @@ -321,6 +328,11 @@ function handleKeyDown(event) { } } } + +function getCaption(opt) { + if (optionCaption.value === false) return; + return opt[optionCaption.value] || opt[optionValue.value]; +}