diff --git a/Jenkinsfile b/Jenkinsfile index 63577dad5e9..2f11556b5d7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -120,6 +120,8 @@ pipeline { def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs') sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY' + sh "docker-compose ${env.COMPOSE_PARAMS} pull back" + sh "docker-compose ${env.COMPOSE_PARAMS} pull db" sh "docker-compose ${env.COMPOSE_PARAMS} up -d" image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") { diff --git a/README.md b/README.md index 262e12e5834..d280e29ceb5 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,18 @@ pnpm run test:front pnpm run test:e2e ``` +### Run e2e parallel + +```bash +pnpm run test:e2e:parallel +``` + +### View e2e parallel report + +```bash +pnpm run test:e2e:summary +``` + ### Build the app for production ```bash diff --git a/docs/Dockerfile.dev b/docs/Dockerfile.dev index 84a4d80bc37..3117e2c2050 100644 --- a/docs/Dockerfile.dev +++ b/docs/Dockerfile.dev @@ -25,6 +25,8 @@ RUN apt-get update \ libnss3 \ libxss1 \ libxtst6 \ + mesa-vulkan-drivers \ + vulkan-tools \ xauth \ xvfb \ && apt-get clean \ diff --git a/package.json b/package.json index 33b730b9e17..076cbbb1468 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "test:e2e": "cypress open", "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run", - "test:e2e:parallel": "bash ./test/cypress/cypressParallel.sh", + "test:e2e:parallel": "bash ./test/cypress/run.sh", "test:e2e:summary": "bash ./test/cypress/summary.sh", "test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test:front": "vitest", @@ -56,6 +56,7 @@ "eslint-plugin-cypress": "^4.1.0", "eslint-plugin-vue": "^9.32.0", "husky": "^8.0.0", + "junit-merge": "^2.0.0", "mocha": "^11.1.0", "postcss": "^8.4.23", "prettier": "^3.4.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 168fb9e0d4e..51fc7546973 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,6 +91,9 @@ devDependencies: husky: specifier: ^8.0.0 version: 8.0.3 + junit-merge: + specifier: ^2.0.0 + version: 2.0.0 mocha: specifier: ^11.1.0 version: 11.1.0 @@ -4860,6 +4863,10 @@ packages: universalify: 2.0.1 dev: true + /fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + dev: true + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -5640,6 +5647,16 @@ packages: verror: 1.10.0 dev: true + /junit-merge@2.0.0: + resolution: {integrity: sha512-qwENzBWcdHPazNqPO0fKyFIqEyaSKyO0iyBeIU4Y/scjkXYpwTi88P2S/PWecqgMhzG2MOCwXk8QB9ucvXeIPw==} + hasBin: true + dependencies: + commander: 2.20.3 + fs-readdir-recursive: 1.1.0 + mkdirp: 0.5.6 + xmldoc: 1.3.0 + dev: true + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -6037,7 +6054,6 @@ packages: hasBin: true dependencies: minimist: 1.2.8 - dev: false /mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -7253,6 +7269,10 @@ packages: resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==} dev: true + /sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + dev: true + /scheduler@0.25.0: resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} dev: true @@ -8689,6 +8709,12 @@ packages: engines: {node: '>=4.0'} dev: true + /xmldoc@1.3.0: + resolution: {integrity: sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==} + dependencies: + sax: 1.4.1 + dev: true + /xunit-viewer@10.6.1(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0): resolution: {integrity: sha512-ZMprLPVhCQJf2KD56tv2hlOjc4T+KnUe1E9DkEBHnuliOq7IOXWJf61pxyBMo/7H83B7Ln0DIeWNMMbx/3I7Jg==} hasBin: true diff --git a/src/components/FilterItemForm.vue b/src/components/FilterItemForm.vue index cacfde1b39a..cca8d80c3ef 100644 --- a/src/components/FilterItemForm.vue +++ b/src/components/FilterItemForm.vue @@ -188,7 +188,7 @@ const selectItem = ({ id }) => { > diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue index c522d026960..4aad327b246 100644 --- a/src/components/FilterTravelForm.vue +++ b/src/components/FilterTravelForm.vue @@ -196,7 +196,7 @@ const selectTravel = ({ id }) => { > diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index 9a994949943..8e83bf5790f 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -77,6 +77,7 @@ watch( function findMatches(search, item) { const matches = []; function findRoute(search, item) { + if (!item?.children) return; for (const child of item.children) { if (search?.indexOf(child.name) > -1) { matches.push(child); @@ -92,7 +93,7 @@ function findMatches(search, item) { } function addChildren(module, route, parent) { - const menus = route?.meta?.menu ?? route?.menus?.[props.source]; //backwards compatible + const menus = route?.meta?.menu; if (!menus) return; const matches = findMatches(menus, route); @@ -107,11 +108,7 @@ function getRoutes() { main: getMainRoutes, card: getCardRoutes, }; - try { - handleRoutes[props.source](); - } catch (error) { - throw new Error(`Method is not defined`); - } + handleRoutes[props.source](); } function getMainRoutes() { const modules = Object.assign([], navigation.getModules().value); @@ -122,7 +119,6 @@ function getMainRoutes() { ); if (!moduleDef) continue; item.children = []; - addChildren(item.module, moduleDef, item.children); } @@ -132,21 +128,16 @@ function getMainRoutes() { function getCardRoutes() { const currentRoute = route.matched[1]; const currentModule = toLowerCamel(currentRoute.name); - let moduleDef = routes.find((route) => toLowerCamel(route.name) === currentModule); + let moduleDef; - if (!moduleDef) return; - if (!moduleDef?.menus) moduleDef = betaGetRoutes(); - addChildren(currentModule, moduleDef, items.value); -} - -function betaGetRoutes() { - let menuRoute; let index = route.matched.length - 1; - while (!menuRoute && index > 0) { - if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index]; + while (!moduleDef && index > 0) { + if (route.matched[index]?.meta?.menu) moduleDef = route.matched[index]; index--; } - return menuRoute; + + if (!moduleDef) return; + addChildren(currentModule, moduleDef, items.value); } async function togglePinned(item, event) { diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue index 255bea9cd68..59be9503594 100644 --- a/src/components/TicketProblems.vue +++ b/src/components/TicketProblems.vue @@ -28,6 +28,17 @@ defineProps({ row: { type: Object, required: true } }); {{ t('ticketSale.reserved') }} + + + {{ t('Ticket deleted') }} + + { :row-index="index" > diff --git a/src/components/__tests__/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js index 4ab8b527fdf..0bcc587ac4c 100644 --- a/src/components/__tests__/Leftmenu.spec.js +++ b/src/components/__tests__/Leftmenu.spec.js @@ -15,10 +15,7 @@ vi.mock('src/router/modules', () => ({ meta: { title: 'customers', icon: 'vn:client', - }, - menus: { - main: ['CustomerList', 'CustomerCreate'], - card: ['CustomerBasicData'], + menu: ['CustomerList', 'CustomerCreate'], }, children: [ { @@ -50,14 +47,6 @@ vi.mock('src/router/modules', () => ({ ], }, }, - { - path: 'create', - name: 'CustomerCreate', - meta: { - title: 'createCustomer', - icon: 'vn:addperson', - }, - }, ], }, ], @@ -98,7 +87,7 @@ vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ icon: 'vn:client', moduleName: 'Customer', keyBinding: 'c', - menu: 'customer', + menu: ['customer'], }, }, ], @@ -260,15 +249,6 @@ describe('Leftmenu as main', () => { }); }); - it('should handle a single matched route with a menu', () => { - const route = { - matched: [{ meta: { menu: 'customer' } }], - }; - - const result = vm.betaGetRoutes(); - - expect(result.meta.menu).toEqual(route.matched[0].meta.menu); - }); it('should get routes for main source', () => { vm.props.source = 'main'; vm.getRoutes(); @@ -351,8 +331,9 @@ describe('addChildren', () => { it('should handle routes with no meta menu', () => { const route = { - meta: {}, - menus: {}, + meta: { + menu: [], + }, }; const parent = []; diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index d6b525dc86b..93e3a57f21f 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -54,7 +54,7 @@ const $props = defineProps({ default: 'table', }, redirect: { - type: Boolean, + type: [String, Boolean], default: true, }, arrayData: { diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index eb0804af0c0..6ce28254d34 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -186,7 +186,7 @@ function fetchData([data]) { ref="vnPaginateRef" class="show" v-bind="$attrs" - search-url="notes" + :search-url="false" @on-fetch=" newNote.text = ''; newNote.observationTypeFk = null; diff --git a/src/composables/getColAlign.js b/src/composables/getColAlign.js index a930fd7d86c..c1841e13447 100644 --- a/src/composables/getColAlign.js +++ b/src/composables/getColAlign.js @@ -9,6 +9,8 @@ export function getColAlign(col) { case 'number': align = 'right'; break; + case 'time': + case 'date': case 'checkbox': align = 'center'; break; diff --git a/src/css/app.scss b/src/css/app.scss index b8b53a929b6..5befd150b0d 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -15,6 +15,7 @@ body.body--light { --vn-empty-tag: #acacac; --vn-black-text-color: black; --vn-text-color-contrast: white; + --vn-link-color: #1e90ff; background-color: var(--vn-page-color); @@ -38,6 +39,7 @@ body.body--dark { --vn-empty-tag: #2d2d2d; --vn-black-text-color: black; --vn-text-color-contrast: black; + --vn-link-color: #66bfff; background-color: var(--vn-page-color); @@ -49,7 +51,7 @@ a { } .link { - color: $color-link; + color: var(--vn-link-color); cursor: pointer; &--white { @@ -58,14 +60,14 @@ a { } .tx-color-link { - color: $color-link !important; + color: var(--vn-link-color) !important; } .tx-color-font { - color: $color-link !important; + color: var(--vn-link-color) !important; } .header-link { - color: $color-link !important; + color: var(--vn-link-color) !important; cursor: pointer; border-bottom: solid $primary; border-width: 2px; diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss index 22c6d2b56d3..45d18af7e0e 100644 --- a/src/css/quasar.variables.scss +++ b/src/css/quasar.variables.scss @@ -24,7 +24,6 @@ $alert: $negative; $white: #fff; $dark: #3d3d3d; // custom -$color-link: #66bfff; $color-spacer-light: #a3a3a31f; $color-spacer: #7979794d; $border-thin-light: 1px solid $color-spacer-light; diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index d7187371e4f..c1286267c7e 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -99,7 +99,6 @@ globals: file: File selectFile: Select a file copyClipboard: Copy on clipboard - salesPerson: SalesPerson send: Send code: Code since: Since @@ -158,7 +157,9 @@ globals: changeState: Change state raid: 'Raid {daysInForward} days' isVies: Vies + department: Department noData: No data available + vehicle: Vehicle pageTitles: logIn: Login addressEdit: Update address @@ -346,7 +347,6 @@ globals: params: description: Description clientFk: Client id - salesPersonFk: Sales person warehouseFk: Warehouse provinceFk: Province stateFk: State @@ -531,6 +531,7 @@ ticket: customerCard: Customer card ticketList: Ticket List newOrder: New Order + ticketClaimed: Claimed ticket boxing: expedition: Expedition created: Created @@ -603,7 +604,6 @@ worker: balance: Balance medical: Medical list: - department: Department schedule: Schedule newWorker: New worker summary: @@ -862,7 +862,6 @@ components: mine: For me hasMinPrice: Minimum price # LatestBuysFilter - salesPersonFk: Buyer supplierFk: Supplier from: From to: To diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index fc3018f3977..681781d1137 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -103,7 +103,6 @@ globals: file: Fichero selectFile: Seleccione un fichero copyClipboard: Copiar en portapapeles - salesPerson: Comercial send: Enviar code: Código since: Desde @@ -163,6 +162,8 @@ globals: raid: 'Redada {daysInForward} días' isVies: Vies noData: Datos no disponibles + department: Departamento + vehicle: Vehículo pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario @@ -349,7 +350,6 @@ globals: params: description: Descripción clientFk: Id cliente - salesPersonFk: Comercial warehouseFk: Almacén provinceFk: Provincia stateFk: Estado @@ -531,13 +531,13 @@ ticket: state: Estado shipped: Enviado landed: Entregado - salesPerson: Comercial total: Total card: customerId: ID cliente customerCard: Ficha del cliente ticketList: Listado de tickets newOrder: Nuevo pedido + ticketClaimed: Ticket reclamado boxing: expedition: Expedición created: Creado @@ -622,8 +622,6 @@ invoiceOut: errors: downloadCsvFailed: Error al descargar CSV order: - field: - salesPersonFk: Comercial form: clientFk: Cliente addressFk: Dirección @@ -691,7 +689,6 @@ worker: formation: Formación medical: Mutua list: - department: Departamento schedule: Horario newWorker: Nuevo trabajador summary: @@ -949,7 +946,6 @@ components: hasMinPrice: Precio mínimo wareHouseFk: Almacén # LatestBuysFilter - salesPersonFk: Comprador supplierFk: Proveedor visible: Visible active: Activo diff --git a/src/pages/Account/Alias/Card/AliasSummary.vue b/src/pages/Account/Alias/Card/AliasSummary.vue index b4b9abd25a0..cfd33ec82ea 100644 --- a/src/pages/Account/Alias/Card/AliasSummary.vue +++ b/src/pages/Account/Alias/Card/AliasSummary.vue @@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n'; import CardSummary from 'components/ui/CardSummary.vue'; import VnLv from 'src/components/ui/VnLv.vue'; +import VnTitle from 'src/components/common/VnTitle.vue'; const route = useRoute(); const { t } = useI18n(); @@ -27,13 +28,10 @@ const entityId = computed(() => $props.id || route.params.id);