refactor: quotation

This commit is contained in:
puriphatt 2024-10-03 11:14:12 +07:00
parent 3bead87e03
commit a4ff3052fe
5 changed files with 348 additions and 140 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import useBranchStore from 'src/stores/branch'; import useBranchStore from 'src/stores/branch';
import useCustomerStore from 'src/stores/customer'; import useCustomerStore from 'src/stores/customer';
@ -10,8 +10,8 @@ const { locale } = useI18n({ useScope: 'global' });
const branchStore = useBranchStore(); const branchStore = useBranchStore();
const customerStore = useCustomerStore(); const customerStore = useCustomerStore();
const branch = defineModel<string>('branch'); const branchId = defineModel<string>('branchId');
const customer = defineModel<string>('customer'); const customerBranchId = defineModel<string>('customerBranchId');
const agentPrice = defineModel<boolean>('agentPrice'); const agentPrice = defineModel<boolean>('agentPrice');
const branchOption = ref(); const branchOption = ref();
@ -23,7 +23,7 @@ defineProps<{
separator?: boolean; separator?: boolean;
employee?: boolean; employee?: boolean;
title?: string; title?: string;
prefixId: string; inputOnly?: boolean;
}>(); }>();
defineEmits<{ defineEmits<{
@ -37,37 +37,7 @@ async function filter(
) { ) {
update( update(
async () => { async () => {
const res = await init(val, type);
type === 'branch'
? await branchStore.fetchList({
query: val,
pageSize: 30,
})
: await customerStore.fetchList({
query: val,
pageSize: 30,
});
if (res) {
if (type === 'branch') {
branchOption.value = res.result.map((v) => ({
value: v.id,
label: v.name,
labelEN: v.nameEN,
}));
} else if (type === 'customer') {
customerOption.value = res.result.map((v) => ({
value: v.id,
label:
v.customerType === 'CORP'
? v.branch[0].registerName
: `${v.branch[0].firstName} ${v.branch[0].lastName}`,
labelEN:
v.customerType === 'CORP'
? v.branch[0].registerNameEN
: `${v.branch[0].firstNameEN} ${v.branch[0].lastNameEN}`,
}));
}
}
}, },
(ref: QSelect) => { (ref: QSelect) => {
@ -78,10 +48,56 @@ async function filter(
}, },
); );
} }
async function init(val: string, type: 'branch' | 'customer') {
const res =
type === 'branch'
? await branchStore.fetchList({
query: val,
pageSize: 30,
})
: await customerStore.fetchListCustomeBranch({
query: val,
registeredBranchId: branchId.value || undefined,
pageSize: 30,
});
if (res) {
if (type === 'branch') {
branchOption.value = res.result.map((v) => ({
value: v.id,
label: v.name,
labelEN: v.nameEN,
}));
} else if (type === 'customer') {
customerOption.value = res.result.map((v) => ({
value: v.id,
label: v.registerName || `${v.firstName} ${v.lastName}` || '-',
labelEN: v.registerNameEN || `${v.firstNameEN} ${v.lastNameEN}` || '-',
}));
}
}
}
onMounted(async () => {
await init('', 'branch');
await init('', 'customer');
});
// watch(
// () => branchId.value,
// async (v) => {
// if (v) {
// customerBranchId.value = '';
// }
// },
// );
</script> </script>
<template> <template>
<div class="row col-12"> <div class="row">
<div class="col-12 row items-center q-pb-sm text-weight-bold text-body1"> <div
v-if="!inputOnly"
class="col-12 row items-center q-pb-sm text-weight-bold text-body1"
>
<q-icon <q-icon
flat flat
size="xs" size="xs"
@ -104,7 +120,7 @@ async function filter(
<SelectInput <SelectInput
:readonly :readonly
incremental incremental
v-model="branch" v-model="branchId"
id="quotation-branch" id="quotation-branch"
class="col-md col-12" class="col-md col-12"
:option="branchOption" :option="branchOption"
@ -117,7 +133,7 @@ async function filter(
<SelectInput <SelectInput
:readonly :readonly
incremental incremental
v-model="customer" v-model="customerBranchId"
class="col-md col-12" class="col-md col-12"
id="quotation-customer" id="quotation-customer"
:option="customerOption" :option="customerOption"

View file

@ -19,8 +19,9 @@ defineEmits<{
withDefaults( withDefaults(
defineProps<{ defineProps<{
rows: { rows: {
[key: string]: any;
code: string; code: string;
list: string; name: string;
type: string; type: string;
amount: number; amount: number;
pricePerUnit: number; pricePerUnit: number;
@ -48,10 +49,10 @@ const columns = [
field: 'code', field: 'code',
}, },
{ {
name: 'list', name: 'name',
align: 'left', align: 'left',
label: 'productService.service.list', label: 'productService.service.list',
field: 'list', field: 'name',
}, },
{ {
name: 'amount', name: 'amount',
@ -100,7 +101,7 @@ const columns = [
button-delete button-delete
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
imgColumn="list" imgColumn="name"
:customColumn="['amount', 'pricePerUnit', 'discount', 'tax', 'sumPrice']" :customColumn="['amount', 'pricePerUnit', 'discount', 'tax', 'sumPrice']"
@delete="$emit('delete')" @delete="$emit('delete')"
> >
@ -108,16 +109,8 @@ const columns = [
<q-avatar class="q-mr-sm" size="md"> <q-avatar class="q-mr-sm" size="md">
<q-icon <q-icon
class="full-width full-height" class="full-width full-height"
:name=" name="mdi-shopping-outline"
props.row.type === 'product' :style="`color: var(--teal-10); background: hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
? 'mdi-shopping-outline'
: 'mdi-server-outline'
"
:style="`color: var(--${props.row.type === 'product' ? 'teal-10' : 'orange-5'}); background: ${
props.row.type === 'product'
? `hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`
: `hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`
}`"
/> />
</q-avatar> </q-avatar>
</template> </template>

View file

@ -1,5 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { pageTabs, fieldSelectedOption } from './constants'; import { pageTabs, fieldSelectedOption } from './constants';
import { useQuotationForm } from './form';
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
@ -35,6 +37,7 @@ import ItemCard from 'src/components/ItemCard.vue';
import DialogForm from 'components/DialogForm.vue'; import DialogForm from 'components/DialogForm.vue';
import { AddButton } from 'src/components/button'; import { AddButton } from 'src/components/button';
import SideMenu from 'components/SideMenu.vue'; import SideMenu from 'components/SideMenu.vue';
import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
import { import {
uploadFileListEmployee, uploadFileListEmployee,
@ -71,17 +74,7 @@ import {
import QuotationView from './QuotationView.vue'; import QuotationView from './QuotationView.vue';
import { watch } from 'vue'; import { watch } from 'vue';
type Node = { const quotationForm = useQuotationForm();
[key: string]: any;
opened?: boolean;
checked?: boolean;
bg?: string;
fg?: string;
icon?: string;
displayDropIcon?: boolean;
children?: Node[];
};
const customerFormStore = useCustomerForm(); const customerFormStore = useCustomerForm();
const employeeFormStore = useEmployeeForm(); const employeeFormStore = useEmployeeForm();
const employeeStore = useEmployeeStore(); const employeeStore = useEmployeeStore();
@ -90,12 +83,14 @@ const flowStore = useFlowStore();
const userBranch = useMyBranch(); const userBranch = useMyBranch();
const ocrStore = useOcrStore(); const ocrStore = useOcrStore();
const { currentFormData: quotationFormData } = storeToRefs(quotationForm);
const { state: customerFormState, currentFormData: customerFormData } = const { state: customerFormState, currentFormData: customerFormData } =
storeToRefs(customerFormStore); storeToRefs(customerFormStore);
const { state: employeeFormState, currentFromDataEmployee } = const { state: employeeFormState, currentFromDataEmployee } =
storeToRefs(employeeFormStore); storeToRefs(employeeFormStore);
const { currentMyBranch } = storeToRefs(userBranch); const { currentMyBranch } = storeToRefs(userBranch);
const branchId = ref('');
const currentCustomerId = ref<string | undefined>(); const currentCustomerId = ref<string | undefined>();
const refreshImageState = ref(false); const refreshImageState = ref(false);
const emptyCreateDialog = ref(false); const emptyCreateDialog = ref(false);
@ -360,7 +355,10 @@ function triggerAddQuotationDialog() {
} }
function triggerQuotationDialog() { function triggerQuotationDialog() {
window.open('/quotation/add-quotation', '_blank'); window.open(
`/quotation/add-quotation?branchId=${branchId.value}&customerBranchId=${quotationFormData.value.customerBranchId}&date=${Date.now()}`,
'_blank',
);
// TODO: form and state controll // TODO: form and state controll
} }
@ -484,7 +482,12 @@ watch(() => pageState.currentTab, fetchQuotationList);
</script> </script>
<template> <template>
{{ convertToTree() }} <ButtonAddComponent
hide-icon
style="z-index: 999"
@click.stop="triggerAddQuotationDialog"
/>
<div class="column full-height no-wrap"> <div class="column full-height no-wrap">
<!-- SEC: stat --> <!-- SEC: stat -->
<section class="text-body-2 q-mb-xs flex items-center"> <section class="text-body-2 q-mb-xs flex items-center">
@ -721,7 +724,7 @@ watch(() => pageState.currentTab, fetchQuotationList);
</nav> </nav>
<!-- SEC: body content --> <!-- SEC: body content -->
<article <article
v-if="false" v-if="!quotationData || quotationData.length === 0"
class="col surface-2 flex items-center justify-center" class="col surface-2 flex items-center justify-center"
> >
<CreateButton <CreateButton
@ -832,6 +835,13 @@ watch(() => pageState.currentTab, fetchQuotationList);
submit-icon="mdi-check" submit-icon="mdi-check"
height="auto" height="auto"
width="60vw" width="60vw"
:submit="() => triggerQuotationDialog()"
:close="
() => {
branchId = '';
quotationFormData.customerBranchId = '';
}
"
> >
<header class="q-mx-lg q-mt-lg"> <header class="q-mx-lg q-mt-lg">
<ProfileBanner <ProfileBanner
@ -852,7 +862,8 @@ watch(() => pageState.currentTab, fetchQuotationList);
style="height: 100%; max-height: 100%; overflow-y: auto" style="height: 100%; max-height: 100%; overflow-y: auto"
> >
<FormAbout <FormAbout
prefixId="zxc" v-model:branch-id="branchId"
v-model:customer-branch-id="quotationFormData.customerBranchId"
@add-customer="triggerSelectTypeCustomerd()" @add-customer="triggerSelectTypeCustomerd()"
/> />
</div> </div>

View file

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue'; import { computed, reactive, ref, watch } from 'vue';
import useOptionStore from 'stores/options';
import { moveItemUp, moveItemDown, deleteItem } from 'stores/utils'; import { moveItemUp, moveItemDown, deleteItem } from 'stores/utils';
import useOptionStore from 'stores/options';
import DialogForm from 'src/components/DialogForm.vue'; import DialogForm from 'src/components/DialogForm.vue';
import TreeView from 'src/components/shared/TreeView.vue'; import TreeView from 'src/components/shared/TreeView.vue';
@ -32,6 +32,7 @@ const optionStore = useOptionStore();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'selectGroup', id: string): void; (e: 'selectGroup', id: string): void;
(e: 'submit', nodes: Node[]): void;
}>(); }>();
const model = defineModel<boolean>(); const model = defineModel<boolean>();
@ -186,6 +187,9 @@ function mapNode() {
subtitle: p.product.code || ' ', subtitle: p.product.code || ' ',
detail: p.product.detail, detail: p.product.detail,
remark: p.product.remark, remark: p.product.remark,
price: p.product.price,
agentPrice: p.product.agentPrice,
serviceCharge: p.product.serviceCharge,
icon: 'mdi-shopping-outline', icon: 'mdi-shopping-outline',
bg: 'hsla(var(--teal-10-hsl)/0.1)', bg: 'hsla(var(--teal-10-hsl)/0.1)',
fg: 'var(--teal-10)', fg: 'var(--teal-10)',
@ -207,6 +211,9 @@ function mapNode() {
subtitle: p.product.code || ' ', subtitle: p.product.code || ' ',
detail: p.product.detail, detail: p.product.detail,
remark: p.product.remark, remark: p.product.remark,
price: p.product.price,
agentPrice: p.product.agentPrice,
serviceCharge: p.product.serviceCharge,
type: 'product', type: 'product',
})), })),
})); }));
@ -220,6 +227,9 @@ function mapNode() {
subtitle: v.code, subtitle: v.code,
detail: v.detail, detail: v.detail,
remark: v.remark, remark: v.remark,
price: v.price,
agentPrice: v.agentPrice,
serviceCharge: v.serviceCharge,
type: 'product', type: 'product',
icon: 'mdi-shopping-outline', icon: 'mdi-shopping-outline',
bg: 'hsla(var(--teal-10-hsl)/0.1)', bg: 'hsla(var(--teal-10-hsl)/0.1)',
@ -285,6 +295,7 @@ watch(
:title="$t('general.list', { msg: $t('productService.title') })" :title="$t('general.list', { msg: $t('productService.title') })"
:submit-label="$t('general.select', { msg: $t('productService.title') })" :submit-label="$t('general.select', { msg: $t('productService.title') })"
submit-icon="mdi-check" submit-icon="mdi-check"
:submit="() => $emit('submit', nodes)"
> >
<q-splitter <q-splitter
v-model="splitterModel" v-model="splitterModel"

View file

@ -1,25 +1,57 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref } from 'vue'; import { setLocale } from 'src/utils/datetime';
import { QSelect, useQuasar } from 'quasar'; import { QSelect, useQuasar } from 'quasar';
import { onMounted, reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import ProductServiceForm from './ProductServiceForm.vue';
import WorkerItem from 'components/05_quotation/WorkerItem.vue'; import WorkerItem from 'components/05_quotation/WorkerItem.vue';
import QuotationFormInfo from './QuotationFormInfo.vue'; import QuotationFormInfo from './QuotationFormInfo.vue';
import { AddButton, SaveButton } from 'components/button';
import ToggleButton from 'src/components/button/ToggleButton.vue'; import ToggleButton from 'src/components/button/ToggleButton.vue';
import ProductItem from 'src/components/05_quotation/ProductItem.vue'; import ProductItem from 'src/components/05_quotation/ProductItem.vue';
import { setLocale } from 'src/utils/datetime'; import FormAbout from 'src/components/05_quotation/FormAbout.vue';
import { useI18n } from 'vue-i18n'; import DialogForm from 'src/components/DialogForm.vue';
import SelectZone from 'src/components/shared/SelectZone.vue';
import PersonCard from 'src/components/shared/PersonCard.vue';
import { AddButton, SaveButton } from 'components/button';
import { storeToRefs } from 'pinia';
import { useQuotationForm } from './form';
import { dateFormat } from 'src/utils/datetime';
import { Employee } from 'src/stores/employee/types';
import {
ProductGroup,
ProductList,
Service,
} from 'src/stores/product-service/types';
import useProductServiceStore from 'src/stores/product-service';
type Node = {
[key: string]: any;
opened?: boolean;
checked?: boolean;
bg?: string;
fg?: string;
icon?: string;
children?: Node[];
};
defineProps<{ defineProps<{
readonly?: boolean; readonly?: boolean;
}>(); }>();
const productServiceStore = useProductServiceStore();
const quotationForm = useQuotationForm();
const { locale } = useI18n(); const { locale } = useI18n();
const { currentFormData: quotationFormData } = storeToRefs(quotationForm);
const $q = useQuasar(); const $q = useQuasar();
const date = ref();
const rows = ref<Node[]>([]);
const selectedEmployee = ref<Employee[]>([]);
const selectedBranchIssuer = ref(''); const selectedBranchIssuer = ref('');
const selectedCustomer = ref(''); const selectedCustomer = ref('');
const toggleWorker = ref(true); const toggleWorker = ref(true);
const branchId = ref('');
const quotationNo = ref(''); const quotationNo = ref('');
const actor = ref(''); const actor = ref('');
@ -32,6 +64,89 @@ const payType = ref('');
const paySplitCount = ref(1); const paySplitCount = ref(1);
const payBank = ref(''); const payBank = ref('');
const pageState = reactive({
hideStat: false,
inputSearch: '',
statusFilter: 'all',
fieldSelected: [],
gridView: false,
currentTab: 'all',
addModal: false,
quotationModal: false,
employeeModal: false,
productServiceModal: false,
});
type ProductGroupId = string;
const productGroup = ref<ProductGroup[]>([]);
const productList = ref<Partial<Record<ProductGroupId, ProductList[]>>>({});
const serviceList = ref<Partial<Record<ProductGroupId, Service[]>>>({});
type Id = string;
const product = ref<Record<Id, ProductList>>({});
const service = ref<Record<Id, Service>>({});
const selectedGroup = ref<ProductGroup | null>(null);
const selectedGroupSub = ref<'product' | 'service' | null>(null);
const selectedProductServiceId = ref('');
async function getAllProduct(
groupId: string,
opts?: { force?: false; page?: number; pageSize?: number },
) {
selectedGroupSub.value = 'product';
if (!opts?.force && productList.value[groupId] !== undefined) return;
const ret = await productServiceStore.fetchListProduct({
page: opts?.page ?? 1,
pageSize: opts?.pageSize ?? 9999,
productGroupId: groupId,
});
if (ret) productList.value[groupId] = ret.result;
}
async function getAllService(
groupId: string,
opts?: { force?: false; page?: number; pageSize?: number },
) {
selectedGroupSub.value = 'service';
if (!opts?.force && serviceList.value[groupId] !== undefined) return;
const ret = await productServiceStore.fetchListService({
page: opts?.page ?? 1,
pageSize: opts?.pageSize ?? 9999,
productGroupId: groupId,
fullDetail: true,
});
if (ret) serviceList.value[groupId] = ret.result;
}
function triggerSelectEmployeeDialog() {
pageState.employeeModal = true;
// TODO: form and state controll
}
function triggerProductServiceDialog() {
pageState.productServiceModal = true;
// TODO: form and state controll
}
function convertToTable(nodes: Node[]): Node[] {
const products: Node[] = [];
nodes.forEach((node) => {
if (node.type === 'product' && node.checked) {
products.push(node);
}
if (node.children && node.children.length !== 0) {
products.push(...convertToTable(node.children)); // Correctly push the converted children
}
});
return products;
}
function changeMode(mode: string) { function changeMode(mode: string) {
if (mode === 'light') { if (mode === 'light') {
localStorage.setItem('currentTheme', 'light'); localStorage.setItem('currentTheme', 'light');
@ -60,6 +175,19 @@ function changeMode(mode: string) {
} }
onMounted(async () => { onMounted(async () => {
const ret = await productServiceStore.fetchListProductService({
page: 1,
pageSize: 9999,
});
if (ret) productGroup.value = ret.result;
const urlParams = new URLSearchParams(window.location.search);
const queryDate = urlParams.get('date');
date.value = queryDate && new Date(Number(queryDate));
branchId.value = urlParams.get('branchId') || '';
quotationFormData.value.customerBranchId =
urlParams.get('customerBranchId') || '';
const getCurLang = localStorage.getItem('currentLanguage'); const getCurLang = localStorage.getItem('currentLanguage');
if (getCurLang === 'English') { if (getCurLang === 'English') {
locale.value = 'eng'; locale.value = 'eng';
@ -97,30 +225,20 @@ onMounted(async () => {
<span class="column text-h6 text-bold q-ml-md"> <span class="column text-h6 text-bold q-ml-md">
{{ $t('quotation.title') }} {{ $t('quotation.title') }}
<span class="text-caption text-regular app-text-muted"> <span class="text-caption text-regular app-text-muted">
{{ $t('quotation.processOn', { msg: '27 มีนาคม 2567 16:00:01' }) }} {{
$t('quotation.processOn', {
msg: `${dateFormat(date, true)} ${dateFormat(date, true, true)}`,
})
}}
</span> </span>
</span> </span>
</div> </div>
<q-select <FormAbout
v-model="selectedBranchIssuer" class="col-4"
:options="[{ label: 'Issuer 1', value: 'Issuer 1' }]" input-only
:label="$t('quotation.branch')" v-model:branch-id="branchId"
id="select-branch-issuer" v-model:customer-branch-id="quotationFormData.customerBranchId"
for="select-branch-issuer" @add-customer="triggerSelectTypeCustomerd()"
style="width: 300px"
class="q-mr-md"
outlined
dense
/>
<q-select
v-model="selectedCustomer"
:options="[{ label: 'Customer 1', value: 'Customer 1' }]"
:label="$t('quotation.customer')"
id="select-customer"
for="select-customer"
style="width: 300px"
outlined
dense
/> />
</header> </header>
@ -164,7 +282,11 @@ onMounted(async () => {
toggleWorker ? $t('general.specify') : $t('general.noSpecify') toggleWorker ? $t('general.specify') : $t('general.noSpecify')
}} }}
</div> </div>
<AddButton icon-only class="q-ml-auto" @click.stop="" /> <AddButton
icon-only
class="q-ml-auto"
@click.stop="triggerSelectEmployeeDialog"
/>
</template> </template>
<div class="surface-1 q-pa-md full-width"> <div class="surface-1 q-pa-md full-width">
@ -203,23 +325,22 @@ onMounted(async () => {
{{ $t('quotation.productList') }} {{ $t('quotation.productList') }}
</span> </span>
</div> </div>
<AddButton icon-only class="q-ml-auto" @click.stop="" /> <AddButton
icon-only
class="q-ml-auto"
@click.stop="triggerProductServiceDialog"
/>
</template> </template>
<div class="surface-1 q-pa-md full-width"> <div class="surface-1 q-pa-md full-width">
<ProductItem <ProductItem
:rows="[ :rows="
{ rows.map((p) => ({
code: '123456', code: p.subtitle,
list: 'aaa', name: p.title,
type: 'product', }))
amount: 0, "
pricePerUnit: 0,
discount: 0,
tax: 0,
sumPrice: 0,
},
]"
/> />
{{ console.log(rows) }}
</div> </div>
</q-expansion-item> </q-expansion-item>
@ -267,38 +388,6 @@ onMounted(async () => {
/> />
</div> </div>
</q-expansion-item> </q-expansion-item>
<!-- <AppBox bordered style="padding: var(--size-3)">
<div class="row items-center q-mb-sm">
<span style="flex: 1">
{{ $t('quotation.employeeList') }}
<q-toggle
v-model="toggleWorker"
id="toggle-status"
size="md"
padding="none"
class="q-ml-md"
dense
/>
</span>
<AddButton icon-only />
</div>
<AppBox class="surface-2 worker-list" v-if="toggleWorker" bordered>
<WorkerItem
v-for="_ in Array(20)"
:data="{
no: 1,
refNo: 'CC6613334',
nationality: 'Thai',
birthDate: '1 May 2001',
age: '23 Years',
fullName: 'Methapon Metanipat',
docExpireDate: '16 May 2025',
}"
color="male"
/>
</AppBox>
</AppBox> -->
</div> </div>
</section> </section>
@ -335,6 +424,94 @@ onMounted(async () => {
<SaveButton solid /> <SaveButton solid />
</div> </div>
</footer> </footer>
<!-- SEC: Dialog -->
<!-- add employee quotation -->
<DialogForm
:title="$t('general.select', { msg: $t('quotation.employeeList') })"
v-model:modal="pageState.employeeModal"
:submit-label="$t('general.select', { msg: $t('quotation.employee') })"
submit-icon="mdi-check"
height="75vh"
>
<section class="col row scroll">
<SelectZone
v-model:selected-item="selectedEmployee"
:items="[
{
name: 'มิเคล่า สุวรรณดี',
gender: 'female',
telephoneNo: '0621249602',
code: 'CORP000000-1-01-240001',
birthDate: '16 ปี 11 เดือน 5 วัน',
},
{
name: 'มิลิเซนต์ สุวรรณดี',
gender: 'female',
telephoneNo: '0621249666',
code: 'CORP000000-1-01-240002',
birthDate: '19 ปี 2 เดือน 2 วัน',
},
{
name: 'ไรคาร์ด พวงศรี',
gender: 'male',
telephoneNo: '0621249777',
code: 'CORP000000-1-01-240003',
birthDate: '39 ปี 5 เดือน 2 วัน',
},
]"
>
<template #top>
<AddButton
icon-only
@click="
() => {
triggerCreateEmployee();
}
"
/>
</template>
<template #data="{ item }">
<PersonCard
noAction
prefixId="asda"
class="full-width"
:data="{
name: item.name,
code: item.code,
female: item.gender === 'female',
male: item.gender === 'male',
img: '/images/employee-avatar.png',
detail: [
{ icon: 'mdi-phone-outline', value: item.telephoneNo },
{ icon: 'mdi-clock-outline', value: item.birthDate },
],
}"
></PersonCard>
</template>
</SelectZone>
</section>
</DialogForm>
<!-- add product service -->
<ProductServiceForm
v-model="pageState.productServiceModal"
v-model:product-group="productGroup"
v-model:product-list="productList"
v-model:service-list="serviceList"
@submit="
(nodes) => {
rows = convertToTable(nodes);
pageState.productServiceModal = false;
}
"
@select-group="
async (id) => {
await getAllService(id);
await getAllProduct(id);
}
"
></ProductServiceForm>
</div> </div>
</template> </template>