diff --git a/CHANGELOG.md b/CHANGELOG.md index 555b4f0ba..9f493764a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +### Fixed + +- (General) => Se vuelven a mostrar los parámetros en la url al aplicar un filtro + ## [2414.01] - 2024-04-04 ### Added diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index 8787371bc..a7af0044b 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -101,16 +101,16 @@ onMounted(async () => { }); onBeforeRouteLeave((to, from, next) => { - if (!hasChanges.value) next(); - - quasar.dialog({ - component: VnConfirm, - componentProps: { - title: t('Unsaved changes will be lost'), - message: t('Are you sure exit without saving?'), - promise: () => next(), - }, - }); + if (hasChanges.value) + quasar.dialog({ + component: VnConfirm, + componentProps: { + title: t('Unsaved changes will be lost'), + message: t('Are you sure exit without saving?'), + promise: () => next(), + }, + }); + else next(); }); onUnmounted(() => { diff --git a/src/components/common/VnCurrency.vue b/src/components/common/VnCurrency.vue index 660c4e979..b892e5012 100644 --- a/src/components/common/VnCurrency.vue +++ b/src/components/common/VnCurrency.vue @@ -5,7 +5,7 @@ import { useCapitalize } from 'src/composables/useCapitalize'; import VnInput from 'src/components/common/VnInput.vue'; const props = defineProps({ - modelValue: { type: String, default: '' }, + modelValue: { type: [String, Number], default: '' }, }); const { t } = useI18n(); diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index bf3f4d384..76864f026 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -198,11 +198,13 @@ function addDefaultData(data) { en: contentTypesInfo: Allowed file types {allowedContentTypes} EntryDmsDescription: Reference {reference} + WorkersDescription: Working of employee id {reference} SupplierDmsDescription: Reference {reference} es: Generate identifier for original file: Generar identificador para archivo original contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} EntryDmsDescription: Referencia {reference} + WorkersDescription: Laboral del empleado {reference} SupplierDmsDescription: Referencia {reference} diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index 23e00f5d9..f70146c58 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -5,9 +5,11 @@ import { useRoute } from 'vue-router'; import { useQuasar, QCheckbox, QBtn, QInput } from 'quasar'; import axios from 'axios'; -import FetchData from 'components/FetchData.vue'; +import VnPaginate from 'components/ui/VnPaginate.vue'; import VnDms from 'src/components/common/VnDms.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; +import VnInputDate from 'components/common/VnInputDate.vue'; +import VnUserLink from '../ui/VnUserLink.vue'; import { downloadFile } from 'src/composables/downloadFile'; const route = useRoute(); @@ -26,6 +28,15 @@ const $props = defineProps({ type: String, default: null, }, + deleteModel: { + type: String, + default: null, + }, + downloadModel: { + type: String, + required: false, + default: null, + }, defaultDmsCode: { type: String, required: true, @@ -74,7 +85,7 @@ const dmsFilter = { ], }, }, - order: ['dmsFk DESC'], + where: { [$props.filter]: route.params.id }, }; const columns = computed(() => [ @@ -94,12 +105,12 @@ const columns = computed(() => [ props: (prop) => ({ readonly: true, borderless: true, - 'model-value': prop.row.dmsType.name, + 'model-value': prop.row.dmsType?.name, }), }, { align: 'left', - field: 'order', + field: 'hardCopyNumber', label: t('globals.order'), name: 'order', component: 'span', @@ -117,6 +128,7 @@ const columns = computed(() => [ label: t('globals.description'), name: 'description', component: 'span', + props: (prop) => ({ value: prop.value?.toUpperCase() }), }, { align: 'left', @@ -136,21 +148,53 @@ const columns = computed(() => [ name: 'file', component: 'span', }, + { + align: 'left', + field: 'worker', + label: t('globals.worker'), + name: 'worker', + component: VnUserLink, + props: (prop) => ({ + name: prop.row.worker?.user?.name.toLowerCase(), + workerId: prop.row.worker?.id, + }), + }, + { + align: 'left', + field: 'created', + label: t('globals.created'), + name: 'created', + component: VnInputDate, + props: (prop) => ({ + disable: true, + 'model-value': prop.row.created, + }), + }, { field: 'options', name: 'options', components: [ { component: QBtn, + name: 'download', + isDocuware: true, props: () => ({ icon: 'cloud_download', flat: true, color: 'primary', }), - click: (prop) => downloadFile(prop.row.id), + click: (prop) => + downloadFile( + prop.row.id, + $props.downloadModel, + null, + prop.row.download + ), }, { component: QBtn, + name: 'edit', + external: false, props: () => ({ icon: 'edit', flat: true, @@ -160,6 +204,8 @@ const columns = computed(() => [ }, { component: QBtn, + name: 'delete', + external: false, props: () => ({ icon: 'delete', flat: true, @@ -167,12 +213,24 @@ const columns = computed(() => [ }), click: (prop) => deleteDms(prop.row.id), }, + { + component: QBtn, + name: 'open', + external: true, + props: () => ({ + icon: 'open_in_new', + flat: true, + color: 'primary', + }), + click: (prop) => open(prop.row.url), + }, ], }, ]); function setData(data) { - const newData = data.map((value) => value.dms); + const newData = data.map((value) => value.dms || value); + newData.sort((a, b) => new Date(b.created) - new Date(a.created)); rows.value = newData; } @@ -186,7 +244,7 @@ function deleteDms(dmsFk) { }, }) .onOk(async () => { - await axios.post(`${$props.model}/${dmsFk}/removeFile`); + await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); const index = rows.value.findIndex((row) => row.id == dmsFk); rows.value.splice(index, 1); }); @@ -206,84 +264,106 @@ function parseDms(data) { } return data; } + +async function open(url) { + window.open(url).focus(); +} + +function shouldRenderButton(button, isExternal = false) { + if (button.name == 'download') return true; + return button.external === isExternal; +} es: diff --git a/src/pages/Worker/Card/WorkerDms.vue b/src/pages/Worker/Card/WorkerDms.vue new file mode 100644 index 000000000..a4f7ef5a9 --- /dev/null +++ b/src/pages/Worker/Card/WorkerDms.vue @@ -0,0 +1,15 @@ + + diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index 5da5dba10..e0e91c9f2 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -20,6 +20,7 @@ export default { 'WorkerPBX', 'WorkerLog', 'WorkerCalendar', + 'WorkerDms', ], departmentCard: ['BasicData'], }, @@ -128,6 +129,15 @@ export default { }, component: () => import('src/pages/Worker/Card/WorkerPBX.vue'), }, + { + name: 'WorkerDms', + path: 'dms', + meta: { + title: 'dms', + icon: 'cloud_upload', + }, + component: () => import('src/pages/Worker/Card/WorkerDms.vue'), + }, { name: 'WorkerLog', path: 'log', diff --git a/test/cypress/integration/vnSearchBar.spec.js b/test/cypress/integration/vnSearchBar.spec.js index 3db789773..f1f3a9e82 100644 --- a/test/cypress/integration/vnSearchBar.spec.js +++ b/test/cypress/integration/vnSearchBar.spec.js @@ -36,7 +36,7 @@ describe('VnSearchBar', () => { const checkCardListAndUrl = (expectedLength) => { cy.get(cardList).then(($cardList) => { expect($cardList.find('.q-card').length).to.equal(expectedLength); - cy.url().then((currentUrl) => expect(currentUrl).to.equal(url)); + cy.url().then((currentUrl) => expect(currentUrl).to.contain(url)); }); }; }); diff --git a/test/vitest/__tests__/composables/useArrayData.spec.js b/test/vitest/__tests__/composables/useArrayData.spec.js new file mode 100644 index 000000000..ae0ca7368 --- /dev/null +++ b/test/vitest/__tests__/composables/useArrayData.spec.js @@ -0,0 +1,31 @@ +import { describe, expect, it, beforeAll } from 'vitest'; +import { axios } from 'app/test/vitest/helper'; +import { useArrayData } from 'composables/useArrayData'; + +describe('useArrayData', () => { + let arrayData; + beforeAll(() => { + axios.get.mockResolvedValue({ data: [] }); + arrayData = useArrayData('InvoiceIn', { url: 'invoice-in/list' }); + Object.defineProperty(window.location, 'href', { + writable: true, + value: 'localhost:9000/invoice-in/list', + }); + + // Mock the window.history.pushState method within useArrayData + window.history.pushState = (data, title, url) => (window.location.href = url); + + // Mock the URL constructor within useArrayData + global.URL = class URL { + constructor(url) { + this.hash = url.split('localhost:9000/')[1]; + } + }; + }); + + it('should add the params to the url', async () => { + arrayData.store.userParams = { supplierFk: 2 }; + arrayData.updateStateParams(); + expect(window.location.href).contain('params=%7B%22supplierFk%22%3A2%7D'); + }); +});