From 4f63307c7ee514c4ed6a9ed7fd19bf465d75c99d Mon Sep 17 00:00:00 2001 From: provira Date: Fri, 14 Feb 2025 10:01:46 +0100 Subject: [PATCH 01/14] fix: refs #8593 fixed parking e2e tests --- .../integration/parking/parkingBasicData.spec.js | 10 +++++----- test/cypress/integration/parking/parkingList.spec.js | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/test/cypress/integration/parking/parkingBasicData.spec.js b/test/cypress/integration/parking/parkingBasicData.spec.js index f64f23ec8..1ad06a4f6 100644 --- a/test/cypress/integration/parking/parkingBasicData.spec.js +++ b/test/cypress/integration/parking/parkingBasicData.spec.js @@ -9,15 +9,15 @@ describe('ParkingBasicData', () => { }); it('should edit the code and sector', () => { - cy.get(sectorSelect).type('Second'); + cy.get(sectorSelect).type('First'); cy.get(sectorOpt).click(); cy.get(codeInput).eq(0).clear(); - cy.get(codeInput).eq(0).type('900-001'); + cy.get(codeInput).eq(0).type('900-002'); cy.saveCard(); - - cy.get(sectorSelect).should('have.value', 'Second sector'); - cy.get(codeInput).should('have.value', '900-001'); + cy.get('.q-notification__message').should('have.text', 'Data saved'); + cy.get(sectorSelect).should('have.value', 'First sector'); + cy.get(codeInput).should('have.value', '900-002'); }); }); diff --git a/test/cypress/integration/parking/parkingList.spec.js b/test/cypress/integration/parking/parkingList.spec.js index 8b7152ca4..a4f2146c0 100644 --- a/test/cypress/integration/parking/parkingList.spec.js +++ b/test/cypress/integration/parking/parkingList.spec.js @@ -30,4 +30,10 @@ describe('ParkingList', () => { cy.get(firstDetailBtn).click(); cy.get(summaryHeader).contains('Basic data'); }); + + it('should filter and redirect to summary if only one result', () => { + cy.dataCy('Code_input').type('A{enter}'); + cy.dataCy('Sector_select').type('First Sector{enter}'); + cy.url().should('match', /\/shelving\/parking\/\d+\/summary/); + }); }); From c49a72e5e541ac95da301a05920ea6306f136368 Mon Sep 17 00:00:00 2001 From: provira Date: Tue, 18 Feb 2025 11:59:20 +0100 Subject: [PATCH 02/14] feat: refs #8593 changed parking to VnTable and modified e2e tests --- .../Shelving/Parking/Card/ParkingSummary.vue | 2 - src/pages/Shelving/Parking/ParkingList.vue | 95 ++++++++++--------- .../parking/parkingBasicData.spec.js | 4 +- .../integration/parking/parkingList.spec.js | 21 ++-- 4 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/pages/Shelving/Parking/Card/ParkingSummary.vue b/src/pages/Shelving/Parking/Card/ParkingSummary.vue index 95620ebfd..7188ebeb6 100644 --- a/src/pages/Shelving/Parking/Card/ParkingSummary.vue +++ b/src/pages/Shelving/Parking/Card/ParkingSummary.vue @@ -45,8 +45,6 @@ const filter = { :label="t('parking.sector')" :value="entity.sector?.description" /> - - diff --git a/src/pages/Shelving/Parking/ParkingList.vue b/src/pages/Shelving/Parking/ParkingList.vue index fe6c93ba5..0f56d54c0 100644 --- a/src/pages/Shelving/Parking/ParkingList.vue +++ b/src/pages/Shelving/Parking/ParkingList.vue @@ -1,19 +1,17 @@ + diff --git a/test/cypress/integration/parking/parkingBasicData.spec.js b/test/cypress/integration/parking/parkingBasicData.spec.js index 1ad06a4f6..b26c23215 100644 --- a/test/cypress/integration/parking/parkingBasicData.spec.js +++ b/test/cypress/integration/parking/parkingBasicData.spec.js @@ -14,10 +14,12 @@ describe('ParkingBasicData', () => { cy.get(codeInput).eq(0).clear(); cy.get(codeInput).eq(0).type('900-002'); + cy.dataCy('Picking order_input').clear().type(80230); cy.saveCard(); cy.get('.q-notification__message').should('have.text', 'Data saved'); - cy.get(sectorSelect).should('have.value', 'First sector'); + cy.get(sectorSelect).should('have.value', 'Second sector'); cy.get(codeInput).should('have.value', '900-002'); + cy.dataCy('Picking order_input').should('have.value', 80230); }); }); diff --git a/test/cypress/integration/parking/parkingList.spec.js b/test/cypress/integration/parking/parkingList.spec.js index a4f2146c0..840974744 100644 --- a/test/cypress/integration/parking/parkingList.spec.js +++ b/test/cypress/integration/parking/parkingList.spec.js @@ -1,11 +1,7 @@ /// describe('ParkingList', () => { const searchbar = '#searchbar input'; - const firstCard = '.q-card:nth-child(1)'; - const firstChipId = - ':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content'; - const firstDetailBtn = - ':nth-child(1) > :nth-child(1) > .card-list-body > .actions > .q-btn'; + const firstCard = ':nth-child(1) > .q-card > .no-margin > .q-py-none'; const summaryHeader = '.summaryBody .header'; beforeEach(() => { @@ -16,18 +12,13 @@ describe('ParkingList', () => { it('should redirect on clicking a parking', () => { cy.get(searchbar).type('{enter}'); - cy.get(firstChipId) - .invoke('text') - .then((content) => { - const id = content.substring(4); - cy.get(firstCard).click(); - cy.url().should('include', `/parking/${id}/summary`); - }); + cy.get(firstCard).click(); + cy.get(summaryHeader).contains('Basic data'); }); - it('should open the details', () => { - cy.get(searchbar).type('{enter}'); - cy.get(firstDetailBtn).click(); + it('should filter and redirect if there is only one result', () => { + cy.dataCy('Code_input').type('01{enter}'); + cy.dataCy('Sector_select').type('First{enter}'); cy.get(summaryHeader).contains('Basic data'); }); From 8f2e42ecbb554fc2aa258e51cd92b7aaf3ff2d86 Mon Sep 17 00:00:00 2001 From: provira Date: Fri, 21 Feb 2025 13:04:49 +0100 Subject: [PATCH 03/14] feat: refs #8593 added summary button & modified e2e tests --- .../Shelving/Parking/Card/ParkingBasicData.vue | 4 ---- src/pages/Shelving/Parking/ParkingList.vue | 15 +++++++++++++-- .../parking/parkingBasicData.spec.js | 13 ++++++++++--- .../{ => shelving}/parking/parkingList.spec.js | 4 ++-- 4 files changed, 25 insertions(+), 11 deletions(-) rename test/cypress/integration/{ => shelving}/parking/parkingBasicData.spec.js (61%) rename test/cypress/integration/{ => shelving}/parking/parkingList.spec.js (90%) diff --git a/src/pages/Shelving/Parking/Card/ParkingBasicData.vue b/src/pages/Shelving/Parking/Card/ParkingBasicData.vue index fcc9dbd24..5c3657691 100644 --- a/src/pages/Shelving/Parking/Card/ParkingBasicData.vue +++ b/src/pages/Shelving/Parking/Card/ParkingBasicData.vue @@ -26,10 +26,6 @@ const sectorFilter = { fields: ['id', 'description'] }; :label="$t('parking.pickingOrder')" /> - - - - import { computed, onMounted, onUnmounted } from 'vue'; -import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useStateStore } from 'stores/useStateStore'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; @@ -11,7 +10,6 @@ import exprBuilder from './ParkingExprBuilder.js'; import ParkingSummary from './Card/ParkingSummary.vue'; const stateStore = useStateStore(); -const router = useRouter(); const { t } = useI18n(); const { viewSummary } = useSummaryDialog(); const dataKey = 'ParkingList'; @@ -48,6 +46,19 @@ const columns = computed(() => [ sortable: true, cardVisible: true, }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('components.smartCard.viewSummary'), + icon: 'preview', + action: (row) => viewSummary(row.id, ParkingSummary), + isPrimary: true, + }, + ], + }, ]); diff --git a/test/cypress/integration/parking/parkingBasicData.spec.js b/test/cypress/integration/shelving/parking/parkingBasicData.spec.js similarity index 61% rename from test/cypress/integration/parking/parkingBasicData.spec.js rename to test/cypress/integration/shelving/parking/parkingBasicData.spec.js index b26c23215..e28d7eeca 100644 --- a/test/cypress/integration/parking/parkingBasicData.spec.js +++ b/test/cypress/integration/shelving/parking/parkingBasicData.spec.js @@ -8,18 +8,25 @@ describe('ParkingBasicData', () => { cy.visit(`/#/shelving/parking/1/basic-data`); }); + it('should give an error if the code aldready exists', () => { + cy.get(codeInput).eq(0).should('have.value', '700-01').clear(); + cy.get(codeInput).eq(0).type('700-02'); + cy.saveCard(); + cy.get('.q-notification__message').should('have.text', 'The code already exists'); + }); + it('should edit the code and sector', () => { cy.get(sectorSelect).type('First'); cy.get(sectorOpt).click(); cy.get(codeInput).eq(0).clear(); - cy.get(codeInput).eq(0).type('900-002'); + cy.get(codeInput).eq(0).type('700-01'); cy.dataCy('Picking order_input').clear().type(80230); cy.saveCard(); cy.get('.q-notification__message').should('have.text', 'Data saved'); - cy.get(sectorSelect).should('have.value', 'Second sector'); - cy.get(codeInput).should('have.value', '900-002'); + cy.get(sectorSelect).should('have.value', 'First sector'); + cy.get(codeInput).should('have.value', '700-01'); cy.dataCy('Picking order_input').should('have.value', 80230); }); }); diff --git a/test/cypress/integration/parking/parkingList.spec.js b/test/cypress/integration/shelving/parking/parkingList.spec.js similarity index 90% rename from test/cypress/integration/parking/parkingList.spec.js rename to test/cypress/integration/shelving/parking/parkingList.spec.js index 840974744..ecee8aab7 100644 --- a/test/cypress/integration/parking/parkingList.spec.js +++ b/test/cypress/integration/shelving/parking/parkingList.spec.js @@ -17,8 +17,8 @@ describe('ParkingList', () => { }); it('should filter and redirect if there is only one result', () => { - cy.dataCy('Code_input').type('01{enter}'); - cy.dataCy('Sector_select').type('First{enter}'); + cy.dataCy('Code_input').type('1{enter}'); + cy.dataCy('Sector_select').type('Normal{enter}'); cy.get(summaryHeader).contains('Basic data'); }); From 4354fc22937085e90a5a63f0e72aa8f1d6be48f8 Mon Sep 17 00:00:00 2001 From: pablone Date: Mon, 24 Feb 2025 13:48:19 +0100 Subject: [PATCH 04/14] refactor: refs #6897 update VnTable components for improved value handling and UI adjustments --- src/components/VnTable/VnFilter.vue | 1 - src/components/VnTable/VnTable.vue | 74 ++++++++++++++++----------- src/pages/Entry/Card/EntryBuys.vue | 4 +- src/pages/Entry/EntryList.vue | 2 +- src/pages/Route/RouteExtendedList.vue | 2 +- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue index 0de3834ea..e9660e4c2 100644 --- a/src/components/VnTable/VnFilter.vue +++ b/src/components/VnTable/VnFilter.vue @@ -91,7 +91,6 @@ const components = { event: updateEvent, attrs: { ...defaultAttrs, - style: 'min-width: 150px', }, forceAttrs, }, diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 105010140..3323ee6cc 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -31,6 +31,8 @@ import VnLv from 'components/ui/VnLv.vue'; import VnTableOrder from 'src/components/VnTable/VnOrder.vue'; import VnTableFilter from './VnTableFilter.vue'; import { getColAlign } from 'src/composables/getColAlign'; +import RightMenu from '../common/RightMenu.vue'; +import { QItemSection } from 'quasar'; const arrayData = useArrayData(useAttrs()['data-key']); const $props = defineProps({ @@ -414,20 +416,13 @@ async function renderInput(rowId, field, clickedElement) { eventHandlers: { 'update:modelValue': async (value) => { if (isSelect && value) { - row[column.name] = value[column.attrs?.optionValue ?? 'id']; - row[column?.name + 'TextValue'] = - value[column.attrs?.optionLabel ?? 'name']; - await column?.cellEvent?.['update:modelValue']?.( - value, - oldValue, - row, - ); + await updateSelectValue(value, column, row, oldValue); } else row[column.name] = value; await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row); }, keyup: async (event) => { if (event.key === 'Enter') - await destroyInput(rowIndex, field, clickedElement); + await destroyInput(rowId, field, clickedElement); }, keydown: async (event) => { switch (event.key) { @@ -458,6 +453,17 @@ async function renderInput(rowId, field, clickedElement) { node.el?.querySelector('span > div > div').focus(); } +async function updateSelectValue(value, column, row, oldValue) { + row[column.name] = value[column.attrs?.optionValue ?? 'id']; + + row[column?.name + 'VnTableTextValue'] = value[column.attrs?.optionLabel ?? 'name']; + + if (column?.attrs?.find?.label) + row[column?.attrs?.find?.label] = value[column.attrs?.optionLabel ?? 'name']; + + await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row); +} + async function destroyInput(rowIndex, field, clickedElement) { if (!clickedElement) clickedElement = document.querySelector( @@ -520,9 +526,9 @@ function getToggleIcon(value) { } function formatColumnValue(col, row, dashIfEmpty) { - if (col?.format || row[col?.name + 'TextValue']) { - if (selectRegex.test(col?.component) && row[col?.name + 'TextValue']) { - return dashIfEmpty(row[col?.name + 'TextValue']); + if (col?.format || row[col?.name + 'VnTableTextValue']) { + if (selectRegex.test(col?.component) && row[col?.name + 'VnTableTextValue']) { + return dashIfEmpty(row[col?.name + 'VnTableTextValue']); } else { return col.format(row, dashIfEmpty); } @@ -555,19 +561,33 @@ function formatColumnValue(col, row, dashIfEmpty) { } return dashIfEmpty(row[col?.name]); } + function cardClick(_, row) { if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` }); } + +function removeTextValue(data, getChanges) { + let changes = data.updates; + if (!changes) return data; + + for (const change of changes) { + for (const key in change.data) { + if (key.endsWith('VnTableTextValue')) { + delete change.data[key]; + } + } + } + + data.updates = changes.filter((change) => Object.keys(change.data).length > 0); + + if ($attrs?.beforeSaveFn) data = $attrs.beforeSaveFn(data, getChanges); + + return data; +} + - -