From 4f63307c7ee514c4ed6a9ed7fd19bf465d75c99d Mon Sep 17 00:00:00 2001 From: provira <provira@verdnatura.es> 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 f64f23ec83e..1ad06a4f662 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 8b7152ca43a..a4f2146c0a0 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 <provira@verdnatura.es> 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 95620ebfd75..7188ebeb61f 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" /> - <VnLv :label="t('parking.row')" :value="entity.row" /> - <VnLv :label="t('parking.column')" :value="entity.column" /> </QCard> </template> </CardSummary> diff --git a/src/pages/Shelving/Parking/ParkingList.vue b/src/pages/Shelving/Parking/ParkingList.vue index fe6c93ba538..0f56d54c05d 100644 --- a/src/pages/Shelving/Parking/ParkingList.vue +++ b/src/pages/Shelving/Parking/ParkingList.vue @@ -1,19 +1,17 @@ <script setup> -import { onMounted, onUnmounted } from 'vue'; +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'; -import VnPaginate from 'components/ui/VnPaginate.vue'; -import CardList from 'components/ui/CardList.vue'; -import VnLv from 'components/ui/VnLv.vue'; -import ParkingFilter from './ParkingFilter.vue'; -import ParkingSummary from './Card/ParkingSummary.vue'; -import exprBuilder from './ParkingExprBuilder.js'; +import VnTable from 'components/VnTable/VnTable.vue'; import VnSection from 'src/components/common/VnSection.vue'; +import ParkingFilter from './ParkingFilter.vue'; +import exprBuilder from './ParkingExprBuilder.js'; +import ParkingSummary from './Card/ParkingSummary.vue'; const stateStore = useStateStore(); -const { push } = useRouter(); +const router = useRouter(); const { t } = useI18n(); const { viewSummary } = useSummaryDialog(); const dataKey = 'ParkingList'; @@ -24,7 +22,35 @@ onUnmounted(() => (stateStore.rightDrawer = false)); const filter = { fields: ['id', 'sectorFk', 'code', 'pickingOrder'], }; + +const columns = computed(() => [ + { + align: 'left', + name: 'code', + label: t('globals.code'), + isId: true, + isTitle: true, + columnFilter: false, + sortable: true, + }, + { + align: 'left', + name: 'sector', + label: t('parking.sector'), + format: (val) => val.sector.description ?? '', + sortable: true, + cardVisible: true, + }, + { + align: 'left', + name: 'pickingOrder', + label: t('parking.pickingOrder'), + sortable: true, + cardVisible: true, + }, +]); </script> + <template> <VnSection :data-key="dataKey" @@ -40,41 +66,24 @@ const filter = { <ParkingFilter data-key="ParkingList" /> </template> <template #body> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate :data-key="dataKey"> - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :key="row.id" - :id="row.id" - :title="row.code" - @click=" - push({ path: `/shelving/parking/${row.id}/summary` }) - " - > - <template #list-items> - <VnLv - label="Sector" - :value="row.sector?.description" - /> - <VnLv - :label="t('parking.pickingOrder')" - :value="row.pickingOrder" - /> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, ParkingSummary)" - color="primary" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - </QPage> + <VnTable + :data-key="dataKey" + :columns="columns" + is-editable="false" + :right-search="false" + :use-model="true" + :disable-option="{ table: true }" + redirect="shelving/parking" + default-mode="card" + > + <template #actions="{ row }"> + <QBtn + :label="t('components.smartCard.openSummary')" + @click.stop="viewSummary(row.id, ParkingSummary)" + color="primary" + /> + </template> + </VnTable> </template> </VnSection> </template> diff --git a/test/cypress/integration/parking/parkingBasicData.spec.js b/test/cypress/integration/parking/parkingBasicData.spec.js index 1ad06a4f662..b26c2321560 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 a4f2146c0a0..840974744a5 100644 --- a/test/cypress/integration/parking/parkingList.spec.js +++ b/test/cypress/integration/parking/parkingList.spec.js @@ -1,11 +1,7 @@ /// <reference types="cypress" /> 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 <provira@verdnatura.es> 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 fcc9dbd24d4..5c3657691a5 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')" /> </VnRow> - <VnRow> - <VnInput v-model="data.row" :label="$t('parking.row')" /> - <VnInput v-model="data.column" :label="$t('parking.column')" /> - </VnRow> <VnRow> <VnSelect v-model="data.sectorFk" diff --git a/src/pages/Shelving/Parking/ParkingList.vue b/src/pages/Shelving/Parking/ParkingList.vue index 0f56d54c05d..7c5058a74c4 100644 --- a/src/pages/Shelving/Parking/ParkingList.vue +++ b/src/pages/Shelving/Parking/ParkingList.vue @@ -1,6 +1,5 @@ <script setup> 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, + }, + ], + }, ]); </script> 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 b26c2321560..e28d7eecab8 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 840974744a5..ecee8aab749 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 <pablone@verdnatura.es> 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 0de3834eadb..e9660e4c229 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 1050101405a..3323ee6cc4f 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; +} </script> <template> - <QDrawer - v-if="$props.rightSearch" - v-model="stateStore.rightDrawer" - side="right" - :width="256" - :overlay="$props.overlay" - > - <QScrollArea class="fit"> + <RightMenu v-if="$props.rightSearch"> + <template #right-panel> <VnTableFilter :data-key="$attrs['data-key']" :columns="columns" @@ -581,8 +601,8 @@ function cardClick(_, row) { <slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" /> </template> </VnTableFilter> - </QScrollArea> - </QDrawer> + </template> + </RightMenu> <CrudModel v-bind="$attrs" :class="$attrs['class'] ?? 'q-px-md'" @@ -591,6 +611,7 @@ function cardClick(_, row) { @on-fetch="(...args) => emit('onFetch', ...args)" :search-url="searchUrl" :disable-infinite-scroll="isTableMode" + :before-save-fn="removeTextValue" @save-changes="reload" :has-sub-toolbar="$props.hasSubToolbar ?? isEditable" :auto-load="hasParams || $attrs['auto-load']" @@ -635,20 +656,13 @@ function cardClick(_, row) { :skip="columnsVisibilitySkipped" /> <QBtnToggle + v-if="!tableModes.some((mode) => mode.disable)" v-model="mode" toggle-color="primary" class="bg-vn-section-color" dense :options="tableModes.filter((mode) => !mode.disable)" /> - - <QBtn - v-if="showRightIcon" - icon="filter_alt" - class="bg-vn-section-color q-ml-sm" - dense - @click="stateStore.toggleRightDrawer()" - /> </template> <template #header-cell="{ col }"> <QTh diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue index 81578c609e1..67333b5bdb2 100644 --- a/src/pages/Entry/Card/EntryBuys.vue +++ b/src/pages/Entry/Card/EntryBuys.vue @@ -639,7 +639,7 @@ onMounted(() => { 'flex-wrap': 'wrap', gap: '16px', position: 'relative', - height: '450px', + height: '500px', }, columnGridStyle: { 'max-width': '50%', @@ -650,7 +650,7 @@ onMounted(() => { :is-editable="editableMode" :without-header="!editableMode" :with-filters="editableMode" - :right-search="true" + :right-search="editableMode" :right-search-icon="true" :row-click="false" :columns="columns" diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 3c96a230286..a9cf2a5e2e2 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -274,7 +274,7 @@ onBeforeMount(async () => { :array-data-props="{ url: 'Entries/filter', order: 'landed DESC', - userFilter: EntryFilter, + userFilter: entryQueryFilter, }" > <template #advanced-menu> diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue index 46bc1a69080..340641e173b 100644 --- a/src/pages/Route/RouteExtendedList.vue +++ b/src/pages/Route/RouteExtendedList.vue @@ -3,7 +3,7 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useQuasar } from 'quasar'; -import { dashIfEmpty, toDate, toHour } from 'src/filters'; +import { toDate, toHour } from 'src/filters'; import { useRouter } from 'vue-router'; import { usePrintService } from 'src/composables/usePrintService'; From fbc2967ba157a28d2f13076297d454a6f7c765ee Mon Sep 17 00:00:00 2001 From: carlossa <carlossa@verdnatura.es> Date: Mon, 24 Feb 2025 14:40:46 +0100 Subject: [PATCH 05/14] fix: workerBasicData --- src/pages/Worker/Card/WorkerBasicData.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue index fcf0f0369e2..cf43412aff5 100644 --- a/src/pages/Worker/Card/WorkerBasicData.vue +++ b/src/pages/Worker/Card/WorkerBasicData.vue @@ -17,6 +17,12 @@ const maritalStatus = [ { code: 'M', name: t('Married') }, { code: 'S', name: t('Single') }, ]; +async function setAdvancedSummary(data) { + const advanced = (await useAdvancedSummary('Workers', data.id)) ?? {}; + Object.assign(form.value.formData, advanced); + await nextTick(); + if (form.value) form.value.hasChanges = false; +} </script> <template> <FetchData @@ -36,13 +42,7 @@ const maritalStatus = [ :url-update="`Workers/${$route.params.id}`" auto-load model="Worker" - @on-fetch=" - async (data) => { - Object.assign(data, (await useAdvancedSummary('Workers', data.id)) ?? {}); - await $nextTick(); - if (form) form.hasChanges = false; - } - " + @on-fetch="setAdvancedSummary" > <template #form="{ data }"> <VnRow> From 7f1be98b742358db329772eabf29908d7b180992 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Mon, 24 Feb 2025 16:20:28 +0100 Subject: [PATCH 06/14] fix: fixed account descriptor menu and created e2e --- src/i18n/locale/en.yml | 1 + src/i18n/locale/es.yml | 1 + .../Account/Card/AccountDescriptorMenu.vue | 5 ++-- .../account/accountDescriptorMenu.spec.js | 24 +++++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/cypress/integration/account/accountDescriptorMenu.spec.js diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 9a60e9da138..9e46c54e36a 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -153,6 +153,7 @@ globals: maxTemperature: Max minTemperature: Min changePass: Change password + setPass: Set password deleteConfirmTitle: Delete selected elements changeState: Change state raid: 'Raid {daysInForward} days' diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 846c442ea51..6e43e0882c3 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -157,6 +157,7 @@ globals: maxTemperature: Máx minTemperature: Mín changePass: Cambiar contraseña + setPass: Establecer contraseña deleteConfirmTitle: Eliminar los elementos seleccionados changeState: Cambiar estado raid: 'Redada {daysInForward} días' diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue index 30584c61f46..95ad7ed63c3 100644 --- a/src/pages/Account/Card/AccountDescriptorMenu.vue +++ b/src/pages/Account/Card/AccountDescriptorMenu.vue @@ -25,12 +25,13 @@ const $props = defineProps({ const { t } = useI18n(); const { hasAccount } = toRefs($props); const { openConfirmationModal } = useVnConfirm(); +const arrayData = useArrayData('Account'); const route = useRoute(); const router = useRouter(); const state = useState(); const user = state.getUser(); const { notify } = useQuasar(); -const account = computed(() => useArrayData('Account').store.data[0]); +const account = computed(() => arrayData.store.data); account.value.hasAccount = hasAccount.value; const entityId = computed(() => +route.params.id); const hasitManagementAccess = ref(); @@ -39,7 +40,7 @@ const isHimself = computed(() => user.value.id === account.value.id); const url = computed(() => isHimself.value ? 'Accounts/change-password' - : `Accounts/${entityId.value}/setPassword` + : `Accounts/${entityId.value}/setPassword`, ); async function updateStatusAccount(active) { diff --git a/test/cypress/integration/account/accountDescriptorMenu.spec.js b/test/cypress/integration/account/accountDescriptorMenu.spec.js new file mode 100644 index 00000000000..67a7d8ef66d --- /dev/null +++ b/test/cypress/integration/account/accountDescriptorMenu.spec.js @@ -0,0 +1,24 @@ +describe('ClaimNotes', () => { + const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list'; + const url = '/#/account/1/summary'; + + it('should see all the account options', () => { + cy.login('itManagement'); + cy.visit(url); + cy.dataCy('descriptor-more-opts').click(); + cy.get(descriptorOptions) + .find('.q-item') + .its('length') + .then((count) => { + cy.log('Número de opciones:', count); + expect(count).to.equal(5); + }); + }); + + it('should not see any option', () => { + cy.login('salesPerson'); + cy.visit(url); + cy.dataCy('descriptor-more-opts').click(); + cy.get(descriptorOptions).should('not.be.visible'); + }); +}); From e4e57127a0c3f1d77bec87ffc5c02f5fa38db7b3 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 25 Feb 2025 13:49:54 +0100 Subject: [PATCH 07/14] fix: add datakey --- src/pages/Worker/Card/WorkerDescriptorProxy.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pages/Worker/Card/WorkerDescriptorProxy.vue b/src/pages/Worker/Card/WorkerDescriptorProxy.vue index a142570f9ca..5f71abbead8 100644 --- a/src/pages/Worker/Card/WorkerDescriptorProxy.vue +++ b/src/pages/Worker/Card/WorkerDescriptorProxy.vue @@ -12,6 +12,11 @@ const $props = defineProps({ <template> <QPopupProxy> - <WorkerDescriptor v-if="$props.id" :id="$props.id" :summary="WorkerSummary" /> + <WorkerDescriptor + v-if="$props.id" + :id="$props.id" + :summary="WorkerSummary" + data-key="WorkerDescriptorProxy" + /> </QPopupProxy> </template> From df62ccee8bb7985d7da8496b6e06eebeaa25f6b4 Mon Sep 17 00:00:00 2001 From: Javier Segarra <jsegarra@verdnatura.es> Date: Tue, 25 Feb 2025 13:50:07 +0100 Subject: [PATCH 08/14] feat: detect when is descriptor proxy --- src/components/ui/CardDescriptor.vue | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue index e6e7e6fa0f1..8ed1fa0fa73 100644 --- a/src/components/ui/CardDescriptor.vue +++ b/src/components/ui/CardDescriptor.vue @@ -76,6 +76,15 @@ onBeforeMount(async () => { ); }); +const routeName = computed(() => { + const DESCRIPTOR_PROXY = 'DescriptorProxy'; + + let name = $props.dataKey; + if ($props.dataKey.includes(DESCRIPTOR_PROXY)) { + name = name.split(DESCRIPTOR_PROXY)[0]; + } + return `${name}Summary`; +}); async function getData() { store.url = $props.url; store.filter = $props.filter ?? {}; @@ -154,9 +163,7 @@ const toModule = computed(() => {{ t('components.smartCard.openSummary') }} </QTooltip> </QBtn> - <RouterLink - :to="{ name: `${dataKey}Summary`, params: { id: entity.id } }" - > + <RouterLink :to="{ name: routeName, params: { id: entity.id } }"> <QBtn class="link" color="white" From 6525e8907f06067672bbec0a0d7d21d94ec61fa6 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 07:37:12 +0100 Subject: [PATCH 09/14] refactor: remove unused variables --- src/components/VnTable/VnTable.vue | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 721927018c9..c1e541abb78 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -32,7 +32,6 @@ 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({ @@ -52,10 +51,6 @@ const $props = defineProps({ type: Boolean, default: true, }, - rightSearchIcon: { - type: Boolean, - default: true, - }, rowClick: { type: [Function, Boolean], default: null, @@ -167,7 +162,6 @@ const app = inject('app'); const editingRow = ref(null); const editingField = ref(null); const isTableMode = computed(() => mode.value == TABLE_MODE); -const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon); const selectRegex = /select/; const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']); const tableModes = [ From 4593fda04ef29a1767ee84ec28cc6557bb2a89a1 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 09:37:29 +0100 Subject: [PATCH 10/14] test: skip workerCreate e2e --- test/cypress/integration/worker/workerCreate.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/worker/workerCreate.spec.js b/test/cypress/integration/worker/workerCreate.spec.js index 71fd6b347e7..6349f04a0e7 100644 --- a/test/cypress/integration/worker/workerCreate.spec.js +++ b/test/cypress/integration/worker/workerCreate.spec.js @@ -1,4 +1,4 @@ -describe('WorkerCreate', () => { +describe.skip('WorkerCreate', () => { const externalRadio = '.q-radio:nth-child(2)'; const developerBossId = 120; const payMethodCross = From 4d80d72c90c2edc12e880d302a4a33d1cf92d72b Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 10:02:12 +0100 Subject: [PATCH 11/14] fix: update docker-compose command to remove volumes on teardown --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8efc2f8801a..341fffefa4c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -122,7 +122,7 @@ pipeline { } post { always { - sh "docker-compose ${env.COMPOSE_PARAMS} down" + sh "docker-compose ${env.COMPOSE_PARAMS} down -v" junit( testResults: 'junit/e2e.xml', allowEmptyResults: true From ad267ed1322396582cbb1c5c7d2dd55cabb28089 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 10:26:41 +0100 Subject: [PATCH 12/14] test: skip clientList e2e --- test/cypress/integration/client/clientList.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js index f2e3671baae..7572ea4170f 100644 --- a/test/cypress/integration/client/clientList.spec.js +++ b/test/cypress/integration/client/clientList.spec.js @@ -1,5 +1,5 @@ /// <reference types="cypress" /> -describe('Client list', () => { +describe.skip('Client list', () => { beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); From ce30276c73976e9e748c4b4f6e929340131f67f5 Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 10:27:34 +0100 Subject: [PATCH 13/14] test: skip clientList e2e --- test/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index bc8158b626b..6b6ebd426ee 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -112,7 +112,7 @@ function selectItem(selector, option, ariaControl, hasWrite = true) { .find((item) => item.innerText.includes(option)); if (matchingItem) return cy.wrap(matchingItem).click(); - if (hasWrite) cy.get(selector).clear().type(option, { delay: 0 }); + if (hasWrite) cy.get(selector).clear().type(option); return selectItem(selector, option, ariaControl, false); }); } From 60dfda5921b8c842d42dd13cdeaaeba34c99909b Mon Sep 17 00:00:00 2001 From: alexm <alexm@verdnatura.es> Date: Wed, 26 Feb 2025 10:30:17 +0100 Subject: [PATCH 14/14] fix: revert cypress.config --- cypress.config.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index 368b92d8d26..dfe963a1294 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -31,6 +31,7 @@ export default defineConfig({ requestTimeout: 10000, responseTimeout: 30000, pageLoadTimeout: 60000, + defaultBrowser: 'chromium', fixturesFolder: 'test/cypress/fixtures', screenshotsFolder: 'test/cypress/screenshots', supportFile: 'test/cypress/support/index.js', @@ -38,17 +39,10 @@ export default defineConfig({ downloadsFolder: 'test/cypress/downloads', video: false, specPattern: 'test/cypress/integration/**/*.spec.js', - experimentalRunAllSpecs: false, - watchForFileChanges: false, - reporter: 'cypress-mochawesome-reporter', - reporterOptions: { - charts: true, - reportPageTitle: 'Cypress Inline Reporter', - reportFilename: '[status]_[datetime]-report', - embeddedScreenshots: true, - reportDir: 'test/cypress/reports', - inlineAssets: true, - }, + experimentalRunAllSpecs: true, + watchForFileChanges: true, + reporter, + reporterOptions, component: { componentFolder: 'src', testFiles: '**/*.spec.js',