0
0
Fork 0

feat: refs #6825 create vnTableColumn, cardActions

This commit is contained in:
Alex Moreno 2024-04-29 15:12:49 +02:00
parent e0379dd1bc
commit ed3c9db919
3 changed files with 132 additions and 100 deletions

View File

@ -1,15 +1,11 @@
<script setup> <script setup>
import { ref, onMounted, markRaw, computed } from 'vue'; import { ref, onMounted, computed } from 'vue';
import { QCheckbox, useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnPaginate from 'components/ui/VnPaginate.vue'; import VnPaginate from 'components/ui/VnPaginate.vue';
import VnBreadcrumbs from 'components/common/VnBreadcrumbs.vue'; import VnBreadcrumbs from 'components/common/VnBreadcrumbs.vue';
import VnTableColumn from 'src/components/common/VnTableColumn.vue';
/* basic input */ import VnLv from 'src/components/ui/VnLv.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
// import VnLv from 'src/components/ui/VnLv.vue';
const $props = defineProps({ const $props = defineProps({
columns: { columns: {
@ -64,13 +60,6 @@ const tableModes = computed(() => {
return modes; return modes;
}); });
const basicInputs = {
input: markRaw(VnInput),
number: markRaw(VnInput),
date: markRaw(VnInputDate),
checkbox: markRaw(QCheckbox),
select: markRaw(VnSelect),
};
// { // {
// isId: Boolean // isId: Boolean
// align: 'left', // align: 'left',
@ -146,19 +135,12 @@ onMounted(() => {
/> />
</QTh> </QTh>
</template> </template>
<template #body-cell="{ props, row, col }"> <template #body-cell="{ row, col }">
<QTd auto-width :class="`text-${col.align ?? 'left'}`"> <QTd auto-width :class="`text-${col.align ?? 'left'}`">
<!-- {{ row[col.field] }} --> <VnTableColumn :column="col" :row />
<component
v-if="col.component"
:is="basicInputs[col.component] ?? col.component"
v-bind="col.props && col.props(props)"
@click="col.event && col.event(props)"
/>
<span v-else> {{ row[col.field] }}</span>
</QTd> </QTd>
</template> </template>
<template #item="{ row, cols }"> <template #item="{ row, cols, colsMap }">
<QCard bordered flat> <QCard bordered flat>
<QCardSection horizontal> <QCardSection horizontal>
<span <span
@ -166,57 +148,47 @@ onMounted(() => {
:key="index" :key="index"
> >
<QChip <QChip
color="primary" color="primary-light"
v-if="cols[index]?.isId"
square square
v-if="cols[index]?.isId"
:title="t(cols[index].label)" :title="t(cols[index].label)"
class="no-margin"
> >
{{ prop[1] }} {{ prop[1] }}
</QChip> </QChip>
</span> </span>
</QCardSection> </QCardSection>
<QCardSection> <QCardSection class="row justify-between q-pa-sm">
<div>
<div v-for="col of colsMap" :key="col.field">
<div <div
v-for="(prop, index) of Object.entries(row)" v-if="
col.cardVisible &&
!col.isId &&
col.field != 'tableActions'
"
>
<VnLv :label="`${col.label}:`">
<template #value>
<VnTableColumn :column="col" :row />
</template>
</VnLv>
</div>
</div>
</div>
<div v-if="colsMap.tableActions" class="column">
<QBtn
v-for="(btn, index) of colsMap.tableActions.actions"
:key="index" :key="index"
> :title="btn.title"
<div :icon="btn.icon"
v-if="cols[index]?.cardVisible && !cols[index]?.isId" :outline="!btn.isPrimary"
> size="sm"
{{ t(cols[index].label) }} : class="q-pa-sm q-mb-sm"
<component :class="{ 'bg-primary-light': btn.isPrimary }"
v-if="cols[index]?.component" @click.stop="btn.action(row)"
:is="
basicInputs[cols[index]?.component] ??
cols[index]?.component
"
v-bind="
cols[index]?.props && cols[index]?.props(row)
"
@click="
cols[index]?.event && cols[index]?.event(row)
"
/> />
<span v-else>
{{ prop[1] }}
</span>
</div> </div>
</div>
</QCardSection>
<QCardSection>
<span
v-for="(prop, index) of Object.entries(row)"
:key="index"
>
<QChip
color="primary"
v-if="cols[index]?.isId"
square
:title="t(cols[index].label)"
>
{{ prop[1] }}
</QChip>
</span>
</QCardSection> </QCardSection>
</QCard> </QCard>
</template> </template>
@ -225,12 +197,22 @@ onMounted(() => {
</VnPaginate> </VnPaginate>
</template> </template>
<style lang="scss"> <style lang="scss">
* {
--primary-light: #f5b351;
}
.bg-primary-light {
background-color: var(--primary-light);
color: var(--vn-section-color);
}
.text-primary-light {
color: var(--primary-light);
}
.q-checkbox { .q-checkbox {
& .q-checkbox__label { & .q-checkbox__label {
color: #f5b351; /* use global*/ color: var(--primary-light); /* use global*/
} }
& .q-checkbox__inner { & .q-checkbox__inner {
color: #f5b351; /* use global*/ color: var(--primary-light); /* use global*/
} }
} }
.q-table--dark .q-table__bottom, .q-table--dark .q-table__bottom,
@ -248,7 +230,7 @@ onMounted(() => {
/* Works on Firefox */ /* Works on Firefox */
* { * {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: #f5b351 transparent; scrollbar-color: var(--primary-light) transparent;
} }
/* Works on Chrome, Edge, and Safari */ /* Works on Chrome, Edge, and Safari */
@ -263,7 +245,7 @@ onMounted(() => {
*::-webkit-scrollbar-thumb { *::-webkit-scrollbar-thumb {
background-color: transparent; background-color: transparent;
border-radius: 20px; border-radius: 20px;
border: 3px solid #f5b351; border: 3px solid var(--primary-light);
} }
.grid-one { .grid-one {
@ -297,4 +279,9 @@ onMounted(() => {
top: 0; top: 0;
} }
} }
.vn-label-value {
display: flex;
flex-direction: row;
}
</style> </style>

View File

@ -0,0 +1,39 @@
<template>
<component
v-if="column.component"
:is="components[column.component] ?? column.component"
v-bind="column.props && column.props(row)"
@click="column.event && column.event(row)"
/>
<span v-else>{{ dashIfEmpty(row[column.field]) }}</span>
</template>
<script setup>
import { markRaw } from 'vue';
import { QIcon, QCheckbox } from 'quasar';
import { dashIfEmpty } from 'src/filters';
/* basic input */
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
const components = {
input: markRaw(VnInput),
number: markRaw(VnInput),
date: markRaw(VnInputDate),
checkbox: markRaw(QCheckbox),
select: markRaw(VnSelect),
icon: markRaw(QIcon),
};
defineProps({
column: {
type: Object,
required: true,
},
row: {
type: Object,
required: true,
},
});
</script>

View File

@ -1,19 +1,15 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount, onMounted } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import VnInput from 'src/components/common/VnInput.vue';
import VnTable from 'components/common/VnTable.vue'; import VnTable from 'components/common/VnTable.vue';
import CustomerSummary from '../Card/CustomerSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { QBtn, QIcon } from 'quasar'; import { QBtn, QIcon } from 'quasar';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import CustomerExtendedListActions from './CustomerExtendedListActions.vue'; import CustomerExtendedListActions from './CustomerExtendedListActions.vue';
import CustomerExtendedListFilter from './CustomerExtendedListFilter.vue'; import CustomerExtendedListFilter from './CustomerExtendedListFilter.vue';
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import { useArrayData } from 'composables/useArrayData';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
@ -21,17 +17,6 @@ const { t } = useI18n();
const router = useRouter(); const router = useRouter();
const stateStore = useStateStore(); const stateStore = useStateStore();
const arrayData = ref(null);
onBeforeMount(async () => {
arrayData.value = useArrayData('CustomerExtendedList', {
url: 'Clients/extendedListFilter',
limit: 0,
});
await arrayData.value.fetch({ append: false });
stateStore.rightDrawer = true;
});
onMounted(() => { onMounted(() => {
const filteredColumns = columns.value.filter( const filteredColumns = columns.value.filter(
(col) => col.name !== 'actions' && col.name !== 'customerStatus' (col) => col.name !== 'actions' && col.name !== 'customerStatus'
@ -39,8 +24,6 @@ onMounted(() => {
allColumnNames.value = filteredColumns.map((col) => col.name); allColumnNames.value = filteredColumns.map((col) => col.name);
}); });
const rows = computed(() => arrayData.value.store.data);
const selectedCustomerId = ref(0); const selectedCustomerId = ref(0);
const selectedSalesPersonId = ref(0); const selectedSalesPersonId = ref(0);
const allColumnNames = ref([]); const allColumnNames = ref([]);
@ -264,6 +247,17 @@ const tableColumnComponents = {
event: () => {}, event: () => {},
}, },
}; };
const { viewSummary } = useSummaryDialog();
const redirectToCreateView = (row) => {
router.push({
name: 'TicketList',
query: {
params: JSON.stringify({
clientFk: row.id,
}),
},
});
};
const columns = computed(() => [ const columns = computed(() => [
{ {
@ -284,14 +278,12 @@ const columns = computed(() => [
field: 'name', field: 'name',
label: t('customer.extendedList.tableVisibleColumns.name'), label: t('customer.extendedList.tableVisibleColumns.name'),
name: 'name', name: 'name',
cardVisible: true,
}, },
{ {
align: 'left', align: 'left',
field: 'fi', field: 'fi',
label: t('customer.extendedList.tableVisibleColumns.fi'), label: t('customer.extendedList.tableVisibleColumns.fi'),
name: 'fi', name: 'fi',
cardVisible: true,
}, },
{ {
align: 'left', align: 'left',
@ -316,12 +308,14 @@ const columns = computed(() => [
field: 'phone', field: 'phone',
label: t('customer.extendedList.tableVisibleColumns.phone'), label: t('customer.extendedList.tableVisibleColumns.phone'),
name: 'phone', name: 'phone',
cardVisible: true,
}, },
{ {
align: 'left', align: 'left',
field: 'mobile', field: 'mobile',
label: t('customer.extendedList.tableVisibleColumns.mobile'), label: t('customer.extendedList.tableVisibleColumns.mobile'),
name: 'mobile', name: 'mobile',
cardVisible: true,
}, },
{ {
align: 'left', align: 'left',
@ -358,6 +352,7 @@ const columns = computed(() => [
field: 'email', field: 'email',
label: t('customer.extendedList.tableVisibleColumns.email'), label: t('customer.extendedList.tableVisibleColumns.email'),
name: 'email', name: 'email',
cardVisible: true,
}, },
{ {
align: 'left', align: 'left',
@ -469,9 +464,22 @@ const columns = computed(() => [
}, },
{ {
align: 'right', align: 'right',
field: 'actions', field: 'tableActions',
label: '', label: '',
name: 'actions', name: 'tableActions',
actions: [
{
title: t('Client ticket list'),
icon: 'vn:ticket',
action: redirectToCreateView,
isPrimary: true,
},
{
title: t('Client ticket list'),
icon: 'preview',
action: (row) => viewSummary(row.id, CustomerSummary),
},
],
}, },
]); ]);
@ -513,12 +521,10 @@ const selectSalesPersonId = (id) => (selectedSalesPersonId.value = id);
<VnTable <VnTable
data-key="CustomerExtendedList" data-key="CustomerExtendedList"
url="Clients/extendedListFilter"
order="id DESC"
:columns="columns" :columns="columns"
:rows="rows" auto-load
class="full-width q-mt-md"
row-key="id"
:visible-columns="visibleColumns"
@row-click="(evt, row, id) => navigateToTravelId(row.id)"
> >
<!-- <!--
default-mode="table" default-mode="table"