0
0
Fork 0

refs #5673 fix: front, e2e, fix: VnSelectFilter

This commit is contained in:
Alex Moreno 2023-08-23 15:09:03 +02:00
parent 50ae75ac17
commit 169e4863b2
6 changed files with 172 additions and 165 deletions

View File

@ -261,10 +261,6 @@ function isEmpty(obj) {
} }
</script> </script>
<template> <template>
<QBanner v-if="hasChanges" class="text-white bg-warning">
<QIcon name="warning" size="md" class="q-mr-md" />
<span>{{ t('globals.changesToSave') }}</span>
</QBanner>
<VnPaginate <VnPaginate
@submit="onSubmit" @submit="onSubmit"
@reset="reset" @reset="reset"
@ -286,12 +282,13 @@ function isEmpty(obj) {
</VnPaginate> </VnPaginate>
<SkeletonTable v-if="!formData" /> <SkeletonTable v-if="!formData" />
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()"> <Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push flat class="q-gutter-x-sm"> <QBtnGroup push class="q-gutter-x-sm">
<slot name="moreActions" /> <slot name="moreActions" />
<QBtn <QBtn
:label="tMobile('globals.remove')" :label="tMobile('globals.remove')"
color="primary" color="primary"
icon="delete" icon="delete"
flat
@click="remove(selected)" @click="remove(selected)"
:disable="!selected?.length" :disable="!selected?.length"
:title="t('globals.remove')" :title="t('globals.remove')"

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, toRefs } from 'vue'; import { ref, toRefs, computed } from 'vue';
const emit = defineEmits(['update:modelValue', 'update:options']); const emit = defineEmits(['update:modelValue', 'update:options']);
const $props = defineProps({ const $props = defineProps({
@ -16,10 +16,9 @@ const $props = defineProps({
default: '', default: '',
}, },
}); });
const myOptions = computed(() => $props.options);
const updateValue = (newValue) => emit('update:modelValue', newValue); const updateValue = (newValue) => emit('update:modelValue', newValue);
const { modelValue, optionLabel, options } = toRefs($props); const { modelValue, optionLabel, options } = toRefs($props);
const myOptions = ref(JSON.parse(JSON.stringify(options.value)));
const myOptionsOriginal = ref(JSON.parse(JSON.stringify(options.value))); const myOptionsOriginal = ref(JSON.parse(JSON.stringify(options.value)));
const filter = (val, options) => { const filter = (val, options) => {

View File

@ -171,7 +171,7 @@ async function onLoad(...params) {
</QCard> </QCard>
</div> </div>
</div> </div>
<QInfiniteScroll v-if="store.data" @load="onLoad" :offset="offset"> <QInfiniteScroll v-if="store.data" @load="onLoad" :offset="offset" class="full-width">
<slot name="body" :rows="store.data"></slot> <slot name="body" :rows="store.data"></slot>
<div v-if="isLoading" class="info-row q-pa-md text-center"> <div v-if="isLoading" class="info-row q-pa-md text-center">
<QSpinner color="orange" size="md" /> <QSpinner color="orange" size="md" />

View File

@ -121,67 +121,65 @@ const columns = computed(() => [
auto-load auto-load
/> />
<div class="column items-center"> <div class="column items-center">
<div class="list"> <CrudModel
<CrudModel data-key="ClaimDevelopments"
data-key="ClaimDevelopments" url="ClaimDevelopments"
url="ClaimDevelopments" model="claimDevelopment"
model="claimDevelopment" :filter="developmentsFilter"
:filter="developmentsFilter" ref="claimDevelopmentForm"
ref="claimDevelopmentForm" :data-required="{ claimFk: route.params.id }"
:data-required="{ claimFk: route.params.id }" v-model:selected="selected"
v-model:selected="selected" auto-load
auto-load >
> <template #body="{ rows }">
<template #body="{ rows }"> <QTable
<QTable :columns="columns"
:columns="columns" :rows="rows"
:rows="rows" :pagination="{ rowsPerPage: 0 }"
:pagination="{ rowsPerPage: 0 }" row-key="$index"
row-key="$index" selection="multiple"
selection="multiple" hide-pagination
hide-pagination v-model:selected="selected"
v-model:selected="selected" :grid="$q.screen.lt.md"
:grid="$q.screen.lt.md" >
> <template #body-cell="{ row, col }">
<template #body-cell="{ row, col }"> <QTd auto-width>
<QTd auto-width> <VnSelectFilter
<VnSelectFilter :label="col.label"
:label="col.label" v-model="row[col.model]"
v-model="row[col.model]" :options="col.options"
:options="col.options" :option-value="col.optionValue"
:option-value="col.optionValue" :option-label="col.optionLabel"
:option-label="col.optionLabel" />
/> </QTd>
</QTd> </template>
</template> <template #item="props">
<template #item="props"> <div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition"> <QCard bordered flat>
<QCard bordered flat> <QCardSection>
<QCardSection> <QCheckbox v-model="props.selected" dense />
<QCheckbox v-model="props.selected" dense /> </QCardSection>
</QCardSection> <QSeparator />
<QSeparator /> <QList dense>
<QList dense> <QItem v-for="col in props.cols" :key="col.name">
<QItem v-for="col in props.cols" :key="col.name"> <QItemSection>
<QItemSection> <VnSelectFilter
<VnSelectFilter :label="col.label"
:label="col.label" v-model="props.row[col.model]"
v-model="props.row[col.model]" :options="col.options"
:options="col.options" :option-value="col.optionValue"
:option-value="col.optionValue" :option-label="col.optionLabel"
:option-label="col.optionLabel" dense
dense />
/> </QItemSection>
</QItemSection> </QItem>
</QItem> </QList>
</QList> </QCard>
</QCard> </div>
</div> </template>
</template> </QTable>
</QTable> </template>
</template> </CrudModel>
</CrudModel>
</div>
</div> </div>
<QPageSticky position="bottom-right" :offset="[25, 25]"> <QPageSticky position="bottom-right" :offset="[25, 25]">
<QBtn fab color="primary" icon="add" @click="claimDevelopmentForm.insert()" /> <QBtn fab color="primary" icon="add" @click="claimDevelopmentForm.insert()" />
@ -192,6 +190,9 @@ const columns = computed(() => [
.grid-style-transition { .grid-style-transition {
transition: transform 0.28s, background-color 0.28s; transition: transform 0.28s, background-color 0.28s;
} }
.maxwidth {
width: 100%;
}
</style> </style>
<i18n> <i18n>

View File

@ -1,6 +1,8 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('ClaimDevelopment', () => { describe('ClaimDevelopment', () => {
const claimId = 1; const claimId = 1;
const firstLineReason = 'tbody > :nth-child(1) > :nth-child(2)';
const thirdRow = 'tbody > :nth-child(3)';
beforeEach(() => { beforeEach(() => {
cy.viewport(1920, 1080); cy.viewport(1920, 1080);
@ -9,58 +11,46 @@ describe('ClaimDevelopment', () => {
}); });
it('should reset line', () => { it('should reset line', () => {
cy.get('tbody > :nth-child(1) > :nth-child(2)').click(); cy.selectOption(firstLineReason, 'Novato');
cy.selectOption('Novato'); cy.resetCard();
cy.get('[title="Reset"]').click(); cy.getValue(firstLineReason).should('have.text', 'Prisas');
cy.get(
':nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span'
).should('have.text', 'Prisas');
}); });
it('should edit line', () => { it('should edit line', () => {
cy.get('tbody > :nth-child(1) > :nth-child(2)').click(); cy.selectOption(firstLineReason, 'Novato');
cy.selectOption('Novato'); cy.saveCard();
cy.get('[title="Save"]').click();
cy.visit(`/#/claim/${claimId}/development`); cy.reload();
cy.get( cy.getValue(firstLineReason).should('have.text', 'Novato');
':nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span'
).should('have.text', 'Novato');
//Restart data //Restart data
cy.get('tbody > :nth-child(1) > :nth-child(2)'); cy.selectOption(firstLineReason, 'Prisas');
cy.selectOption('Prisas'); cy.saveCard();
cy.get('[title="Save"]').click();
}); });
it('should add new line', () => { it('should add and remove new line', () => {
//check third if row exist //add row
cy.get('.q-page-sticky > div > .q-btn').click(); cy.addCard();
cy.get('tbody > :nth-child(3)').should('exist'); cy.get(thirdRow).should('exist');
//fill in data const rowData = [false, 'Novato', 'Roces', 'Compradores', 'employeeNick', 'Tour'];
const rowData = ['', '', '']; cy.fillRow(thirdRow, rowData);
cy.fillTableRow(3, rowData); cy.saveCard();
cy.validateRow(thirdRow, rowData);
cy.reload();
cy.validateRow(thirdRow, rowData);
//remove row
cy.fillRow(thirdRow, [true]);
cy.removeCard();
cy.clickConfirm();
cy.get(thirdRow).should('not.exist');
cy.reload();
cy.get(thirdRow).should('not.exist');
}); });
// it('should remove last line', () => {
// cy.get(
// ':nth-child(1) > .q-card > .q-img > .q-img__container > .q-img__image'
// ).click();
// cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
// 'be.visible'
// );
// cy.get('.q-carousel__control > .q-btn > .q-btn__content > .q-icon').click();
// cy.get(
// '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon'
// ).click();
// cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should(
// 'not.be.visible'
// );
// });
// it('should remove third and fourth file', () => { // it('should remove third and fourth file', () => {
// cy.get( // cy.get(
// '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' // '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon'

View File

@ -41,70 +41,90 @@ Cypress.Commands.add('login', (user) => {
}); });
}); });
Cypress.Commands.add('selectOption', (option) => { Cypress.Commands.add('waitForElement', (element) => {
//cy.visit('/#/login'); cy.get(element, { timeout: 2000 }).should('be.visible');
cy.get('.q-item__label').then(() => { });
cy.contains('.q-item__label', option).click();
Cypress.Commands.add('getValue', (selector) => {
cy.get(selector).then(($el) => {
if ($el.find('.q-checkbox__inner').length > 0) {
return cy.get(selector + '.q-checkbox__inner');
}
// Si es un QSelect
else if ($el.find('.q-select__dropdown-icon').length) {
return cy.get(
selector +
'> .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span'
);
} else {
// Puedes añadir un log o lanzar un error si el elemento no es reconocido
cy.log('Elemento no soportado');
}
}); });
}); });
// Cypress.Commands.add('fillRow', (row, options) => { // Fill Inputs
// //cy.visit('/#/login'); Cypress.Commands.add('selectOption', (selector, option) => {
// for (let [i, option] of options.entries()) { cy.get(selector).find('.q-select__dropdown-icon').click();
// i++; cy.get('.q-menu .q-item').contains(option).click();
// console.log(i); });
// const selector = `tbody > :nth-child(${row}) > :nth-child(${i})`;
// if (cy.get(selector).should('have.class', 'q-select')) Cypress.Commands.add('checkOption', (selector) => {
// cy.selectOption(selector, option); cy.wrap(selector).find('.q-checkbox__inner').click();
// } });
// });
Cypress.Commands.add('fillTableRow', (rowNumber, data) => { // Global buttons
// Obtener todas las filas de la tabla Cypress.Commands.add('saveCard', () => {
cy.get('table tbody tr').eq(rowNumber).as('currentRow'); cy.get('[title="Save"]').click();
cy.get('[title="Save"]').should('have.class', 'disabled');
});
Cypress.Commands.add('resetCard', () => {
cy.get('[title="Reset"]').click();
});
Cypress.Commands.add('removeCard', () => {
cy.get('[title="Remove"]').click();
});
Cypress.Commands.add('addCard', () => {
cy.waitForElement('tbody');
cy.get('.q-page-sticky > div > .q-btn').click();
});
Cypress.Commands.add('clickConfirm', () => {
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
});
Cypress.Commands.add('fillRow', (rowSelector, data) => {
// Usar el selector proporcionado para obtener la fila deseada
cy.waitForElement('tbody');
cy.get(rowSelector).as('currentRow');
// Iterar sobre cada dato en el array 'data'
data.forEach((value, index) => { data.forEach((value, index) => {
// Basándonos en el índice, encontramos la celda correspondiente y verificamos el tipo de input if (value === null) return;
cy.get('@currentRow') cy.get('@currentRow')
.find('td') .find('td')
.eq(index) .eq(index)
.find('input') .then((td) => {
.invoke('attr', 'type') if (td.find('.q-select__dropdown-icon').length) {
.then((type) => { cy.selectOption(td, value);
switch (type) { }
case 'text': if (td.find('.q-checkbox__inner').length && value) {
cy.get('@currentRow') cy.checkOption(td);
.find('td')
.eq(index)
.find('input[type="text"]')
.clear()
.type(value);
break;
case 'checkbox':
if (value) {
// Puede adaptar esto según cómo represente los valores booleanos en su array 'data'
cy.get('@currentRow')
.find('td')
.eq(index)
.find('input[type="checkbox"]')
.check();
} else {
cy.get('@currentRow')
.find('td')
.eq(index)
.find('input[type="checkbox"]')
.uncheck();
}
break;
// ... Puede agregar más casos para otros tipos de inputs según sea necesario
default:
// Manejar cualquier otro tipo de input o agregar lógica de error aquí si es necesario
break;
} }
}); });
}); });
}); });
Cypress.Commands.add('validateRow', (rowSelector, expectedValues) => {
cy.waitForElement('tbody');
cy.get(rowSelector).within(() => {
for (const [index, value] of expectedValues.entries()) {
cy.log('CHECKING ', index, value);
if (typeof value == 'boolean') {
const prefix = value ? '' : 'not.';
cy.getValue(`:nth-child(${index + 1})`).should(`${prefix}be.checked`);
continue;
}
cy.getValue(`:nth-child(${index + 1})`).should('have.text', value);
}
});
});
// registerCommands(); // registerCommands();