From 9f8c491eda5518e8dcc4411548c57a000a806e47 Mon Sep 17 00:00:00 2001 From: Jon <jon@verdnatura.es> Date: Thu, 6 Mar 2025 08:07:40 +0100 Subject: [PATCH] refactor: refs #8363 modified ItemFixedPrice and the e2e --- src/components/CrudModel.vue | 1 + src/components/EditTableCellValueForm.vue | 4 +- src/pages/Item/ItemFixedPrice.vue | 527 ++++++++---------- src/pages/Item/ItemFixedPriceFilter.vue | 17 +- .../integration/item/ItemFixedPrice.spec.js | 101 ++-- 5 files changed, 285 insertions(+), 365 deletions(-) diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue index 8c4f70f3b..92244886c 100644 --- a/src/components/CrudModel.vue +++ b/src/components/CrudModel.vue @@ -333,6 +333,7 @@ watch(formUrl, async () => { :disable="!selected?.length" :title="t('globals.remove')" v-if="$props.defaultRemove" + data-cy="crudModelDefaultRemoveBtn" /> <QBtn :label="tMobile('globals.reset')" diff --git a/src/components/EditTableCellValueForm.vue b/src/components/EditTableCellValueForm.vue index 172866191..2197718c1 100644 --- a/src/components/EditTableCellValueForm.vue +++ b/src/components/EditTableCellValueForm.vue @@ -85,14 +85,14 @@ const closeForm = () => { hide-selected option-label="label" v-model="selectedField" - data-cy="field-to-edit" + data-cy="EditFixedPriceSelectOption" /> <component :is="inputs[selectedField?.component || 'input']" v-bind="selectedField?.attrs || {}" v-model="newValue" :label="t('Value')" - data-cy="value-to-edit" + data-cy="EditFixedPriceValueOption" style="width: 200px" /> </VnRow> diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue index fdfa1d3d1..8e647a228 100644 --- a/src/pages/Item/ItemFixedPrice.vue +++ b/src/pages/Item/ItemFixedPrice.vue @@ -1,150 +1,171 @@ <script setup> -import { onMounted, ref, onUnmounted, nextTick, computed } from 'vue'; +import { onMounted, ref, onUnmounted, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -import FetchedTags from 'components/ui/FetchedTags.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import VnInputDate from 'src/components/common/VnInputDate.vue'; -import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue'; -import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; -import { useQuasar } from 'quasar'; -import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; -import { tMobile } from 'src/composables/tMobile'; -import VnConfirm from 'components/ui/VnConfirm.vue'; -import FetchData from 'src/components/FetchData.vue'; -import { useStateStore } from 'stores/useStateStore'; -import { toDate } from 'src/filters'; -import { useVnConfirm } from 'composables/useVnConfirm'; -import { useState } from 'src/composables/useState'; -import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; -import { isLower, isBigger } from 'src/filters/date.js'; +import { useQuasar } from 'quasar'; +import { useStateStore } from 'stores/useStateStore'; +import useNotify from 'src/composables/useNotify.js'; +import FetchedTags from 'components/ui/FetchedTags.vue'; +import VnConfirm from 'components/ui/VnConfirm.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue'; +import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; import VnTable from 'src/components/VnTable/VnTable.vue'; -import { QCheckbox } from 'quasar'; +import VnColor from 'src/components/common/VnColor.vue'; +import VnImg from 'src/components/ui/VnImg.vue'; +import { toDate } from 'src/filters'; +import { isLower, isBigger } from 'src/filters/date.js'; +import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; +import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; const quasar = useQuasar(); const stateStore = useStateStore(); const { t } = useI18n(); -const { openConfirmationModal } = useVnConfirm(); -const state = useState(); const { notify } = useNotify(); const tableRef = ref(); const editTableCellDialogRef = ref(null); -const user = state.getUser(); const fixedPrices = ref([]); -const warehousesOptions = ref([]); -const hasSelectedRows = computed(() => rowsSelected.value.length > 0); -const rowsSelected = ref([]); -const itemFixedPriceFilterRef = ref(); +const selectedRows = ref([]); +const hasSelectedRows = computed(() => selectedRows.value.length > 0); onMounted(async () => { stateStore.rightDrawer = true; }); onUnmounted(() => (stateStore.rightDrawer = false)); -const defaultColumnAttrs = { - align: 'left', - sortable: true, -}; const columns = computed(() => [ { - label: t('item.fixedPrice.itemFk'), - name: 'itemFk', - ...defaultColumnAttrs, - isId: true, + align: 'center', + label: t('lines.image'), + name: 'image', columnField: { - component: 'input', - type: 'number', + component: VnImg, + attrs: ({ row }) => { + return { + id: row.itemFk, + }; + }, }, - columnClass: 'shrink', + width: '45px', + columnFilter: false, }, { + name: 'itemFk', + label: t('item.fixedPrice.itemFk'), + labelAbbreviation: 'ID', + toolTip: t('item.fixedPrice.itemFk'), + component: 'number', + columnFilter: { + inWhere: true, + }, + width: '50px', + }, + { + labelAbbreviation: '', + label: 'Color', + name: 'hex', + columnSearch: false, + isEditable: false, + width: '12px', + component: 'select', + attrs: { + url: 'Inks', + fields: ['id', 'name'], + }, + }, + { + align: 'left', label: t('globals.name'), name: 'name', - ...defaultColumnAttrs, create: true, - columnFilter: { - component: 'select', - attrs: { - url: 'Items', - fields: ['id', 'name', 'subName'], - optionLabel: 'name', - optionValue: 'name', - uppercase: false, - }, + component: 'select', + attrs: { + url: 'Items', + fields: ['id', 'name', 'subName'], + optionLabel: 'name', + optionValue: 'name', + uppercase: false, }, }, { label: t('item.fixedPrice.groupingPrice'), name: 'rate2', - ...defaultColumnAttrs, - component: 'input', - type: 'number', + component: 'number', + create: true, + createOrder: 3, + width: '55px', }, { label: t('item.fixedPrice.packingPrice'), name: 'rate3', - ...defaultColumnAttrs, - component: 'input', - type: 'number', + component: 'number', + create: true, + createOrder: 4, + width: '55px', + }, + { + name: 'hasMinPrice', + label: t('item.fixedPrice.hasMinPrice'), + labelAbbreviation: 'MP', + toolTip: t('item.fixedPrice.hasMinPrice'), + label: t('Has min price'), + component: 'checkbox', + attrs: { + toggleIndeterminate: false, + }, + width: '50px', }, - { label: t('item.fixedPrice.minPrice'), name: 'minPrice', - ...defaultColumnAttrs, - component: 'input', - type: 'number', + component: 'number', + cellEvent: { + 'update:modelValue': async (value, oldValue, row) => { + updateMinPrice(value, row); + }, + }, + width: '55px', + style: (row) => { + if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' }; + }, + format: (row) => parseFloat(row['minPrice']).toFixed(2), }, { label: t('item.fixedPrice.started'), - field: 'started', name: 'started', - format: ({ started }) => toDate(started), - ...defaultColumnAttrs, - columnField: { - component: 'date', - class: 'shrink', - }, + component: 'date', columnFilter: { component: 'date', }, - columnClass: 'expand', + create: true, + createOrder: 5, + width: '70px', }, { label: t('item.fixedPrice.ended'), name: 'ended', - ...defaultColumnAttrs, - columnField: { - component: 'date', - class: 'shrink', - }, + component: 'date', columnFilter: { component: 'date', }, - columnClass: 'expand', - format: (row) => toDate(row.ended), + create: true, + createOrder: 6, + width: '70px', }, - { + align: 'center', label: t('globals.warehouse'), name: 'warehouseFk', - ...defaultColumnAttrs, - columnClass: 'shrink', component: 'select', - options: warehousesOptions, - columnFilter: { - name: 'warehouseFk', - inWhere: true, - component: 'select', - attrs: { - options: warehousesOptions, - 'option-label': 'name', - 'option-value': 'id', - }, + attrs: { + url: 'Warehouses', + fields: ['id', 'name'], + optionLabel: 'name', + optionValue: 'id', }, + create: true, + format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseName), }, { align: 'right', @@ -206,14 +227,6 @@ const editTableFieldsOptions = [ }, }, ]; -const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => { - return inputType === 'text' - ? { - 'keyup.enter': () => upsertPrice(props, resetMinPrice), - blur: () => upsertPrice(props, resetMinPrice), - } - : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) }; -}; const updateMinPrice = async (value, props) => { props.row.hasMinPrice = value; @@ -234,7 +247,7 @@ const validations = ({ row }) => { 'warehouseFk', ]; const isValid = requiredFields.every( - (field) => row[field] !== null && row[field] !== undefined + (field) => row[field] !== null && row[field] !== undefined, ); return isValid; }; @@ -261,59 +274,17 @@ async function upsertFixedPrice(row) { return data; } -function checkLastVisibleRow() { - let lastVisibleRow = null; - - getTableRows().forEach((row, index) => { - const rect = row.getBoundingClientRect(); - if (rect.top >= 0 && rect.bottom <= window.innerHeight) { - lastVisibleRow = index; - } - }); - - return lastVisibleRow; -} - -const addRow = (original = null) => { - let copy = null; - const today = Date.vnNew(); - const millisecsInDay = 86400000; - const daysInWeek = 7; - const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay); - - copy = { - id: 0, - started: today, - ended: nextWeek, - hasMinPrice: 0, - $index: 0, - }; - return { original, copy }; -}; - -const getTableRows = () => - document.getElementsByClassName('q-table')[0].querySelectorAll('tr.cursor-pointer'); - -function highlightNewRow({ $index: index }) { - const row = getTableRows()[index]; - if (row) { - row.classList.add('highlight'); - setTimeout(() => { - row.classList.remove('highlight'); - }, 3000); - } -} const openEditTableCellDialog = () => { editTableCellDialogRef.value.show(); }; const onEditCellDataSaved = async () => { - rowsSelected.value = []; + selectedRows.value = []; tableRef.value.reload(); }; const removeFuturePrice = async () => { - rowsSelected.value.forEach(({ id }) => { + selectedRows.value.forEach(({ id }) => { const rowIndex = fixedPrices.value.findIndex(({ id }) => id === id); removePrice(id, rowIndex); }); @@ -340,46 +311,43 @@ const removePrice = async (id) => { const dateStyle = (date) => date ? { - 'bg-color': 'warning', - 'is-outlined': true, + color: 'var(--vn-black-text-color)', } - : {}; + : { 'background-color': 'transparent' }; -function handleOnDataSave({ CrudModelRef }) { - const { original, copy } = addRow(CrudModelRef.formData[checkLastVisibleRow()]); - if (original) { - CrudModelRef.formData.splice(original?.$index ?? 0, 0, copy); - } else { - CrudModelRef.insert(copy); +async function cloneFixedPrice(rows) { + for (let row of rows) { + let clonedLine = { + itemFk: row.itemFk, + warehouseFk: row.warehouseFk, + rate2: row.rate2, + rate3: row.rate3, + started: row.started, + ended: row.ended, + }; + console.log('clonedLine: ', clonedLine); + await axios.post('FixedPrices', clonedLine); } - nextTick(() => { - highlightNewRow(original ?? { $index: 0 }); - }); } </script> <template> - <FetchData - @on-fetch="(data) => (warehousesOptions = data)" - auto-load - url="Warehouses" - :filter="{ fields: ['id', 'name'], order: 'name ASC' }" - /> <RightMenu> <template #right-panel> - <ItemFixedPriceFilter - data-key="ItemFixedPrices" - ref="itemFixedPriceFilterRef" - /> + <ItemFixedPriceFilter data-key="ItemFixedPrices" /> </template> </RightMenu> - <VnSubToolbar> - <template #st-actions> + <VnSubToolbar /> + <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown()"> + <QBtnGroup push style="column-gap: 10px"> <QBtn :disable="!hasSelectedRows" @click="openEditTableCellDialog()" color="primary" icon="edit" + flat + :label="t('globals.edit')" + data-cy="FixedPriceToolbarEditBtn" > <QTooltip> {{ t('Edit fixed price(s)') }} @@ -387,74 +355,50 @@ function handleOnDataSave({ CrudModelRef }) { </QBtn> <QBtn :disable="!hasSelectedRows" - :label="tMobile('globals.remove')" + @click="cloneFixedPrice(selectedRows)" color="primary" - icon="delete" + icon="vn:clone" flat - @click="(row) => confirmRemove(row, true)" - :title="t('globals.remove')" - /> - </template> - </VnSubToolbar> + :label="t('globals.clone')" + data-cy="FixedPriceToolbarCloneBtn" + > + <QTooltip> + {{ t('Clone fixed price(s)') }} + </QTooltip> + </QBtn> + </QBtnGroup> + </Teleport> <VnTable - :default-remove="false" - :default-reset="false" - :default-save="false" + ref="tableRef" data-key="ItemFixedPrices" url="FixedPrices/filter" - :order="['name DESC', 'itemFk DESC']" + :order="'name DESC'" save-url="FixedPrices/crud" - ref="tableRef" - dense - :filter="{ - where: { - warehouseFk: user.warehouseFk, - }, - }" :columns="columns" - default-mode="table" - auto-load :is-editable="true" :right-search="false" :table="{ 'row-key': 'id', selection: 'multiple', }" - v-model:selected="rowsSelected" - :create-as-dialog="false" + v-model:selected="selectedRows" :create="{ - onDataSaved: handleOnDataSave, + urlCreate: 'FixedPrices', + title: t('Create buy'), + formInitialData: {}, + onDataSaved: () => tableRef.reload(), + showSaveAndContinueBtn: true, }" :disable-option="{ card: true }" - :has-sub-toolbar="false" + auto-load > - <template #header-selection="scope"> - <QCheckbox v-model="scope.selected" /> + <template #column-image="{ row }"> + <div class="image-wrapper"> + <VnImg :id="row.itemFk" class="rounded" /> + </div> </template> - <template #body-selection="scope"> - {{ scope }} - <QCheckbox flat v-model="scope.selected" /> - </template> - - <template #column-itemFk="props"> - <VnSelect - style="max-width: 100px" - url="Items/withName" - hide-selected - option-label="id" - option-value="id" - v-model="props.row.itemFk" - v-on="getRowUpdateInputEvents(props, true, 'select')" - > - <template #option="scope"> - <QItem v-bind="scope.itemProps"> - <QItemSection> - <QItemLabel> #{{ scope.opt?.id }} </QItemLabel> - <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel> - </QItemSection> - </QItem> - </template> - </VnSelect> + <template #column-hex="{ row }"> + <VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" /> </template> <template #column-name="{ row }"> <span class="link"> @@ -462,111 +406,78 @@ function handleOnDataSave({ CrudModelRef }) { </span> <span class="subName">{{ row.subName }}</span> <ItemDescriptorProxy :id="row.itemFk" /> - <FetchedTags :item="row" :columns="3" /> + <FetchedTags :item="row" :columns="6" /> </template> - <template #column-rate2="props"> - <QTd class="col"> - <VnInput - type="currency" - style="width: 75px" - v-model.number="props.row.rate2" - v-on="getRowUpdateInputEvents(props)" - > - <template #append>€</template> - </VnInput> - </QTd> + <template #column-started="{ row }"> + <div class="editable-text q-pb-xxs"> + <QBadge :style="dateStyle(isLower(row?.ended))"> + {{ toDate(row?.started) }} + </QBadge> + </div> </template> - <template #column-rate3="props"> - <QTd class="col"> - <VnInput - style="width: 75px" - type="currency" - v-model.number="props.row.rate3" - v-on="getRowUpdateInputEvents(props)" - > - <template #append>€</template> - </VnInput> - </QTd> + <template #column-ended="{ row }"> + <div class="editable-text q-pb-xxs"> + <QBadge :style="dateStyle(isBigger(row?.ended))"> + {{ toDate(row?.ended) }} + </QBadge> + </div> </template> - <template #column-minPrice="props"> - <QTd class="col"> - <div class="row" style="align-items: center"> - <QCheckbox - :model-value="props.row.hasMinPrice" - @update:model-value="updateMinPrice($event, props)" - :false-value="0" - :true-value="1" - :toggle-indeterminate="false" - /> - <VnInput - class="col" - type="currency" - mask="###.##" - :disable="props.row.hasMinPrice === 0" - v-model.number="props.row.minPrice" - v-on="getRowUpdateInputEvents(props)" - > - <template #append>€</template> - </VnInput> - </div> - </QTd> - </template> - <template #column-started="props"> - <VnInputDate - class="vnInputDate" - :show-event="true" - v-model="props.row.started" - v-on="getRowUpdateInputEvents(props, false, 'date')" - v-bind="dateStyle(isBigger(props.row.started))" - /> - </template> - <template #column-ended="props"> - <VnInputDate - class="vnInputDate" - :show-event="true" - v-model="props.row.ended" - v-on="getRowUpdateInputEvents(props, false, 'date')" - v-bind="dateStyle(isLower(props.row.ended))" - /> - </template> - <template #column-warehouseFk="props"> - <QTd class="col"> - <VnSelect - style="max-width: 150px" - :options="warehousesOptions" - hide-selected - option-label="name" - option-value="id" - v-model="props.row.warehouseFk" - v-on="getRowUpdateInputEvents(props, false, 'select')" - /> - </QTd> - </template> - <template #column-deleteAction="{ row, rowIndex }"> - <QIcon - name="delete" - size="sm" - class="cursor-pointer fill-icon-on-hover" - color="primary" - @click.stop=" - openConfirmationModal( - t('globals.rowWillBeRemoved'), - t('Do you want to clone this item?'), - () => removePrice(row.id, rowIndex) - ) - " + <template #column-create-name="{ data }"> + <VnSelect + url="Items/search" + v-model="data.itemFk" + :label="t('Article')" + :fields="['id', 'name']" + :filter-options="['id', 'name']" + option-label="name" + option-value="id" + :required="true" + sort-by="name ASC" + data-cy="FixedPriceCreateNameSelect" > - <QTooltip class="text-no-wrap"> - {{ t('globals.delete') }} - </QTooltip> - </QIcon> + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt.name }} + </QItemLabel> + <QItemLabel caption> #{{ scope.opt.id }} </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + </template> + <template #column-create-warehouseFk="{ data }"> + <VnSelect + :label="t('globals.warehouse')" + url="Warehouses" + v-model="data.warehouseFk" + :fields="['id', 'name']" + option-label="name" + option-value="id" + hide-selected + :required="true" + sort-by="name ASC" + data-cy="FixedPriceCreateWarehouseSelect" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt.name }} + </QItemLabel> + <QItemLabel caption> #{{ scope.opt.id }} </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> </template> </VnTable> <QDialog ref="editTableCellDialogRef"> <EditTableCellValueForm edit-url="FixedPrices/editFixedPrice" - :rows="rowsSelected" + :rows="selectedRows" :fields-options="editTableFieldsOptions" @on-data-saved="onEditCellDataSaved()" /> diff --git a/src/pages/Item/ItemFixedPriceFilter.vue b/src/pages/Item/ItemFixedPriceFilter.vue index 8d92e245d..7e1adb8bb 100644 --- a/src/pages/Item/ItemFixedPriceFilter.vue +++ b/src/pages/Item/ItemFixedPriceFilter.vue @@ -13,11 +13,14 @@ const props = defineProps({ required: true, }, }); - </script> <template> - <ItemsFilterPanel :data-key="props.dataKey" :custom-tags="['tags']"> + <ItemsFilterPanel + :data-key="props.dataKey" + :search-button="true" + :custom-tags="['tags']" + > <template #body="{ params, searchFn }"> <QItem class="q-my-md"> <QItemSection> @@ -53,23 +56,19 @@ const props = defineProps({ /> </QItemSection> </QItem> - <QItem class="q-my-md"> + <QItem> <QItemSection> <VnInputDate - :label="t('params.started')" v-model="params.started" + :label="t('params.started')" is-outlined - @update:model-value="searchFn()" /> </QItemSection> - </QItem> - <QItem class="q-my-md"> <QItemSection> <VnInputDate - :label="t('params.ended')" v-model="params.ended" + :label="t('params.ended')" is-outlined - @update:model-value="searchFn()" /> </QItemSection> </QItem> diff --git a/test/cypress/integration/item/ItemFixedPrice.spec.js b/test/cypress/integration/item/ItemFixedPrice.spec.js index 2cf9c2caf..2fad87eac 100644 --- a/test/cypress/integration/item/ItemFixedPrice.spec.js +++ b/test/cypress/integration/item/ItemFixedPrice.spec.js @@ -1,10 +1,14 @@ /// <reference types="cypress" /> -function goTo(n = 1) { - return `.q-virtual-scroll__content > :nth-child(${n})`; -} -const firstRow = goTo(); -`.q-virtual-scroll__content > :nth-child(2)`; describe('Handle Items FixedPrice', () => { + const grouping = 'Grouping price'; + const saveEditBtn = '.q-mt-lg > .q-btn--standard'; + const createForm = { + 'Grouping price': { val: '5' }, + 'Packing price': { val: '5' }, + Started: { val: '01-01-2001', type: 'date' }, + Ended: { val: '15-01-2001', type: 'date' }, + }; + beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); @@ -14,50 +18,55 @@ describe('Handle Items FixedPrice', () => { '.q-header > .q-toolbar > :nth-child(1) > .q-btn__content > .q-icon', ).click(); }); - it.skip('filter', function () { + + it('filter by category', () => { cy.get('.category-filter > :nth-child(1) > .q-btn__content > .q-icon').click(); - cy.selectOption('.list > :nth-child(2)', 'Alstroemeria'); - cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click(); - - cy.addBtnClick(); - cy.selectOption(`${firstRow} > :nth-child(2)`, '#13'); - cy.get(`${firstRow} > :nth-child(4)`).find('input').type(1); - cy.get(`${firstRow} > :nth-child(5)`).find('input').type('2'); - cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One'); - cy.get('.q-notification__message').should('have.text', 'Data saved'); - /* ==== End Cypress Studio ==== */ - }); - it.skip('Create and delete ', function () { - cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click(); - cy.addBtnClick(); - cy.selectOption(`${firstRow} > :nth-child(2)`, '#11'); - cy.get(`${firstRow} > :nth-child(4)`).type('1'); - cy.get(`${firstRow} > :nth-child(5)`).type('2'); - cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One'); - cy.get('.q-notification__message').should('have.text', 'Data saved'); - cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click(); - cy.get(`${firstRow} > .text-right > .q-btn > .q-btn__content > .q-icon`).click(); - cy.get( - '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block', - ).click(); - cy.get('.q-notification__message').should('have.text', 'Data saved'); + cy.get('.q-table__middle').should('be.visible').should('have.length', 1); }); - it.skip('Massive edit', function () { - cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click(); - cy.get('#subToolbar > .q-btn--standard').click(); - cy.selectOption("[data-cy='field-to-edit']", 'Min price'); - cy.dataCy('value-to-edit').find('input').type('1'); - cy.get('.countLines').should('have.text', ' 1 '); - cy.get('.q-mt-lg > .q-btn--standard').click(); - cy.get('.q-notification__message').should('have.text', 'Data saved'); + it('should create a new fixed price, then delete it', () => { + cy.dataCy('vnTableCreateBtn').click(); + cy.dataCy('FixedPriceCreateNameSelect').type('Melee weapon combat fist 15cm'); + cy.get('.q-menu .q-item').contains('Melee weapon combat fist 15cm').click(); + cy.dataCy('FixedPriceCreateWarehouseSelect').type('Warehouse One'); + cy.get('.q-menu .q-item').contains('Warehouse One').click(); + cy.get('.q-menu').then(($menu) => { + if ($menu.is(':visible')) { + cy.dataCy('FixedPriceCreateWarehouseSelect').as('focusedElement').focus(); + cy.dataCy('FixedPriceCreateWarehouseSelect').blur(); + } + }); + cy.fillInForm(createForm); + cy.dataCy('FormModelPopup_save').click(); + cy.checkNotification('Data created'); + cy.get('[data-col-field="name"]').each(($el) => { + cy.wrap($el) + .invoke('text') + .then((text) => { + if (text.includes('Melee weapon combat fist 15cm')) { + cy.wrap($el).parent().find('.sticky').click(); + + cy.dataCy('VnConfirm_confirm').click(); + cy.checkNotification('Data saved'); + } + }); + }); }); - it.skip('Massive remove', function () { - cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click(); - cy.get('#subToolbar > .q-btn--flat').click(); - cy.get( - '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block', - ).click(); - cy.get('.q-notification__message').should('have.text', 'Data saved'); + + it('should edit all items', () => { + cy.get('.bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner').click(); + cy.dataCy('FixedPriceToolbarEditBtn').click(); + cy.dataCy('EditFixedPriceSelectOption').type(grouping); + cy.get('.q-menu .q-item').contains(grouping).click(); + cy.dataCy('EditFixedPriceValueOption').type('5'); + cy.get(saveEditBtn).click(); + cy.checkNotification('Data saved'); + }); + + it('should remove all items', () => { + cy.get('.bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner').click(); + cy.dataCy('crudModelDefaultRemoveBtn').click(); + cy.dataCy('VnConfirm_confirm').click(); + cy.checkNotification('Data saved'); }); });