feat: Vndescriptor

This commit is contained in:
Javier Segarra 2024-07-02 20:28:13 +02:00
parent c3d97231d2
commit 32fe76aaab
4 changed files with 144 additions and 99 deletions

View File

@ -8,6 +8,8 @@ import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'components/common/VnInput.vue'; import VnInput from 'components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnComponent from 'components/common/VnComponent.vue'; import VnComponent from 'components/common/VnComponent.vue';
import VnDescriptor from 'components/VnTable/VnDescriptor.vue';
import { QBtn } from 'quasar';
const model = defineModel(undefined, { required: true }); const model = defineModel(undefined, { required: true });
const $props = defineProps({ const $props = defineProps({
@ -102,6 +104,17 @@ const defaultComponents = {
icon: { icon: {
component: markRaw(QIcon), component: markRaw(QIcon),
}, },
descriptor: {
component: markRaw(VnDescriptor),
attrs: {
class: 'link',
flat: true,
dense: true,
},
forceAttrs: {
row: $props.row,
},
},
}; };
const value = computed(() => { const value = computed(() => {

View File

@ -0,0 +1,49 @@
<script setup>
import { useQuasar } from 'quasar';
const quasar = useQuasar();
import VnComponent from 'components/common/VnComponent.vue';
import { onMounted, ref } from 'vue';
import ItemDescriptor from 'src/pages/Item/Card/ItemDescriptor.vue';
const $props = defineProps({
label: {
type: Function,
required: true,
},
row: {
type: Object,
default: null,
},
proxy: {
type: Object,
default: null,
},
});
const btnRow = ref(null);
const popupVisible = ref(true);
const handleClick = (event) => {
event.preventDefault();
event.stopPropagation();
console.log(event);
popupVisible.value = true;
// quasar.dialog({
// component: $props.proxy.component,
// componentProps: {
// id: $props.row[$props.proxy.key],
// },
// });
};
onMounted(() => {
// btnRow.value = btnRow.value.$el;
});
</script>
<template>
<QBtn class="link" flat dense ref="btnRow" @click="handleClick"
>{{ $props.label($props.row) }}
</QBtn>
<!-- <VnComponent :id="row.itemFk" /> -->
<QPopupProxy :target="btnRow"> <ItemDescriptor :id="1" /></QPopupProxy>
</template>
<style lang="scss"></style>

View File

@ -59,6 +59,10 @@ const $props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
hasSubtoolbar: {
type: Boolean,
default: true,
},
}); });
const { t } = useI18n(); const { t } = useI18n();
const stateStore = useStateStore(); const stateStore = useStateStore();
@ -175,11 +179,14 @@ function columnName(col) {
} }
function getColAlign(col) { function getColAlign(col) {
return 'text-' + (col.align ?? 'left') return 'text-' + (col.align ?? 'left');
} }
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
defineExpose({ defineExpose({
reload, reload,
redirect: redirectFn, redirect: redirectFn,
selected,
}); });
</script> </script>
<template> <template>
@ -225,11 +232,18 @@ defineExpose({
:search-url="searchUrl" :search-url="searchUrl"
:disable-infinite-scroll="mode == TABLE_MODE" :disable-infinite-scroll="mode == TABLE_MODE"
@save-changes="reload" @save-changes="reload"
:has-subtoolbar="isEditable" :has-subtoolbar="$attrs['hasSubtoolbar'] ?? isEditable"
> >
<template
v-for="(_, slotName) in $slots"
#[slotName]="slotData"
:key="slotName"
>
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
</template>
<template #body="{ rows }"> <template #body="{ rows }">
<QTable <QTable
v-bind="$attrs['QTable']" v-bind="$attrs['q-table']"
class="vnTable" class="vnTable"
:columns="splittedColumns.columns" :columns="splittedColumns.columns"
:rows="rows" :rows="rows"
@ -246,6 +260,7 @@ defineExpose({
CrudModelRef.vnPaginateRef.paginate() CrudModelRef.vnPaginateRef.paginate()
" "
@row-click="(_, row) => rowClickFunction(row)" @row-click="(_, row) => rowClickFunction(row)"
@update:selected="$emit('update:selected', $event)"
> >
<template #top-left> <template #top-left>
<slot name="top-left"></slot> <slot name="top-left"></slot>
@ -477,6 +492,7 @@ defineExpose({
default="input" default="input"
v-model="data[column.name]" v-model="data[column.name]"
:show-label="true" :show-label="true"
component-prop="columnCreate"
/> />
<slot name="more-create-dialog" :data="data" /> <slot name="more-create-dialog" :data="data" />
</div> </div>

View File

@ -2,14 +2,15 @@
import { computed, ref, reactive } from 'vue'; import { computed, ref, reactive } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import VnPaginate from 'components/ui/VnPaginate.vue'; // import VnPaginate from 'components/ui/VnPaginate.vue';
import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue'; // import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue';
import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue'; // import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue';
// import FetchData from 'components/FetchData.vue'; // import FetchData from 'components/FetchData.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import NegativeOriginDialog from 'pages/Ticket/Negative/components/NegativeOriginDialog.vue'; import NegativeOriginDialog from 'pages/Ticket/Negative/components/NegativeOriginDialog.vue';
import TotalNegativeOriginDialog from 'pages/Ticket/Negative/components/TotalNegativeOriginDialog.vue'; // import TotalNegativeOriginDialog from 'pages/Ticket/Negative/components/TotalNegativeOriginDialog.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; // import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import { onBeforeMount } from 'vue'; import { onBeforeMount } from 'vue';
import { dashIfEmpty, toDate, toHour } from 'src/filters'; import { dashIfEmpty, toDate, toHour } from 'src/filters';
@ -17,6 +18,11 @@ import { useRouter } from 'vue-router';
// import { useUserConfig } from 'src/composables/useUserConfig'; // import { useUserConfig } from 'src/composables/useUserConfig';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
// import TicketLackDetail from './TicketLackDetail.vue';
// import { useSummaryDialog } from 'src/composables/useSummaryDialog';
// const { viewSummary } = useSummaryDialog();
// const DEFAULT_WAREHOUSE = 'Algemesi'; // const DEFAULT_WAREHOUSE = 'Algemesi';
const router = useRouter(); const router = useRouter();
@ -25,7 +31,7 @@ const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const selectedRows = ref([]); const selectedRows = ref([]);
const showNegativeOriginDialog = ref(false); const showNegativeOriginDialog = ref(false);
const showTotalNegativeOriginDialog = ref(false); // const showTotalNegativeOriginDialog = ref(false);
// const showFilterPanel = ref(false); // const showFilterPanel = ref(false);
const currentRow = ref(null); const currentRow = ref(null);
// const state = useState(); // const state = useState();
@ -34,11 +40,10 @@ const negativeParams = reactive({
days: useRole().likeAny('buyer') ? 2 : 0, days: useRole().likeAny('buyer') ? 2 : 0,
warehouseFk: useState().getUser().value.warehouseFk, warehouseFk: useState().getUser().value.warehouseFk,
}); });
const viewSummary = (row) => { const redirectToCreateView = ({ itemFk }) => {
const id = row.itemFk;
// stateStore.rightDrawer = false; // stateStore.rightDrawer = false;
// currentRow.value = row; // currentRow.value = row;
router.push({ name: 'NegativeDetail', params: { id } }); router.push({ name: 'NegativeDetail', params: { id: itemFk } });
}; };
const originDialogRef = ref(); const originDialogRef = ref();
// const totalNegativeDialogRef = ref(); // const totalNegativeDialogRef = ref();
@ -47,15 +52,18 @@ const columns = computed(() => [
name: 'date', name: 'date',
label: t('negative.date'), label: t('negative.date'),
field: 'timed', field: 'timed',
format: (val) => toDate(val), format: ({ timed }) => toDate(timed),
sortable: true, sortable: true,
cardVisible: true,
isId: true,
}, },
{ {
name: 'timed', name: 'timed',
label: t('negative.timed'), label: t('negative.timed'),
field: 'timed', field: 'timed',
format: (val) => toHour(val), format: ({ timed }) => toHour(timed),
sortable: true, sortable: true,
cardVisible: true,
}, },
{ {
name: 'itemFk', name: 'itemFk',
@ -67,9 +75,20 @@ const columns = computed(() => [
name: 'longName', name: 'longName',
label: t('negative.longName'), label: t('negative.longName'),
field: ({ longName }) => longName, field: ({ longName }) => longName,
align: 'center', columnField: {
component: 'descriptor',
attrs: {
label: ({ longName }) => longName,
proxy: {
key: 'itemFk',
component: ItemDescriptorProxy,
},
},
},
sortable: true, sortable: true,
headerStyle: 'width: 350px', headerStyle: 'width: 350px',
cardVisible: true,
}, },
{ {
name: 'producer', name: 'producer',
@ -83,34 +102,44 @@ const columns = computed(() => [
label: t('negative.colour'), label: t('negative.colour'),
field: ({ inkFk }) => inkFk, field: ({ inkFk }) => inkFk,
sortable: true, sortable: true,
cardVisible: true,
}, },
{ {
name: 'size', name: 'size',
label: t('negative.size'), label: t('negative.size'),
field: ({ size }) => size, field: ({ size }) => size,
sortable: true, sortable: true,
cardVisible: true,
}, },
{ {
name: 'category', name: 'category',
label: t('negative.origen'), label: t('negative.origen'),
field: ({ category }) => dashIfEmpty(category), field: ({ category }) => dashIfEmpty(category),
sortable: true, sortable: true,
cardVisible: true,
}, },
{ {
name: 'lack', name: 'lack',
label: t('negative.lack'), label: t('negative.lack'),
field: ({ lack }) => lack, field: ({ lack }) => lack,
align: 'center',
sortable: true, sortable: true,
headerStyle: 'padding-left: 33px', headerStyle: 'padding-left: 33px',
cardVisible: true,
}, },
{ {
name: 'icons', align: 'right',
align: 'center', name: 'tableActions',
field: (row) => row, actions: [
{
title: t('Client ticket list'),
icon: 'preview',
action: redirectToCreateView,
},
],
}, },
]); ]);
const vnPaginateRef = ref(); const tableRef = ref();
// const ticketDetailRef = ref(); // const ticketDetailRef = ref();
onBeforeMount(() => { onBeforeMount(() => {
@ -119,7 +148,7 @@ onBeforeMount(() => {
// const handleWarehouses = async (data) => { // const handleWarehouses = async (data) => {
// negativeParams.warehouse = data.find((w) => w.name === DEFAULT_WAREHOUSE).id; // negativeParams.warehouse = data.find((w) => w.name === DEFAULT_WAREHOUSE).id;
// await vnPaginateRef.value.fetch(); // await tableRef.value.fetch();
// showFilterPanel.value = true; // showFilterPanel.value = true;
// }; // };
</script> </script>
@ -167,88 +196,26 @@ onBeforeMount(() => {
</template> </template>
</VnSubToolbar> </VnSubToolbar>
<div class="list"> <div class="list">
<VnPaginate <VnTable
ref="vnPaginateRef" ref="tableRef"
data-key="NegativeList" data-key="NegativeList"
:url="`Tickets/itemLack`" :url="`Tickets/itemLack`"
:order="['itemFk DESC, date DESC, timed DESC']" :order="['itemFk DESC, date DESC, timed DESC']"
:user-params="negativeParams" :user-params="negativeParams"
auto-load auto-load
>
<template #body="{ rows }">
<QTable
:columns="columns" :columns="columns"
:rows="rows" default-mode="table"
:dense="$q.screen.lt.md" :right-search="true"
flat :is-editable="false"
row-key="itemFk" :use-model="true"
selection="multiple" :row-click="redirectToCreateView"
v-model:selected="selectedRows" v-model:selected="selectedRows"
:grid="$q.screen.lt.md" :q-table="{
auto-load 'row-key': 'itemFk',
:rows-per-page-options="[0]" selection: 'multiple',
hide-pagination }"
:pagination="{ rowsPerPage: null }"
:no-data-label="t('globals.noResults')"
> >
<template #top> </VnTable>
<div style="width: 100%; display: table">
<div style="float: right; color: lightgray">
{{ `${rows.length} ${t('globals.results')}` }}
</div>
</div>
</template>
<template #body-cell-hasCmrDms="{ value }">
<QTd align="center">
<QBadge
:id="value ? 'true' : 'false'"
:label="
value ? t('negative.true') : t('negative.false')
"
/>
</QTd>
</template>
<template #body-cell-longName="{ row, value }">
<QTd align="right" class="text-primary">
<QBtn flat color="blue" dense>{{ value }}</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
</QTd>
</template>
<template #body-cell-producer="{ value }">
<QTd align="right">
<QBtn
v-if="value !== '-'"
flat
class="text-primary"
color="blue"
dense
>{{ value }}</QBtn
>
<span v-else>{{ value }}</span>
</QTd>
</template>
<template #body-cell-icons="{ value }">
<QTd align="center">
<QIcon
@click="viewSummary(value)"
class="q-ml-md"
color="primary"
name="search"
size="sm"
>
<QTooltip>
{{ t('globals.preview') }}
</QTooltip>
</QIcon>
</QTd>
</template>
</QTable>
</template>
</VnPaginate>
</div> </div>
<!-- <div v-if="currentRow" class="list"> <!-- <div v-if="currentRow" class="list">
<TicketLackDetail <TicketLackDetail
@ -270,11 +237,11 @@ onBeforeMount(() => {
:selected-rows="selectedRows" :selected-rows="selectedRows"
> >
</NegativeOriginDialog> </NegativeOriginDialog>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <!-- <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<TicketLackFilter data-key="NegativeList" /> <TicketLackFilter data-key="NegativeList" />
</QScrollArea> </QScrollArea>
</QDrawer> </QDrawer> -->
</QPage> </QPage>
</template> </template>