refactor: refs #8684 improve styling and accessibility in Item components, add data-cy attributes for testing
gitea/salix-front/pipeline/pr-dev This commit is unstable Details

This commit is contained in:
Pablo Natek 2025-04-27 11:51:54 +02:00
parent 1b660a15de
commit d81b8c7fc3
9 changed files with 56 additions and 16 deletions

View File

@ -42,10 +42,7 @@ const val = computed(() => $props.value);
<div v-if="label || $slots.label" class="label"> <div v-if="label || $slots.label" class="label">
<slot name="label"> <slot name="label">
<QTooltip v-if="tooltip">{{ tooltip }}</QTooltip> <QTooltip v-if="tooltip">{{ tooltip }}</QTooltip>
<span style="color: var(--vn-label-color)"> <span style="color: var(--vn-label-color)"> {{ label }}: </span>
{{ label }}
:</span
>
</slot> </slot>
</div> </div>
<div class="value"> <div class="value">

View File

@ -17,6 +17,8 @@ body.body--light {
--vn-text-color-contrast: white; --vn-text-color-contrast: white;
--vn-link-color: #1e90ff; --vn-link-color: #1e90ff;
--vn-image-background-color: white; --vn-image-background-color: white;
--vn-input-underline-color: #bdbdbd;
--vn-input-icons-color: #797979;
background-color: var(--vn-page-color); background-color: var(--vn-page-color);
@ -42,6 +44,8 @@ body.body--dark {
--vn-text-color-contrast: black; --vn-text-color-contrast: black;
--vn-link-color: #66bfff; --vn-link-color: #66bfff;
--vn-image-background-color: black; --vn-image-background-color: black;
--vn-input-underline-color: #545353;
--vn-input-icons-color: #888787;
background-color: var(--vn-page-color); background-color: var(--vn-page-color);
@ -157,7 +161,6 @@ select:-webkit-autofill {
cursor: pointer; cursor: pointer;
} }
/* Estilo para el asterisco en campos requeridos */
.q-field.required .q-field__label:after { .q-field.required .q-field__label:after {
content: ' *'; content: ' *';
} }
@ -299,10 +302,10 @@ input::-webkit-inner-spin-button {
border-color: var(--vn-page-color); border-color: var(--vn-page-color);
} }
div.q-field__append.q-field__marginal { div.q-field__append.q-field__marginal {
color: red !important; color: var(--vn-input-icons-color) !important;
} }
.q-field__control:before { .q-field__control:before {
border-color: #545353 !important; border-color: var(--vn-input-underline-color) !important;
} }
} }

View File

