fix: refs #8388 update VnSelect component to handle option rendering based on optionLabel type
gitea/salix-front/pipeline/pr-dev This commit is unstable Details

This commit is contained in:
Jorge Penadés 2025-04-23 16:38:34 +02:00
parent 587f106818
commit 6c49c9ea82
2 changed files with 96 additions and 188 deletions

View File

@ -407,7 +407,12 @@ function getCaption(opt) {
</template>
<template #option="{ opt, itemProps }">
<QItem v-bind="itemProps">
<QItemSection v-if="typeof opt !== 'object'"> {{ opt }}</QItemSection>
<QItemSection v-if="typeof optionLabel === 'function'">{{
optionLabel(opt)
}}</QItemSection>
<QItemSection v-else-if="typeof opt !== 'object'">
{{ opt }}</QItemSection
>
<QItemSection v-else-if="opt[optionValue] == opt[optionLabel]">
<QItemLabel>{{ opt[optionLabel] }}</QItemLabel>
</QItemSection>

View File

@ -3,71 +3,85 @@ import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { getTotal } from 'src/composables/getTotal';
import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
const { t } = useI18n();
const route = useRoute();
const invoceInIntrastat = ref([]);
const rowsSelected = ref([]);
const countries = ref([]);
const intrastats = ref([]);
const invoiceInFormRef = ref();
const invoiceInIntrastatRef = ref();
const invoiceInId = computed(() => +route.params.id);
const filter = { where: { invoiceInFk: invoiceInId.value } };
const filter = computed(() => ({ where: { invoiceInFk: invoiceInId.value } }));
const columns = computed(() => [
{
name: 'code',
name: 'intrastatFk',
label: t('Code'),
field: (row) => row.intrastatFk,
options: intrastats.value,
model: 'intrastatFk',
optionValue: 'id',
optionLabel: (row) => `${row.id}: ${row.description}`,
sortable: true,
tabIndex: 1,
align: 'left',
component: 'select',
columnFilter: false,
attrs: {
options: intrastats.value,
optionValue: 'id',
optionLabel: (row) => `${row.id}: ${row.description}`,
'data-cy': 'intrastat-code',
sortBy: 'id',
fields: ['id', 'description'],
},
format: getCode,
create: true,
isEditable: true,
},
{
name: 'amount',
label: t('amount'),
field: (row) => row.amount,
sortable: true,
tabIndex: 2,
align: 'left',
component: 'number',
create: true,
isEditable: true,
columnFilter: false,
width: '30px',
},
{
name: 'net',
label: t('net'),
field: (row) => row.net,
sortable: true,
tabIndex: 3,
align: 'left',
component: 'number',
create: true,
isEditable: true,
columnFilter: false,
width: '30px',
},
{
name: 'stems',
label: t('stems'),
field: (row) => row.stems,
sortable: true,
tabIndex: 4,
align: 'left',
component: 'number',
create: true,
isEditable: true,
columnFilter: false,
width: '30px',
},
{
name: 'country',
name: 'countryFk',
label: t('country'),
field: (row) => row.countryFk,
options: countries.value,
model: 'countryFk',
optionValue: 'id',
optionLabel: 'code',
sortable: true,
tabIndex: 5,
align: 'left',
component: 'select',
attrs: {
options: countries.value,
optionLabel: 'code',
},
create: true,
isEditable: true,
columnFilter: false,
width: '30px',
},
]);
const tableRows = computed(
() => invoiceInIntrastatRef.value?.CrudModelRef?.formData || [],
);
function getCode(row) {
const { id, description } = intrastats.value.find(({ id }) => id === row.intrastatFk);
return `${id}: ${description}`;
}
</script>
<template>
<FetchData
@ -82,164 +96,51 @@ const columns = computed(() => [
auto-load
@on-fetch="(data) => (intrastats = data)"
/>
<div class="invoiceIn-intrastat">
<CrudModel
ref="invoiceInFormRef"
<div class="invoice-in-intrastat">
<VnTable
ref="invoiceInIntrastatRef"
data-key="InvoiceInIntrastats"
url="InvoiceInIntrastats"
save-url="InvoiceInIntrastats/crud"
search-url="InvoiceInIntrastats"
auto-load
:data-required="{ invoiceInFk: invoiceInId }"
:filter="filter"
:filter
:user-filter
v-model:selected="rowsSelected"
@on-fetch="(data) => (invoceInIntrastat = data)"
:columns
:is-editable="true"
:table="{ selection: 'multiple', 'row-key': '$index' }"
:create="{
urlCreate: 'InvoiceInIntrastats',
title: t('Create Intrastat Line'),
formInitialData: { invoiceInFk: invoiceInId },
onDataSaved: () => invoiceInIntrastatRef.reload(),
}"
footer
data-cy="invoice-in-intrastat-table"
:right-search="false"
:disable-option="{ card: true }"
>
<template #body="{ rows }">
<QTable
v-model:selected="rowsSelected"
selection="multiple"
:columns="columns"
:rows="rows"
row-key="$index"
:grid="$q.screen.lt.sm"
>
<template #body-cell="{ row, col }">
<QTd>
<VnInputNumber v-model="row[col.name]" />
</QTd>
</template>
<template #body-cell-code="{ row, col }">
<QTd>
<VnSelect
v-model="row[col.model]"
:options="col.options"
:option-value="col.optionValue"
:option-label="col.optionLabel"
:filter-options="['id', 'description']"
data-cy="intrastat-code"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
{{ `${scope.opt.id}: ${scope.opt.description}` }}
</QItem>
</template>
</VnSelect>
</QTd>
</template>
<template #body-cell-country="{ row, col }">
<QTd>
<VnSelect
v-model="row[col.model]"
:options="col.options"
:option-value="col.optionValue"
:option-label="col.optionLabel"
/>
</QTd>
</template>
<template #bottom-row>
<QTr class="bg">
<QTd />
<QTd />
<QTd>
{{ getTotal(rows, 'amount', { currency: 'default' }) }}
</QTd>
<QTd>
{{ getTotal(rows, 'net') }}
</QTd>
<QTd>
{{ getTotal(rows, 'stems', { decimalPlaces: 0 }) }}
</QTd>
<QTd />
</QTr>
</template>
<template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
<QCard>
<QCardSection>
<QCheckbox v-model="props.selected" dense />
</QCardSection>
<QSeparator />
<QList>
<QItem>
<VnSelect
:label="t('Code')"
class="full-width"
v-model="props.row['intrastatFk']"
:options="intrastats"
option-value="id"
:option-label="
(row) => `${row.id}:${row.description}`
"
:filter-options="['id', 'description']"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
{{
`${scope.opt.id}: ${scope.opt.description}`
}}
</QItem>
</template>
</VnSelect>
</QItem>
<QItem
v-for="(value, index) of [
'amount',
'net',
'stems',
]"
:key="index"
>
<VnInputNumber
:label="t(value)"
class="full-width"
v-model="props.row[value]"
clearable
clear-icon="close"
/>
</QItem>
<QItem>
<VnSelect
:label="t('country')"
class="full-width"
v-model="props.row['countryFk']"
:options="countries"
option-value="id"
option-label="code"
/>
</QItem>
</QList>
</QCard>
</div>
</template>
</QTable>
<template #column-footer-amount>
{{ getTotal(tableRows, 'amount', { currency: 'default' }) }}
</template>
</CrudModel>
<template #column-footer-net>
{{ getTotal(tableRows, 'net') }}
</template>
<template #column-footer-stems>
{{ getTotal(tableRows, 'stems', { decimalPlaces: 0 }) }}
</template>
</VnTable>
</div>
<QPageSticky position="bottom-right" :offset="[25, 25]">
<QBtn
color="primary"
icon="add"
v-shortcut="'+'"
size="lg"
round
@click="invoiceInFormRef.insert()"
/>
</QPageSticky>
</template>
<style lang="scss">
.invoiceIn-intrastat {
> .q-card {
.vn-label-value {
display: flex;
gap: 1em;
.label {
flex: 1;
}
.value {
flex: 0.5;
}
}
}
<style lang="scss" scoped>
.invoice-in-intrastat {
display: flex;
flex-direction: column;
align-items: center;
}
:deep(.full-width) {
max-width: 900px;
}
</style>
<i18n>
@ -248,6 +149,7 @@ const columns = computed(() => [
net: Net
stems: Stems
country: Country
Create Intrastat Line: Create Intrastat Line
es:
Code: Código
amount: Valor mercancía
@ -257,4 +159,5 @@ const columns = computed(() => [
Total amount: Total importe
Total net: Total neto
Total stems: Total tallos
Create Intrastat Line: Crear Línea Intrastat
</i18n>