From 3f1c0b95faf7d8ff00b10fa93acdbed4047d6b9a Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 10 Jul 2024 15:03:25 +0200 Subject: [PATCH 001/214] fix: proposal to avoid notify error --- src/pages/Customer/Card/CustomerUnpaid.vue | 2 +- src/pages/Customer/Card/CustomerWebAccess.vue | 2 +- src/pages/Customer/components/CustomerChangePassword.vue | 2 +- src/pages/Customer/components/CustomerSamplesCreate.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/Customer/Card/CustomerUnpaid.vue b/src/pages/Customer/Card/CustomerUnpaid.vue index a9d4a3d66..6c61b92a1 100644 --- a/src/pages/Customer/Card/CustomerUnpaid.vue +++ b/src/pages/Customer/Card/CustomerUnpaid.vue @@ -92,7 +92,7 @@ const onSubmit = async () => { notify('globals.dataSaved', 'positive'); unpaidClient.value = true; } catch (error) { - notify('errors.create', 'negative'); + notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; } diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index 33659dd77..4468c52f0 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -70,7 +70,7 @@ const onSubmit = async () => { notify('globals.dataSaved', 'positive'); if (usersPreviewRef.value) usersPreviewRef.value.fetch(); } catch (error) { - notify('errors.create', 'negative'); + notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; } diff --git a/src/pages/Customer/components/CustomerChangePassword.vue b/src/pages/Customer/components/CustomerChangePassword.vue index 1bfc5e103..632b11dc9 100644 --- a/src/pages/Customer/components/CustomerChangePassword.vue +++ b/src/pages/Customer/components/CustomerChangePassword.vue @@ -48,7 +48,7 @@ const onSubmit = async () => { await axios.patch(`Clients/${$props.id}/setPassword`, payload); await $props.promise(); } catch (error) { - notify('errors.create', 'negative'); + notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; if (closeButton.value) closeButton.value.click(); diff --git a/src/pages/Customer/components/CustomerSamplesCreate.vue b/src/pages/Customer/components/CustomerSamplesCreate.vue index be614aa0b..283b8fa97 100644 --- a/src/pages/Customer/components/CustomerSamplesCreate.vue +++ b/src/pages/Customer/components/CustomerSamplesCreate.vue @@ -150,7 +150,7 @@ const onSubmit = async () => { notify('globals.dataSaved', 'positive'); onDataSaved(data); } catch (error) { - notify('errors.create', 'negative'); + notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; } From e90b78c4c5867f2afd48b9029c9b443d5291c385 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 13 Sep 2024 12:27:37 +0200 Subject: [PATCH 002/214] fix: refs #7702 rollback --- src/pages/Customer/Card/CustomerWebAccess.vue | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index 3dc025d9c..f990e720c 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; import { useQuasar } from 'quasar'; -import useNotify from 'src/composables/useNotify'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; import FormModel from 'components/FormModel.vue'; @@ -13,7 +12,6 @@ const { t } = useI18n(); const quasar = useQuasar(); const route = useRoute(); const canChangePassword = ref(0); -const { notify } = useNotify(); const filter = computed(() => { return { @@ -32,13 +30,8 @@ const showChangePasswordDialog = () => { }; async function hasCustomerRole() { - try { - canChangePassword.value = ( - await axios(`Clients/${route.params.id}/hasCustomerRole`) - ).data; - } catch (e) { - notify('errors.writeRequest', 'negative'); - } + const { data } = await axios(`Clients/${route.params.id}/hasCustomerRole`); + canChangePassword.value = data; } From 4bf8e1224d1d8cd0082174fe7830baeeddc45b0c Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 13 Sep 2024 12:28:07 +0200 Subject: [PATCH 003/214] chore: refs #7702 rollback --- src/pages/Customer/Card/CustomerWebAccess.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index f990e720c..8d025a365 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; import { useQuasar } from 'quasar'; + import VnInput from 'src/components/common/VnInput.vue'; import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; import FormModel from 'components/FormModel.vue'; From 98cdeabe9f91791faa4a623ed9e67237180b0666 Mon Sep 17 00:00:00 2001 From: jorgep Date: Fri, 13 Sep 2024 18:15:28 +0200 Subject: [PATCH 004/214] feat: refs #7702 vnChangePassword --- src/components/common/VnChangePassword.vue | 112 ++++++++++++++++++ src/pages/Customer/Card/CustomerWebAccess.vue | 28 ++--- 2 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 src/components/common/VnChangePassword.vue diff --git a/src/components/common/VnChangePassword.vue b/src/components/common/VnChangePassword.vue new file mode 100644 index 000000000..d7c9ad02f --- /dev/null +++ b/src/components/common/VnChangePassword.vue @@ -0,0 +1,112 @@ + + + + +es: + Change password: Cambiar contraseña + New password: Nueva contraseña + Repeat password: Repetir contraseña + You must enter a new password: Debes introducir la nueva contraseña + Passwords don't match: Las contraseñas no coinciden + diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index 8d025a365..ba906a144 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -3,14 +3,11 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; -import { useQuasar } from 'quasar'; - import VnInput from 'src/components/common/VnInput.vue'; -import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; import FormModel from 'components/FormModel.vue'; +import VnChangePassword from 'src/components/common/VnChangePassword.vue'; const { t } = useI18n(); -const quasar = useQuasar(); const route = useRoute(); const canChangePassword = ref(0); @@ -21,21 +18,11 @@ const filter = computed(() => { }; }); -const showChangePasswordDialog = () => { - quasar.dialog({ - component: CustomerChangePassword, - componentProps: { - id: route.params.id, - }, - }); -}; - async function hasCustomerRole() { const { data } = await axios(`Clients/${route.params.id}/hasCustomerRole`); canChangePassword.value = data; } - + - es: Enable web access: Habilitar acceso web From 9ec2fb4c77edede9e5b80a34a80263a33ac80a1c Mon Sep 17 00:00:00 2001 From: jorgep Date: Mon, 16 Sep 2024 10:36:56 +0200 Subject: [PATCH 005/214] feat: refs #7702 fine tunning --- src/components/common/VnChangePassword.vue | 14 +++++++- src/pages/Worker/Card/WorkerDescriptor.vue | 40 ++++++++++------------ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/components/common/VnChangePassword.vue b/src/components/common/VnChangePassword.vue index d7c9ad02f..a36c6bcff 100644 --- a/src/components/common/VnChangePassword.vue +++ b/src/components/common/VnChangePassword.vue @@ -7,7 +7,7 @@ import FetchData from '../FetchData.vue'; import useNotify from 'src/composables/useNotify'; const props = defineProps({ submitFn: { type: Function, default: () => {} } }); - +const emit = defineEmits(['onSubmit']); const { t } = useI18n(); const { notify } = useNotify(); @@ -15,19 +15,27 @@ const form = ref(); const changePassDialog = ref(); const passwords = ref({ newPassword: null, repeatPassword: null }); const requirements = ref([]); +const isLoading = ref(false); const validate = async () => { const { newPassword, repeatPassword } = passwords.value; + if (!newPassword) { + notify(t('You must enter a new password'), 'negative'); + return; + } if (newPassword !== repeatPassword) { notify(t("Passwords don't match"), 'negative'); return; } try { + isLoading.value = true; await props.submitFn(newPassword); + emit('onSubmit'); } catch (e) { notify('errors.writeRequest', 'negative'); } finally { changePassDialog.value.hide(); + isLoading.value = false; } }; @@ -84,6 +92,8 @@ defineExpose({ show: () => changePassDialog.value.show() }); changePassDialog.value.show() }); v-close-popup /> { showEditPhotoForm.value = !showEditPhotoForm.value; }; - const entityId = computed(() => { return $props.id || route.params.id; }); - -const worker = ref(); const workerExcluded = ref(false); const getIsExcluded = async () => { @@ -61,10 +56,10 @@ const handleExcluded = async () => { workerExcluded.value = !workerExcluded.value; }; + const handlePhotoUpdated = (evt = false) => { image.value.reload(evt); }; -const refetch = async () => await cardDescriptorRef.value.getData(); @@ -197,6 +184,15 @@ const refetch = async () => await cardDescriptorRef.value.getData(); + +en: + daysOnward: Days onward + daysAgo: Days ago es: No filters applied: No se han aplicado filtros Applied filters: Filtros aplicados @@ -294,4 +297,6 @@ es: Search: Buscar Yes: Si No: No + daysOnward: Días Adelante + daysAgo: Días Atrás diff --git a/src/pages/Entry/MyEntries.vue b/src/pages/Entry/MyEntries.vue index 17b1f91c5..b95c73847 100644 --- a/src/pages/Entry/MyEntries.vue +++ b/src/pages/Entry/MyEntries.vue @@ -9,6 +9,11 @@ import VnTable from 'components/VnTable/VnTable.vue'; const { t } = useI18n(); const quasar = useQuasar(); +const params = { + daysOnward: 7, + daysAgo: 3, +}; + const columns = computed(() => [ { align: 'left', @@ -120,6 +125,7 @@ const printBuys = (rowId) => { data-key="myEntriesList" url="Entries/filter" :columns="columns" + :user-params="params" default-mode="card" order="shipped DESC" auto-load From 271e33a999d54cf06788aa41dce6164658aaf6ab Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 20 Sep 2024 11:57:15 +0200 Subject: [PATCH 013/214] feat: formatLocation when field is null --- src/components/common/VnLocation.vue | 40 +++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index b6cbfbafd..c3b07c72c 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -12,14 +12,46 @@ const props = defineProps({ default: null, }, }); +const formatLocation = (obj, properties) => { + // Crear un array con las propiedades del objeto + const parts = properties.map((prop) => { + if (typeof prop === 'string') { + return obj[prop]; + } else if (typeof prop === 'function') { + return prop(obj); + } + return null; + }); + + // Filtrar los valores que no son null o undefined + const filteredParts = parts.filter( + (part) => part !== null && part !== undefined && part !== '' + ); + + // Unir los valores filtrados con el formato deseado + return filteredParts.join(', '); +}; + +const locationProperties = [ + 'postcode', + (obj) => + obj.city + ? `${obj.city}${obj.province?.name ? `(${obj.province.name})` : ''}` + : null, + (obj) => obj.country?.name, +]; const modelValue = ref( - props.location - ? `${props.location?.postcode} - ${props.location?.city}(${props.location?.province?.name}), ${props.location?.country?.name}` - : null + props.location ? formatLocation(props.location, locationProperties) : null ); function showLabel(data) { - return `${data.code} - ${data.town}(${data.province}), ${data.country}`; + const dataProperties = [ + 'code', + (obj) => (obj.town ? `${obj.town}(${obj.province})` : null), + 'country', + ]; + return formatLocation(data, dataProperties); } + const handleModelValue = (data) => { emit('update:model-value', data); }; From b822c7722bb3176120c87aa74abbb7c2c33ec88d Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Fri, 20 Sep 2024 13:45:43 +0200 Subject: [PATCH 014/214] feat: formatLocation when field is null --- src/components/common/VnLocation.vue | 68 +++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index 8256ec5b0..c1b921915 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -2,21 +2,68 @@ import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue'; import { useI18n } from 'vue-i18n'; - +import { ref } from 'vue'; const { t } = useI18n(); -const value = defineModel({ type: [String, Number, Object] }); +const emit = defineEmits(['update:model-value', 'update:options']); + +const props = defineProps({ + location: { + type: Object, + default: null, + }, +}); +const formatLocation = (obj, properties) => { + const parts = properties.map((prop) => { + if (typeof prop === 'string') { + return obj[prop]; + } else if (typeof prop === 'function') { + return prop(obj); + } + return null; + }); + + const filteredParts = parts.filter( + (part) => part !== null && part !== undefined && part !== '' + ); + + return filteredParts.join(', '); +}; + +const locationProperties = [ + 'postcode', + (obj) => + obj.city + ? `${obj.city}${obj.province?.name ? `(${obj.province.name})` : ''}` + : null, + (obj) => obj.country?.name, +]; + +const modelValue = ref( + props.location ? formatLocation(props.location, locationProperties) : null +); + +const handleModelValue = (data) => { + emit('update:model-value', data); +}; function showLabel(data) { - return `${data.code} - ${data.town}(${data.province}), ${data.country}`; + const dataProperties = [ + 'code', + (obj) => (obj.town ? `${obj.town}(${obj.province})` : null), + 'country', + ]; + return formatLocation(data, dataProperties); } diff --git a/src/pages/Worker/locale/en.yml b/src/pages/Worker/locale/en.yml index 96df37919..96764ffd1 100644 --- a/src/pages/Worker/locale/en.yml +++ b/src/pages/Worker/locale/en.yml @@ -4,3 +4,4 @@ tableColumns: name: Name department: Department email: Email +queue: Queue diff --git a/src/pages/Worker/locale/es.yml b/src/pages/Worker/locale/es.yml index 41812345f..cf6bc3afe 100644 --- a/src/pages/Worker/locale/es.yml +++ b/src/pages/Worker/locale/es.yml @@ -9,3 +9,4 @@ tableColumns: name: Nombre department: Departamento email: Email +queue: Cola From a5c6d628ca9eb4378cd548e4a4d9b79bc554592e Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 23 Sep 2024 18:48:58 +0000 Subject: [PATCH 022/214] feat: enable notify positive when user update self data --- src/components/UserPanel.vue | 43 +++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue index 98334460a..5276f9e20 100644 --- a/src/components/UserPanel.vue +++ b/src/components/UserPanel.vue @@ -13,12 +13,14 @@ import FetchData from 'components/FetchData.vue'; import { useClipboard } from 'src/composables/useClipboard'; import { useRole } from 'src/composables/useRole'; import VnAvatar from './ui/VnAvatar.vue'; +import useNotify from 'src/composables/useNotify'; const state = useState(); const session = useSession(); const router = useRouter(); const { t, locale } = useI18n(); const { copyText } = useClipboard(); +const { notify } = useNotify(); const userLocale = computed({ get() { @@ -53,6 +55,7 @@ const user = state.getUser(); const warehousesData = ref(); const companiesData = ref(); const accountBankData = ref(); +const isEmployee = computed(() => useRole().isEmployee()); onMounted(async () => { updatePreferences(); @@ -70,18 +73,28 @@ function updatePreferences() { async function saveDarkMode(value) { const query = `/UserConfigs/${user.value.id}`; - await axios.patch(query, { - darkMode: value, - }); - user.value.darkMode = value; + try { + await axios.patch(query, { + darkMode: value, + }); + user.value.darkMode = value; + notify('globals.dataSaved', 'positive'); + } catch (error) { + console.error(error); + } } async function saveLanguage(value) { const query = `/VnUsers/${user.value.id}`; - await axios.patch(query, { - lang: value, - }); - user.value.lang = value; + try { + await axios.patch(query, { + lang: value, + }); + user.value.lang = value; + notify('globals.dataSaved', 'positive'); + } catch (error) { + console.error(error); + } } function logout() { @@ -98,10 +111,18 @@ function localUserData() { } function saveUserData(param, value) { - axios.post('UserConfigs/setUserConfig', { [param]: value }); - localUserData(); + try { + axios.post('UserConfigs/setUserConfig', { [param]: value }); + localUserData(); + notify('globals.dataSaved', 'positive'); + } catch (error) { + console.error(error); + } } -const isEmployee = computed(() => useRole().isEmployee()); + +const onDataSaved = () => { + notify('globals.dataSaved', 'positive'); +}; + es: isOwn: Tiene propietario diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue new file mode 100644 index 000000000..1e20df99c --- /dev/null +++ b/src/pages/Route/RouteExtendedList.vue @@ -0,0 +1,411 @@ + + + + + + +en: + newRoute: New Route + hourStarted: Started hour + hourFinished: Finished hour +es: + From: Desde + To: Hasta + Worker: Trabajador + Agency: Agencia + Vehicle: Vehículo + Volume: Volumen + Date: Fecha + Description: Descripción + Hour started: Hora inicio + Hour finished: Hora fin + KmStart: Km inicio + KmEnd: Km fin + Served: Servida + newRoute: Nueva Ruta + Clone Selected Routes: Clonar rutas seleccionadas + Select the starting date: Seleccione la fecha de inicio + Stating date: Fecha de inicio + Cancel: Cancelar + Mark as served: Marcar como servidas + Download selected routes as PDF: Descargar rutas seleccionadas como PDF + Add ticket: Añadir tickets + Preview: Vista previa + Summary: Resumen + Route is closed: La ruta está cerrada + Route is not served: La ruta no está servida + hourStarted: Hora de inicio + hourFinished: Hora de fin + diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue index 1e20df99c..20e5deb1e 100644 --- a/src/pages/Route/RouteList.vue +++ b/src/pages/Route/RouteList.vue @@ -1,34 +1,19 @@ - - -es: - Worker: Trabajador - Agency: Agencia - Vehicle: Vehículo - Description: Descripción - Hour started: Hora inicio - Hour finished: Hora fin - diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml new file mode 100644 index 000000000..617d704d2 --- /dev/null +++ b/src/pages/Route/locale/en.yml @@ -0,0 +1,25 @@ +route: + Worker: Worker + Agency: Agency + Vehicle: Vehicle + Description: Description + hourStarted: H.Start + hourFinished: H.End + createRoute: Create route + From: From + To: To + Date: Date + KmStart: Km start + KmEnd: Km end + Served: Served + Clone Selected Routes: Clone selected routes + Select the starting date: Select the starting date + Stating date: Starting date + Cancel: Cancel + Mark as served: Mark as served + Download selected routes as PDF: Download selected routes as PDF + Add ticket: Add ticket + Preview: Preview + Summary: Summary + Route is closed: Route is closed + Route is not served: Route is not served diff --git a/src/pages/Route/locale/es.yml b/src/pages/Route/locale/es.yml new file mode 100644 index 000000000..ed96ad915 --- /dev/null +++ b/src/pages/Route/locale/es.yml @@ -0,0 +1,25 @@ +route: + Worker: Trabajador + Agency: Agencia + Vehicle: Vehículo + Description: Descripción + hourStarted: H.Inicio + hourFinished: H.Fin + createRoute: Crear ruta + From: Desde + To: Hasta + Date: Fecha + KmStart: Km inicio + KmEnd: Km fin + Served: Servida + Clone Selected Routes: Clonar rutas seleccionadas + Select the starting date: Seleccione la fecha de inicio + Stating date: Fecha de inicio + Cancel: Cancelar + Mark as served: Marcar como servidas + Download selected routes as PDF: Descargar rutas seleccionadas como PDF + Add ticket: Añadir tickets + Preview: Vista previa + Summary: Resumen + Route is closed: La ruta está cerrada + Route is not served: La ruta no está servida diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index d7dce911b..829eb3a17 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -319,7 +319,7 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`; -