@ -71,6 +71,7 @@ const onIntrastatCreated = (response, formData) => {
hide-selected hide-selected
map-options map-options
required required
data-cy="itemBasicDataItemType"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -83,11 +84,16 @@ const onIntrastatCreated = (response, formData) => {
</QItem> </QItem>
</template> </template>
</VnSelect> </VnSelect>
<VnInput :label="t('item.basicData.reference')" v-model="data.comment" /> <VnInput
:label="t('item.basicData.reference')"
v-model="data.comment"
data-cy="itemBasicDataReference"
/>
<VnInput <VnInput
:label="t('item.basicData.relevancy')" :label="t('item.basicData.relevancy')"
type="number" type="number"
v-model="data.relevancy" v-model="data.relevancy"
data-cy="itemBasicDataRelevancy"
/> />
</VnRow> </VnRow>
<VnRow class="q-py-sm"> <VnRow class="q-py-sm">
@ -95,11 +101,13 @@ const onIntrastatCreated = (response, formData) => {
:label="t('item.basicData.stems')" :label="t('item.basicData.stems')"
type="number" type="number"
v-model="data.stems" v-model="data.stems"
data-cy="itemBasicDataStems"
/> />
<VnInput <VnInput
:label="t('item.basicData.multiplier')" :label="t('item.basicData.multiplier')"
type="number" type="number"
v-model="data.stemMultiplier" v-model="data.stemMultiplier"
data-cy="itemBasicDataMultiplier"
/> />
<VnSelectDialog <VnSelectDialog
:label="t('item.basicData.generic')" :label="t('item.basicData.generic')"
@ -112,6 +120,7 @@ const onIntrastatCreated = (response, formData) => {
map-options map-options
hide-selected hide-selected
action-icon="filter_alt" action-icon="filter_alt"
data-cy="itemBasicDataGeneric"
> >
<template #form> <template #form>
<FilterItemForm <FilterItemForm
@ -133,6 +142,7 @@ const onIntrastatCreated = (response, formData) => {
<VnCheckbox <VnCheckbox
v-model="data.isCustomInspectionRequired" v-model="data.isCustomInspectionRequired"
:label="t('item.basicData.isCustomInspectionRequired')" :label="t('item.basicData.isCustomInspectionRequired')"
data-cy="itemBasicDataCustomInspection"
/> />
<VnSelectDialog <VnSelectDialog
:label="t('item.basicData.intrastat')" :label="t('item.basicData.intrastat')"
@ -142,6 +152,7 @@ const onIntrastatCreated = (response, formData) => {
option-label="description" option-label="description"
map-options map-options
hide-selected hide-selected
data-cy="itemBasicDataIntrastat"
> >
<template #form> <template #form>
<CreateIntrastatForm <CreateIntrastatForm
@ -169,6 +180,7 @@ const onIntrastatCreated = (response, formData) => {
option-label="name" option-label="name"
hide-selected hide-selected
map-options map-options
data-cy="itemBasicDataExpense"
/> />
</div> </div>
</VnRow> </VnRow>
@ -176,35 +188,41 @@ const onIntrastatCreated = (response, formData) => {
<VnCheckbox <VnCheckbox
v-model="data.hasKgPrice" v-model="data.hasKgPrice"
:label="t('item.basicData.hasKgPrice')" :label="t('item.basicData.hasKgPrice')"
data-cy="itemBasicDataHasKgPrice"
/> />
<VnInput <VnInput
:label="t('item.basicData.weightByPiece')" :label="t('item.basicData.weightByPiece')"
v-model.number="data.weightByPiece" v-model.number="data.weightByPiece"
:min="0" :min="0"
type="number" type="number"
data-cy="itemBasicDataWeightByPiece"
/> />
<VnInput <VnInput
:label="t('item.basicData.boxUnits')" :label="t('item.basicData.boxUnits')"
v-model.number="data.packingOut" v-model.number="data.packingOut"
:min="0" :min="0"
type="number" type="number"
data-cy="itemBasicDataBoxUnits"
/> />
</VnRow> </VnRow>
<VnRow class="q-py-sm"> <VnRow class="q-py-sm">
<VnCheckbox <VnCheckbox
v-model="data.isActive" v-model="data.isActive"
:label="t('item.basicData.isActive')" :label="t('item.basicData.isActive')"
data-cy="itemBasicDataIsActive"
/> />
<VnCheckbox <VnCheckbox
v-model="data.isFragile" v-model="data.isFragile"
:label="t('item.basicData.isFragile')" :label="t('item.basicData.isFragile')"
:info="t('item.basicData.isFragileTooltip')" :info="t('item.basicData.isFragileTooltip')"
data-cy="itemBasicDataIsFragile"
/> />
<VnCheckbox <VnCheckbox
v-model="data.isPhotoRequested" v-model="data.isPhotoRequested"
:label="t('item.basicData.isPhotoRequested')" :label="t('item.basicData.isPhotoRequested')"
:info="t('item.basicData.isPhotoRequestedTooltip')" :info="t('item.basicData.isPhotoRequestedTooltip')"
data-cy="itemBasicDataIsPhotoRequested"
/> />
</VnRow> </VnRow>
<VnRow class="q-py-sm"> <VnRow class="q-py-sm">
@ -213,12 +231,14 @@ const onIntrastatCreated = (response, formData) => {
v-model.number="data.recycledPlastic" v-model.number="data.recycledPlastic"
:min="0" :min="0"
type="number" type="number"
data-cy="itemBasicDataRecycledPlastic"
/> />
<VnInput <VnInput
:label="t('item.basicData.nonRecycledPlastic')" :label="t('item.basicData.nonRecycledPlastic')"
v-model.number="data.nonRecycledPlastic" v-model.number="data.nonRecycledPlastic"
:min="0" :min="0"
type="number" type="number"
data-cy="itemBasicDataNonRecycledPlastic"
/> />
</VnRow> </VnRow>
<VnRow class="q-py-sm"> <VnRow class="q-py-sm">
@ -227,12 +247,14 @@ const onIntrastatCreated = (response, formData) => {
type="textarea" type="textarea"
v-model="data.description" v-model="data.description"
fill-input fill-input
data-cy="itemBasicDataDescription"
/> />
<VnInput <VnInput
type="textarea" type="textarea"
:label="t('item.basicData.photoMotivation')" :label="t('item.basicData.photoMotivation')"
v-model="data.photoMotivation" v-model="data.photoMotivation"
fill-input fill-input
data-cy="itemBasicDataPhotoMotivation"
/> />
</VnRow> </VnRow>
</template> </template>

View File

@ -57,7 +57,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`;
:show-edit-button="false" :show-edit-button="false"
/> />
</QCard> </QCard>
<QCard class="vn-three"> <QCard class="vn-two">
<VnTitle <VnTitle
:url="getUrl(entityId, 'basic-data')" :url="getUrl(entityId, 'basic-data')"
:text="t('globals.summary.basicData')" :text="t('globals.summary.basicData')"

View File

@ -155,7 +155,7 @@ item:
isPhotoRequestedTooltip: This item does need a photo isPhotoRequestedTooltip: This item does need a photo
isCustomInspectionRequired: Needs physical inspection (PIF) isCustomInspectionRequired: Needs physical inspection (PIF)
description: Description description: Description
fotoMotivation: Comment for the photographer photoMotivation: Comment for the photographer
fixedPrice: fixedPrice:
itemFk: Item ID itemFk: Item ID
groupingPrice: Grouping price groupingPrice: Grouping price

View File

@ -0,0 +1,21 @@
describe('Item list', () => {
beforeEach(() => {
cy.login('buyer');
cy.visit(`/#/item/1/basic-data`);
});
const mock = {
itemBasicDataItemType: { val: 'Container', type: 'select' },
itemBasicDataReference: '1',
itemBasicDataRelevancy: '1',
itemBasicDataStems: '1',
itemBasicDataMultiplier: '2',
itemBasicDataGeneric: { val: 'Pallet', type: 'select' },
};
it('should edit every field', () => {
cy.fillInForm(mock, { attr: 'data-cy' });
cy.saveCard();
cy.validateForm(mock, { attr: 'data-cy' });
});
});

View File

@ -17,6 +17,7 @@ describe('Item list', () => {
it('should create an item', () => { it('should create an item', () => {
const data = { const data = {
'Provisional name': { val: `Test item` },
Description: { val: `Test item` }, Description: { val: `Test item` },
Type: { val: `Crisantemo`, type: 'select' }, Type: { val: `Crisantemo`, type: 'select' },
Intrastat: { val: `Coral y materiales similares`, type: 'select' }, Intrastat: { val: `Coral y materiales similares`, type: 'select' },

View File

@ -14,11 +14,9 @@ describe('Item summary', () => {
}); });
it('should regularize stock', () => { it('should regularize stock', () => {
cy.dataCy('descriptor-more-opts').click(); cy.selectDescriptorOption();
cy.get('.q-menu > .q-list > :nth-child(1) > .q-item__section').click();
cy.dataCy('regularizeStockInput').type('10'); cy.dataCy('regularizeStockInput').type('10');
cy.dataCy('Warehouse_select').type('Warehouse One{enter}'); cy.dataCy('Warehouse_select').type('Warehouse One{enter}');
cy.dataCy('FormModelPopup_save').click();
cy.checkNotification('Data created'); cy.checkNotification('Data created');
}); });
}); });

View File

@ -194,9 +194,7 @@ Cypress.Commands.add('fillInForm', (obj, opts = {}) => {
cy.selectOption(el, val); cy.selectOption(el, val);
break; break;
case 'date': case 'date':
cy.get(el).type( cy.get(el).type(`{selectall}{backspace}${val}`).blur();
`{selectall}{backspace}${val}`,
).blur();
break; break;
case 'time': case 'time':
cy.get(el).click(); cy.get(el).click();