From 8817fd7c5582934a91b2ec9d852c46e0517122a5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 30 Oct 2024 13:55:51 +0100 Subject: [PATCH 01/15] feat: add support service wip --- src/boot/quasar.js | 58 ++++++++++++++++++++++++++++++-- src/components/NavBar.vue | 7 ++-- src/composables/useNotify.js | 3 +- src/composables/useVnConfirm.js | 31 ++++++++++------- src/i18n/locale/en.yml | 2 ++ src/i18n/locale/es.yml | 3 ++ src/stores/useStateQueryStore.js | 5 ++- 7 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 01fe68d8b..a1991d9a4 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -1,10 +1,17 @@ +import { ref } from 'vue'; +import axios from 'axios'; import { boot } from 'quasar/wrappers'; import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; +import { i18n } from './i18n'; import useNotify from 'src/composables/useNotify.js'; -import { CanceledError } from 'axios'; +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; +import VnInput from 'src/components/common/VnInput.vue'; +import { useVnConfirm } from 'src/composables/useVnConfirm'; const { notify } = useNotify(); +const stateQuery = useStateQueryStore(); +const { openConfirmationModal } = useVnConfirm(); export default boot(({ app }) => { app.mixin(qFormMixin); @@ -40,12 +47,57 @@ export default boot(({ app }) => { } console.error(error); - if (error instanceof CanceledError) { + if (error instanceof axios.CanceledError) { const env = process.env.NODE_ENV; if (env && env !== 'development') return; message = 'Duplicate request'; } + // Convey to Alex or Juan... + const additionalData = { + frontPath: stateQuery.route.name, + backError: { + config: error.config, + data: error, + }, + httpRequest: error.request.response, + }; - notify(message ?? 'globals.error', 'negative', 'error'); + const opts = { + actions: [ + { + icon: 'support_agent', + color: 'primary', + dense: true, + flat: false, + round: true, + noDismiss: true, + handler: async () => { + const reason = ref(); + openConfirmationModal( + i18n.global.t('globals.sendCau'), + false, + async () => { + await axios.post('OsTickets/send-to-support', { + reason: reason.value, + additionalData, + }); + }, + null, + { + component: VnInput, + props: { + modelValue: reason, + 'onUpdate:modelValue': (val) => (reason.value = val), + label: i18n.global.t('globals.ExplainReason'), + class: 'full-width', + required: true, + }, + } + ); + }, + }, + ], + }; + notify(message ?? 'globals.error', 'negative', 'error', opts); }; }); diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index 9b0393489..6f8377d96 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -1,6 +1,7 @@ diff --git a/src/composables/useNotify.js b/src/composables/useNotify.js index 2f0e1c257..309156d2a 100644 --- a/src/composables/useNotify.js +++ b/src/composables/useNotify.js @@ -2,7 +2,7 @@ import { Notify } from 'quasar'; import { i18n } from 'src/boot/i18n'; export default function useNotify() { - const notify = (message, type, icon) => { + const notify = (message, type, icon, opts = {}) => { const defaultIcons = { warning: 'warning', negative: 'error', @@ -13,6 +13,7 @@ export default function useNotify() { message: i18n.global.t(message), type: type, icon: icon ? icon : defaultIcons[type], + ...opts, }); }; diff --git a/src/composables/useVnConfirm.js b/src/composables/useVnConfirm.js index 76c3f4f28..4438ad11d 100644 --- a/src/composables/useVnConfirm.js +++ b/src/composables/useVnConfirm.js @@ -1,22 +1,29 @@ +import { h } from 'vue'; +import { Dialog } from 'quasar'; import VnConfirm from 'components/ui/VnConfirm.vue'; -import { useQuasar } from 'quasar'; export function useVnConfirm() { - const quasar = useQuasar(); - - const openConfirmationModal = (title, message, promise, successFn) => { - quasar - .dialog({ - component: VnConfirm, - componentProps: { + const openConfirmationModal = ( + title, + message, + promise, + successFn, + customHTML = {} + ) => { + const { component, props } = customHTML; + Dialog.create({ + component: h( + VnConfirm, + { title: title, message: message, promise: promise, }, - }) - .onOk(async () => { - if (successFn) successFn(); - }); + { customHTML: () => h(component, props) } + ), + }).onOk(async () => { + if (successFn) successFn(); + }); }; return { openConfirmationModal }; diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 10186d92a..7feaa990a 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -314,6 +314,8 @@ globals: deleteConfirmTitle: Delete selected elements changeState: Change state raid: 'Raid {daysInForward} days' + sendCau: Send cau + ExplainReason: Explain why this error should not appear errors: statusUnauthorized: Access denied statusInternalServerError: An internal server error has ocurred diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 66b5efd52..be1e25ca8 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -318,6 +318,9 @@ globals: deleteConfirmTitle: Eliminar los elementos seleccionados changeState: Cambiar estado raid: 'Redada {daysInForward} días' + sendCau: Enviar cau + ExplainReason: Explique el motivo por el que no deberia aparecer este fallo + By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor diff --git a/src/stores/useStateQueryStore.js b/src/stores/useStateQueryStore.js index d25dbb921..9893d3264 100644 --- a/src/stores/useStateQueryStore.js +++ b/src/stores/useStateQueryStore.js @@ -3,7 +3,9 @@ import { defineStore } from 'pinia'; export const useStateQueryStore = defineStore('stateQueryStore', () => { const queries = ref(new Set()); - + const route = computed(() => + Array.from(queries.value).find((query) => query?.fullPath) + ); function add(query) { queries.value.add(query); return query; @@ -27,5 +29,6 @@ export const useStateQueryStore = defineStore('stateQueryStore', () => { remove, queries, reset, + route, }; }); From f6d200405ce236e88dcbc63152247b3d3a0766a2 Mon Sep 17 00:00:00 2001 From: jorgep Date: Tue, 5 Nov 2024 09:33:16 +0100 Subject: [PATCH 02/15] feat: message to grant access --- src/boot/quasar.js | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index a1991d9a4..b3fb62ee7 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -62,6 +62,8 @@ export default boot(({ app }) => { httpRequest: error.request.response, }; + const isErrorPrivaleges = response?.code == 'ACCESS_DENIED'; + const opts = { actions: [ { @@ -70,30 +72,36 @@ export default boot(({ app }) => { dense: true, flat: false, round: true, - noDismiss: true, + noDismiss: isErrorPrivaleges, handler: async () => { - const reason = ref(); - openConfirmationModal( - i18n.global.t('globals.sendCau'), - false, - async () => { - await axios.post('OsTickets/send-to-support', { - reason: reason.value, - additionalData, - }); - }, - null, - { - component: VnInput, - props: { - modelValue: reason, - 'onUpdate:modelValue': (val) => (reason.value = val), - label: i18n.global.t('globals.ExplainReason'), - class: 'full-width', - required: true, + if (isErrorPrivaleges) { + // Create message and send to support + console.log('QUIERO ACCEDER!!!'); + } else { + const reason = ref(); + openConfirmationModal( + i18n.global.t('globals.sendCau'), + false, + async () => { + await axios.post('OsTickets/send-to-support', { + reason: reason.value, + additionalData, + }); }, - } - ); + null, + { + component: VnInput, + props: { + modelValue: reason, + 'onUpdate:modelValue': (val) => + (reason.value = val), + label: i18n.global.t('globals.ExplainReason'), + class: 'full-width', + required: true, + }, + } + ); + } }, }, ], From 0c476725ae5672cf3bef59d32255797e6e1d6116 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 13 Nov 2024 13:11:02 +0100 Subject: [PATCH 03/15] refactor: use locale keys --- src/boot/quasar.js | 56 +++++++++++++++++++----------------------- src/i18n/locale/en.yml | 7 ++++-- src/i18n/locale/es.yml | 8 +++--- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index b3fb62ee7..5e10bacf1 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -61,9 +61,6 @@ export default boot(({ app }) => { }, httpRequest: error.request.response, }; - - const isErrorPrivaleges = response?.code == 'ACCESS_DENIED'; - const opts = { actions: [ { @@ -72,36 +69,33 @@ export default boot(({ app }) => { dense: true, flat: false, round: true, - noDismiss: isErrorPrivaleges, handler: async () => { - if (isErrorPrivaleges) { - // Create message and send to support - console.log('QUIERO ACCEDER!!!'); - } else { - const reason = ref(); - openConfirmationModal( - i18n.global.t('globals.sendCau'), - false, - async () => { - await axios.post('OsTickets/send-to-support', { - reason: reason.value, - additionalData, - }); + const reason = ref( + response.data.error.code == 'ACCESS_DENIED' + ? i18n.global.t('cau.askPrivileges') + : '' + ); + openConfirmationModal( + i18n.global.t('cau.title'), + i18n.global.t('cau.subtitle'), + async () => { + await axios.post('OsTickets/send-to-support', { + reason: reason.value, + additionalData, + }); + }, + null, + { + component: VnInput, + props: { + modelValue: reason, + 'onUpdate:modelValue': (val) => (reason.value = val), + label: i18n.global.t('cau.inputLabel'), + class: 'full-width', + required: true, }, - null, - { - component: VnInput, - props: { - modelValue: reason, - 'onUpdate:modelValue': (val) => - (reason.value = val), - label: i18n.global.t('globals.ExplainReason'), - class: 'full-width', - required: true, - }, - } - ); - } + } + ); }, }, ], diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index e0d35d7e7..2eda4ddce 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -317,8 +317,6 @@ globals: deleteConfirmTitle: Delete selected elements changeState: Change state raid: 'Raid {daysInForward} days' - sendCau: Send cau - ExplainReason: Explain why this error should not appear errors: statusUnauthorized: Access denied statusInternalServerError: An internal server error has ocurred @@ -356,6 +354,11 @@ resetPassword: repeatPassword: Repeat password passwordNotMatch: Passwords don't match passwordChanged: Password changed +cau: + title: Send cau + subtitle: By sending this ticket, all the data related to the error, the section, the user, etc., are already sent. + inputLabel: Explain why this error should not appear + askPrivileges: Ask for privileges entry: list: newEntry: New entry diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index ce8a8bf01..af475d27d 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -321,9 +321,6 @@ globals: deleteConfirmTitle: Eliminar los elementos seleccionados changeState: Cambiar estado raid: 'Redada {daysInForward} días' - sendCau: Enviar cau - ExplainReason: Explique el motivo por el que no deberia aparecer este fallo - By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor @@ -359,6 +356,11 @@ resetPassword: repeatPassword: Repetir contraseña passwordNotMatch: Las contraseñas no coinciden passwordChanged: Contraseña cambiada +cau: + title: Enviar cau + subtitle: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc + inputLabel: Explique el motivo por el que no deberia aparecer este fallo + askPrivileges: Solicitar permisos entry: list: newEntry: Nueva entrada From 34df9cf2543fe0eb2783966897bd2dfd77416020 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 13 Nov 2024 15:33:41 +0100 Subject: [PATCH 04/15] fix: rollback --- src/boot/quasar.js | 13 +++++++------ src/components/NavBar.vue | 7 ++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 5e10bacf1..103b4812e 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -52,9 +52,9 @@ export default boot(({ app }) => { if (env && env !== 'development') return; message = 'Duplicate request'; } - // Convey to Alex or Juan... + const additionalData = { - frontPath: stateQuery.route.name, + frontPath: '', backError: { config: error.config, data: error, @@ -70,14 +70,15 @@ export default boot(({ app }) => { flat: false, round: true, handler: async () => { + const locale = i18n.global.t; const reason = ref( response.data.error.code == 'ACCESS_DENIED' - ? i18n.global.t('cau.askPrivileges') + ? locale('cau.askPrivileges') : '' ); openConfirmationModal( - i18n.global.t('cau.title'), - i18n.global.t('cau.subtitle'), + locale('cau.title'), + locale('cau.subtitle'), async () => { await axios.post('OsTickets/send-to-support', { reason: reason.value, @@ -90,7 +91,7 @@ export default boot(({ app }) => { props: { modelValue: reason, 'onUpdate:modelValue': (val) => (reason.value = val), - label: i18n.global.t('cau.inputLabel'), + label: locale('cau.inputLabel'), class: 'full-width', required: true, }, diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index 6f8377d96..9b0393489 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -1,7 +1,6 @@ From a5d032f0224f4184bcf619762ff569656765bc0c Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 13 Nov 2024 17:29:19 +0100 Subject: [PATCH 05/15] feat: make additional data object --- src/boot/quasar.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 103b4812e..a018eede7 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -5,12 +5,10 @@ import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; import { i18n } from './i18n'; import useNotify from 'src/composables/useNotify.js'; -import { useStateQueryStore } from 'src/stores/useStateQueryStore'; import VnInput from 'src/components/common/VnInput.vue'; import { useVnConfirm } from 'src/composables/useVnConfirm'; const { notify } = useNotify(); -const stateQuery = useStateQueryStore(); const { openConfirmationModal } = useVnConfirm(); export default boot(({ app }) => { @@ -53,13 +51,25 @@ export default boot(({ app }) => { message = 'Duplicate request'; } + const { config, headers, request, status, statusText, data } = response || {}; + const { params, url, method, signal, headers: confHeaders } = config || {}; + const { message: resMessage, code, name } = data?.error || {}; const additionalData = { - frontPath: '', - backError: { - config: error.config, - data: error, + path: location.href, + message: resMessage, + code, + request: request?.responseURL, + status, + name, + statusText: statusText, + config: { + url, + method, + params, + headers: confHeaders, + aborted: signal.aborted, + version: headers?.['salix-version'], }, - httpRequest: error.request.response, }; const opts = { actions: [ @@ -72,9 +82,7 @@ export default boot(({ app }) => { handler: async () => { const locale = i18n.global.t; const reason = ref( - response.data.error.code == 'ACCESS_DENIED' - ? locale('cau.askPrivileges') - : '' + code == 'ACCESS_DENIED' ? locale('cau.askPrivileges') : '' ); openConfirmationModal( locale('cau.title'), From 81f1c447ad4152dfaf1eb03da686ebf8cb1f3b31 Mon Sep 17 00:00:00 2001 From: jorgep Date: Wed, 13 Nov 2024 17:45:02 +0100 Subject: [PATCH 06/15] fix: rollback --- src/stores/useStateQueryStore.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/stores/useStateQueryStore.js b/src/stores/useStateQueryStore.js index 9893d3264..d25dbb921 100644 --- a/src/stores/useStateQueryStore.js +++ b/src/stores/useStateQueryStore.js @@ -3,9 +3,7 @@ import { defineStore } from 'pinia'; export const useStateQueryStore = defineStore('stateQueryStore', () => { const queries = ref(new Set()); - const route = computed(() => - Array.from(queries.value).find((query) => query?.fullPath) - ); + function add(query) { queries.value.add(query); return query; @@ -29,6 +27,5 @@ export const useStateQueryStore = defineStore('stateQueryStore', () => { remove, queries, reset, - route, }; }); From fa43f270ca0bc266c1f9644e15a19209f7bb7e30 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 14 Nov 2024 12:02:40 +0100 Subject: [PATCH 07/15] fix: prevent null --- src/boot/quasar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boot/quasar.js b/src/boot/quasar.js index a018eede7..720fc29de 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -67,7 +67,7 @@ export default boot(({ app }) => { method, params, headers: confHeaders, - aborted: signal.aborted, + aborted: signal?.aborted, version: headers?.['salix-version'], }, }; From 0fe740e415f3f15666fba18b4857adf8dd447de5 Mon Sep 17 00:00:00 2001 From: jorgep Date: Thu, 14 Nov 2024 13:20:23 +0100 Subject: [PATCH 08/15] fix: e2e --- src/pages/Worker/WorkerList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 02bea0231..81b231710 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -306,7 +306,7 @@ async function autofillBic(worker) { Date: Mon, 9 Dec 2024 13:42:00 +0100 Subject: [PATCH 09/15] refactor: add useCau composable --- src/boot/quasar.js | 71 ++----------------------------------- src/composables/useCau.js | 73 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 68 deletions(-) create mode 100644 src/composables/useCau.js diff --git a/src/boot/quasar.js b/src/boot/quasar.js index a1ae1eb3a..547517682 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -1,25 +1,18 @@ -import { ref } from 'vue'; import axios from 'axios'; import { boot } from 'quasar/wrappers'; import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; -import { i18n } from './i18n'; -import useNotify from 'src/composables/useNotify.js'; -import VnInput from 'src/components/common/VnInput.vue'; -import { useVnConfirm } from 'src/composables/useVnConfirm'; import { QForm } from 'quasar'; import { QLayout } from 'quasar'; import mainShortcutMixin from './mainShortcutMixin'; - -const { notify } = useNotify(); -const { openConfirmationModal } = useVnConfirm(); +import { useCau } from 'src/composables/useCau'; export default boot(({ app }) => { QForm.mixins = [qFormMixin]; QLayout.mixins = [mainShortcutMixin]; app.directive('shortcut', keyShortcut); - app.config.errorHandler = (error) => { + app.config.errorHandler = async (error) => { let message; const response = error.response; const responseData = response?.data; @@ -56,64 +49,6 @@ export default boot(({ app }) => { message = 'Duplicate request'; } - const { config, headers, request, status, statusText, data } = response || {}; - const { params, url, method, signal, headers: confHeaders } = config || {}; - const { message: resMessage, code, name } = data?.error || {}; - const additionalData = { - path: location.href, - message: resMessage, - code, - request: request?.responseURL, - status, - name, - statusText: statusText, - config: { - url, - method, - params, - headers: confHeaders, - aborted: signal?.aborted, - version: headers?.['salix-version'], - }, - }; - const opts = { - actions: [ - { - icon: 'support_agent', - color: 'primary', - dense: true, - flat: false, - round: true, - handler: async () => { - const locale = i18n.global.t; - const reason = ref( - code == 'ACCESS_DENIED' ? locale('cau.askPrivileges') : '' - ); - openConfirmationModal( - locale('cau.title'), - locale('cau.subtitle'), - async () => { - await axios.post('OsTickets/send-to-support', { - reason: reason.value, - additionalData, - }); - }, - null, - { - component: VnInput, - props: { - modelValue: reason, - 'onUpdate:modelValue': (val) => (reason.value = val), - label: locale('cau.inputLabel'), - class: 'full-width', - required: true, - }, - } - ); - }, - }, - ], - }; - notify(message ?? 'globals.error', 'negative', 'error', opts); + await useCau(response, message); }; }); diff --git a/src/composables/useCau.js b/src/composables/useCau.js new file mode 100644 index 000000000..29319bd9a --- /dev/null +++ b/src/composables/useCau.js @@ -0,0 +1,73 @@ +import VnInput from 'src/components/common/VnInput.vue'; +import { useVnConfirm } from 'src/composables/useVnConfirm'; +import axios from 'axios'; +import { ref } from 'vue'; +import { i18n } from 'src/boot/i18n'; +import useNotify from 'src/composables/useNotify.js'; + +export async function useCau(res, message) { + const { notify } = useNotify(); + const { openConfirmationModal } = useVnConfirm(); + const { config, headers, request, status, statusText, data } = res || {}; + const { params, url, method, signal, headers: confHeaders } = config || {}; + const { message: resMessage, code, name } = data?.error || {}; + + const additionalData = { + path: location.hash, + message: resMessage, + code, + request: request?.responseURL, + status, + name, + statusText: statusText, + config: { + url, + method, + params, + headers: confHeaders, + aborted: signal?.aborted, + version: headers?.['salix-version'], + }, + }; + const opts = { + actions: [ + { + icon: 'support_agent', + color: 'primary', + dense: true, + flat: false, + round: true, + handler: async () => { + const locale = i18n.global.t; + const reason = ref( + code == 'ACCESS_DENIED' ? locale('cau.askPrivileges') : '' + ); + openConfirmationModal( + locale('cau.title'), + locale('cau.subtitle'), + async () => { + await axios.post('OsTickets/send-to-support', { + reason: reason.value, + additionalData, + }); + }, + null, + { + component: VnInput, + props: { + modelValue: reason, + 'onUpdate:modelValue': (val) => (reason.value = val), + label: locale('cau.inputLabel'), + class: 'full-width', + required: true, + autofocus: true, + }, + } + ); + }, + }, + ], + }; + + notify(message ?? 'globals.error', 'negative', 'error', opts); +} From ff8561d0c255e582a6ab6badf5c68112660a75e2 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 9 Dec 2024 15:24:18 +0100 Subject: [PATCH 10/15] chore: refs #8282 add changelog --- CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03812d252..e110e4cd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,87 @@ +# Version 24.50 - 2024-12-10 + +### Added 🆕 + +- feat: add reportFileName option by:Javier Segarra +- feat: all clients just with global series by:jgallego +- feat: improve Merge branch 'test' into dev by:Javier Segarra +- feat: manual invoice in two lines by:jgallego +- feat: manualInvoice with address by:jgallego +- feat: randomize functions and example by:Javier Segarra +- feat: refs #6999 added search when user tabs on a filter with value by:Jon +- feat: refs #6999 added tab to search in VnTable filter by:Jon +- feat: refs #7346 #7346 improve form by:Javier Segarra +- feat: refs #7346 address ordered by:jgallego +- feat: refs #7346 radioButton by:jgallego +- feat: refs #7346 style radioButton by:jgallego +- feat: refs #7346 traducciones en cammelCase (7346-manualInvoice) by:jgallego +- feat: refs #8038 added new functionality in VnSelect and refactor styles by:Jon +- feat: refs #8061 #8061 updates by:Javier Segarra +- feat: refs #8087 reactive data by:jorgep +- feat: refs #8087 refs#8087 Redadas en travel by:Carlos Andrés +- feat: refs #8138 add component ticket problems by:pablone +- feat: refs #8163 add max length and more tests by:wbuezas +- feat: refs #8163 add prop by:wbuezas +- feat: refs #8163 add VnInput insert functionality and e2e test by:wbuezas +- feat: refs #8163 limit with maxLength by:Javier Segarra +- feat: refs #8163 maxLength SupplierFD account by:Javier Segarra +- feat: refs #8163 maxLengthVnInput by:Javier Segarra +- feat: refs #8163 use VnAccountNumber in VnAccountNumber by:Javier Segarra +- feat: refs #8166 show notification by:jorgep + +### Changed 📦 + +- feat: refs #8038 added new functionality in VnSelect and refactor styles by:Jon +- perf: add dataCy by:Javier Segarra +- perf: refs #7346 #7346 Imrpove interface dialog by:Javier Segarra +- perf: refs #7346 #7346 use v-show instead v-if by:Javier Segarra +- perf: refs #8036 currentFilter by:alexm +- perf: refs #8061 filter autonomy by:Javier Segarra +- perf: refs #8061 solve conflicts and random posCode it by:Javier Segarra +- perf: refs #8061 use opts from VnSelect by:Javier Segarra +- perf: refs #8163 #8061 createNewPostCodeForm by:Javier Segarra +- perf: remove console by:Javier Segarra +- perf: remove timeout by:Javier Segarra +- perf: test command fillInForm by:Javier Segarra +- refactor: refs #8162 remove comment by:wbuezas +- refactor: remove unnecesary things by:wbuezas + +### Fixed 🛠️ + +- fix: #8016 fetching data by:Javier Segarra +- fix: icons by:jgallego +- fix: refs #7229 download file by:jorgep +- fix: refs #7229 remove catch by:jorgep +- fix: refs #7229 set url by:jorgep +- fix: refs #7229 test by:jorgep +- fix: refs #7229 url by:jorgep +- fix: refs #7229 url + test by:jorgep +- fix: refs #7304 7304 clean warning by:carlossa +- fix: refs #7304 fix list by:carlossa +- fix: refs #7304 fix warning by:carlossa +- fix: refs #7346 traslations by:jgallego +- fix: refs #7529 add save by:carlossa +- fix: refs #7529 fix e2e by:carlossa +- fix: refs #7529 fix front by:carlossa +- fix: refs #7529 fix scss by:carlossa +- fix: refs #7529 fix te2e by:carlossa +- fix: refs #7529 fix workerPit e2e by:carlossa +- fix: refs #7529 front by:carlossa +- fix: refs #8036 apply exprBuilder after save filters by:alexm +- fix: refs #8036 only add where when required by:alexm +- fix: refs #8038 solve conflicts by:Jon +- fix: refs #8061 improve code dependencies (origin/8061_improve_newCP) by:Javier Segarra +- fix: refs #8138 move component from ui folder by:pablone +- fix: refs #8138 sme minor issues by:pablone +- fix: refs #8163 #8061 createNewPostCodeForm by:Javier Segarra +- fix: refs #8163 minor problem when keypress by:Javier Segarra +- fix: refs #8166 show zone error by:jorgep +- fix: removed selectedClient by:jgallego +- refs #7529 fix workerPit by:carlossa +- revert: refs #8061 test #8061 updates by:Javier Segarra +- test: fix own test by:Javier Segarra +- test: refs #8162 #8162 fix TicketList spec by:Javier Segarra + # Version 24.48 - 2024-11-25 ### Added 🆕 From dd33dfc76615f773178c62616d38e813e39eef1c Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 10 Dec 2024 07:49:59 +0100 Subject: [PATCH 11/15] fix(VnSelect): hotFix handleKeyDown add next focus --- src/components/common/VnSelect.vue | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index e116be32a..e5ac05231 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -268,7 +268,7 @@ async function onScroll({ to, direction, from, index }) { defineExpose({ opts: myOptions }); function handleKeyDown(event) { - if (event.key === 'Tab') { + if (event.key === 'Tab' && !event.shiftKey) { event.preventDefault(); const inputValue = vnSelectRef.value?.inputValue; @@ -286,6 +286,17 @@ function handleKeyDown(event) { } vnSelectRef.value?.hidePopup(); } + + const focusableElements = document.querySelectorAll( + 'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])' + ); + const currentIndex = Array.prototype.indexOf.call( + focusableElements, + event.target + ); + if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) { + focusableElements[currentIndex + 1].focus(); + } } } From 8dcf272942228134b30829a728efac283fbb5d22 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 10 Dec 2024 08:34:48 +0100 Subject: [PATCH 12/15] fix: #8282 CustomerSummary email icon --- src/pages/Customer/Card/CustomerSummary.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index f4c5e6e09..ae4c7f3ab 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -101,7 +101,7 @@ const sumRisk = ({ clientRisks }) => { Date: Tue, 10 Dec 2024 08:35:04 +0100 Subject: [PATCH 13/15] fix: replace useNotify by useQuasar --- src/pages/Account/Card/AccountDescriptorMenu.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue index 6f1d2ca1f..1780b4247 100644 --- a/src/pages/Account/Card/AccountDescriptorMenu.vue +++ b/src/pages/Account/Card/AccountDescriptorMenu.vue @@ -8,7 +8,7 @@ import { useAcl } from 'src/composables/useAcl'; import { useArrayData } from 'src/composables/useArrayData'; import VnConfirm from 'src/components/ui/VnConfirm.vue'; import VnChangePassword from 'src/components/common/VnChangePassword.vue'; -import useNotify from 'src/composables/useNotify.js'; +import { useQuasar } from 'quasar'; const $props = defineProps({ hasAccount: { @@ -21,7 +21,7 @@ const { t } = useI18n(); const { hasAccount } = toRefs($props); const { openConfirmationModal } = useVnConfirm(); const route = useRoute(); -const { notify } = useNotify(); +const { notify } = useQuasar(); const account = computed(() => useArrayData('AccountId').store.data[0]); account.value.hasAccount = hasAccount.value; const entityId = computed(() => +route.params.id); From 4a6f859a867021ce6ee3da7169b732d38ee44872 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 10 Dec 2024 13:15:03 +0100 Subject: [PATCH 14/15] fix(RouteExtendedList): fix cloneRoutes --- src/pages/Route/RouteExtendedList.vue | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue index dbf646935..38e907ce0 100644 --- a/src/pages/Route/RouteExtendedList.vue +++ b/src/pages/Route/RouteExtendedList.vue @@ -223,10 +223,10 @@ function navigate(id) { router.push({ path: `/route/${id}` }); } -const cloneRoutes = () => { +const cloneRoutes = async () => { if (!selectedRows.value.length || !startingDate.value) return; - axios.post('Routes/clone', { - created: startingDate.value, + await axios.post('Routes/clone', { + dated: startingDate.value, ids: selectedRows.value.map((row) => row?.id), }); startingDate.value = null; @@ -274,7 +274,6 @@ const openTicketsDialog = (id) => {

{{ t('route.Select the starting date') }}

- Date: Tue, 10 Dec 2024 13:17:31 +0100 Subject: [PATCH 15/15] perf: emit options from VnSelectProvince --- src/components/CreateNewPostcodeForm.vue | 18 +++++------------- src/components/VnSelectProvince.vue | 3 ++- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue index d3d6708f0..c656fcb2f 100644 --- a/src/components/CreateNewPostcodeForm.vue +++ b/src/components/CreateNewPostcodeForm.vue @@ -25,7 +25,6 @@ const townsFetchDataRef = ref(false); const townFilter = ref({}); const countriesRef = ref(false); -const provincesFetchDataRef = ref(false); const provincesOptions = ref([]); const townsOptions = ref([]); const town = ref({}); @@ -71,9 +70,6 @@ async function setProvince(id, data) { await fetchTowns(); } async function onProvinceCreated(data) { - await provincesFetchDataRef.value.fetch({ - where: { countryFk: postcodeFormData.countryFk }, - }); postcodeFormData.provinceFk = data.id; } function provinceByCountry(countryFk = postcodeFormData.countryFk) { @@ -92,7 +88,6 @@ function setTown(newTown, data) { data.countryFk = newTown?.province?.countryFk ?? newTown; } async function onCityCreated(newTown, formData) { - await provincesFetchDataRef.value.fetch(); newTown.province = provincesOptions.value.find( (province) => province.id === newTown.provinceFk ); @@ -125,14 +120,6 @@ async function filterTowns(name) {