refactor: แสดง tree
This commit is contained in:
parent
382ebe6e06
commit
7dc01a301d
1 changed files with 328 additions and 150 deletions
|
|
@ -55,6 +55,7 @@ import {
|
|||
Attributes,
|
||||
ServiceAndProduct,
|
||||
} from 'src/stores/product-service/types';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const flowStore = useFlowStore();
|
||||
const utilsStore = useUtilsStore();
|
||||
|
|
@ -94,7 +95,8 @@ const {
|
|||
fetchListProductAndService,
|
||||
} = productServiceStore;
|
||||
|
||||
const { workNameItems } = storeToRefs(productServiceStore);
|
||||
const { workNameItems, recordTreeProductType } =
|
||||
storeToRefs(productServiceStore);
|
||||
|
||||
const stat = ref<
|
||||
{
|
||||
|
|
@ -138,6 +140,30 @@ const stat = ref<
|
|||
const { t } = useI18n();
|
||||
const baseUrl = ref<string>(import.meta.env.VITE_API_BASE_URL);
|
||||
|
||||
const expandedTree = ref<string[]>([]);
|
||||
const editByTree = ref<'group' | 'type' | undefined>();
|
||||
const treeProductTypeAndGroup = computed(() => {
|
||||
const tempValue =
|
||||
productGroup.value?.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
type: 'group',
|
||||
children:
|
||||
item.id === currentId.value
|
||||
? recordTreeProductType.value[currentId.value]?.map((item) => ({
|
||||
...item,
|
||||
type: 'type',
|
||||
})) ?? []
|
||||
: recordTreeProductType.value[item.id]?.map((item) => ({
|
||||
...item,
|
||||
type: 'type',
|
||||
})) ?? [],
|
||||
};
|
||||
}) ?? [];
|
||||
|
||||
return tempValue;
|
||||
});
|
||||
|
||||
const inputSearch = ref('');
|
||||
const inputSearchProductAndService = ref('');
|
||||
|
||||
|
|
@ -747,21 +773,42 @@ async function deleteProductById(productId?: string) {
|
|||
persistent: true,
|
||||
message: t('deleteConfirmMessage'),
|
||||
action: async () => {
|
||||
if (productMode.value === 'type') {
|
||||
// Product Type
|
||||
await deleteProductServiceType(productId ?? currentIdType.value);
|
||||
await fetchListType();
|
||||
}
|
||||
if (productMode.value === 'group') {
|
||||
// Product Group
|
||||
const res = await deleteProductService(productId ?? currentId.value);
|
||||
if (res) {
|
||||
if (editByTree !== undefined) {
|
||||
if (editByTree.value === 'type') {
|
||||
// Product Type
|
||||
await deleteProductServiceType(productId ?? currentIdType.value);
|
||||
await fetchListType();
|
||||
}
|
||||
await fetchListGroups();
|
||||
if (editByTree.value === 'group') {
|
||||
// Product Group
|
||||
const res = await deleteProductService(productId ?? currentId.value);
|
||||
if (res) {
|
||||
}
|
||||
await fetchListGroups();
|
||||
}
|
||||
|
||||
flowStore.rotate();
|
||||
calculateStats();
|
||||
editByTree.value = undefined;
|
||||
drawerInfo.value = false;
|
||||
} else {
|
||||
if (productMode.value === 'type') {
|
||||
// Product Type
|
||||
await deleteProductServiceType(productId ?? currentIdType.value);
|
||||
await fetchListType();
|
||||
}
|
||||
if (productMode.value === 'group') {
|
||||
// Product Group
|
||||
const res = await deleteProductService(productId ?? currentId.value);
|
||||
if (res) {
|
||||
}
|
||||
await fetchListGroups();
|
||||
}
|
||||
|
||||
flowStore.rotate();
|
||||
calculateStats();
|
||||
drawerInfo.value = false;
|
||||
}
|
||||
flowStore.rotate();
|
||||
calculateStats();
|
||||
drawerInfo.value = false;
|
||||
},
|
||||
cancel: () => {},
|
||||
});
|
||||
|
|
@ -1163,6 +1210,10 @@ onMounted(async () => {
|
|||
|
||||
calculateStats();
|
||||
await fetchListGroups();
|
||||
|
||||
console.log(treeProductTypeAndGroup.value);
|
||||
|
||||
console.log('ddd');
|
||||
flowStore.rotate();
|
||||
});
|
||||
|
||||
|
|
@ -1341,153 +1392,248 @@ watch(inputSearchProductAndService, async () => {
|
|||
</div>
|
||||
|
||||
<div class="col" style="position: relative">
|
||||
<div class="scroll" style="position: absolute; inset: 0">
|
||||
<!-- <q-tree
|
||||
:nodes="treeData"
|
||||
node-key="id"
|
||||
label-key="name"
|
||||
children-key="branch"
|
||||
style="color: var(--foreground)"
|
||||
>
|
||||
<template #default-header="{ node }">
|
||||
<div
|
||||
class="row items-center justify-between full-width no-wrap"
|
||||
>
|
||||
<span>{{ node.name }}</span>
|
||||
<div
|
||||
class="row q-gutter-xs items-center no-wrap"
|
||||
@click.stop
|
||||
>
|
||||
<div
|
||||
class="q-pa-md scroll surface-1"
|
||||
style="position: absolute; inset: 0"
|
||||
>
|
||||
<q-tree
|
||||
:nodes="treeProductTypeAndGroup"
|
||||
node-key="id"
|
||||
label-key="name"
|
||||
children-key="children"
|
||||
v-model:expanded="expandedTree"
|
||||
>
|
||||
<template #default-header="{ node }">
|
||||
<div
|
||||
@click.stop="
|
||||
async () => {
|
||||
if (node.type === 'group' && node._count.type > 0) {
|
||||
pathGroupName = node.name;
|
||||
currentId = node.id;
|
||||
productMode = 'type';
|
||||
await fetchListType();
|
||||
expandedTree.push(node.id);
|
||||
flowStore.rotate();
|
||||
}
|
||||
}
|
||||
"
|
||||
class="column full-width items-center no-wrap"
|
||||
:class="{
|
||||
'cursor-pointer':
|
||||
node.type === 'group' && node._count.type > 0,
|
||||
}"
|
||||
>
|
||||
<div class="col row full-width">
|
||||
<div class="col-9">{{ node.name }}</div>
|
||||
<div class="col no-wrap">
|
||||
<q-btn
|
||||
v-if="node.isHeadOffice"
|
||||
:id="`create-sub-branch-btn-${node.name}`"
|
||||
@click.stop=""
|
||||
icon="mdi-file-plus-outline"
|
||||
size="sm"
|
||||
dense
|
||||
round
|
||||
flat
|
||||
icon="mdi-eye-outline"
|
||||
:id="`btn-tree-eye-${node.name}`"
|
||||
size="sm"
|
||||
dense
|
||||
round
|
||||
flat
|
||||
@click.stop="
|
||||
() => {
|
||||
if (node.type === 'type') {
|
||||
editByTree = 'type';
|
||||
currentStatusProduct =
|
||||
node.status === 'INACTIVE';
|
||||
clearFormGroup();
|
||||
currentIdType = node.id;
|
||||
assignFormDataGroup(node);
|
||||
isEdit = false;
|
||||
drawerInfo = true;
|
||||
}
|
||||
if (node.type === 'group') {
|
||||
editByTree = 'group';
|
||||
currentStatusProduct =
|
||||
node.status === 'INACTIVE';
|
||||
clearFormGroup();
|
||||
assignFormDataGroup(node);
|
||||
isEdit = false;
|
||||
currentId = node.id;
|
||||
drawerInfo = true;
|
||||
}
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
|
||||
<q-btn
|
||||
:id="`view-detail-btn-${node.name}`"
|
||||
icon="mdi-dots-vertical"
|
||||
size="sm"
|
||||
dense
|
||||
round
|
||||
flat
|
||||
icon="mdi-dots-vertical"
|
||||
:id="`btn-tree-dots-${node.name}`"
|
||||
size="sm"
|
||||
dense
|
||||
round
|
||||
flat
|
||||
@click.stop
|
||||
:key="node.id"
|
||||
>
|
||||
<q-menu class="bordered">
|
||||
<q-list v-close-popup>
|
||||
<q-item
|
||||
v-close-popup
|
||||
clickable
|
||||
:id="`view-detail-btn-${node.name}-view`"
|
||||
@click.stop="
|
||||
() => {
|
||||
editByTree = node.type;
|
||||
if (node.type === 'type') {
|
||||
currentStatusProduct =
|
||||
node.status === 'INACTIVE';
|
||||
clearFormGroup();
|
||||
currentIdType = node.id;
|
||||
assignFormDataGroup(node);
|
||||
isEdit = false;
|
||||
drawerInfo = true;
|
||||
}
|
||||
if (node.type === 'group') {
|
||||
currentStatusProduct =
|
||||
node.status === 'INACTIVE';
|
||||
clearFormGroup();
|
||||
assignFormDataGroup(node);
|
||||
isEdit = false;
|
||||
currentId = node.id;
|
||||
drawerInfo = true;
|
||||
}
|
||||
}
|
||||
"
|
||||
dense
|
||||
class="row q-py-sm"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-menu class="bordered">
|
||||
<q-list v-close-popup>
|
||||
<q-item
|
||||
:id="`view-detail-btn-${node.name}-view`"
|
||||
@click.stop="
|
||||
|
||||
"
|
||||
clickable
|
||||
dense
|
||||
class="row q-py-sm"
|
||||
style="white-space: nowrap"
|
||||
>
|
||||
<q-icon
|
||||
<q-icon
|
||||
name="mdi-eye-outline"
|
||||
class="col-3"
|
||||
size="xs"
|
||||
style="color: hsl(var(--green-6-hsl))"
|
||||
/>
|
||||
<span
|
||||
class="col-9 q-px-md flex items-center"
|
||||
>
|
||||
/>
|
||||
<span class="col-9 q-px-md flex items-center">
|
||||
{{ $t('viewDetail') }}
|
||||
</span>
|
||||
</q-item>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
:id="`view-detail-btn-${node.name}-edit`"
|
||||
clickable
|
||||
dense
|
||||
class="row q-py-sm"
|
||||
style="white-space: nowrap"
|
||||
@click="
|
||||
() => {
|
||||
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-icon
|
||||
name="mdi-pencil-outline"
|
||||
class="col-3"
|
||||
size="xs"
|
||||
style="color: hsl(var(--cyan-6-hsl))"
|
||||
/>
|
||||
<span
|
||||
class="col-9 q-px-md flex items-center"
|
||||
>
|
||||
{{ $t('edit') }}
|
||||
</span>
|
||||
</q-item>
|
||||
<q-item
|
||||
:id="`view-detail-btn-${node.name}-delete`"
|
||||
dense
|
||||
:clickable="node.status === 'CREATED'"
|
||||
class="row"
|
||||
:class="{
|
||||
'surface-3': node.status !== 'CREATED',
|
||||
'app-text-muted':
|
||||
node.status !== 'CREATED',
|
||||
}"
|
||||
style="white-space: nowrap"
|
||||
@click=""
|
||||
>
|
||||
<q-icon
|
||||
name="mdi-trash-can-outline"
|
||||
size="xs"
|
||||
class="col-3"
|
||||
:class="{
|
||||
'app-text-negative':
|
||||
node.status === 'CREATED',
|
||||
}"
|
||||
/>
|
||||
<span
|
||||
class="col-9 q-px-md flex items-center"
|
||||
>
|
||||
{{ $t('delete') }}
|
||||
</span>
|
||||
</q-item>
|
||||
<q-item
|
||||
:id="`view-detail-btn-${node.name}-edit`"
|
||||
v-close-popup
|
||||
clickable
|
||||
dense
|
||||
class="row q-py-sm"
|
||||
style="white-space: nowrap"
|
||||
@click.stop="
|
||||
() => {
|
||||
editByTree = node.type;
|
||||
if (node.type === 'type') {
|
||||
clearFormGroup();
|
||||
currentIdType = node.id;
|
||||
assignFormDataGroup(node);
|
||||
isEdit = true;
|
||||
drawerInfo = true;
|
||||
}
|
||||
if (node.type === 'group') {
|
||||
clearFormGroup();
|
||||
assignFormDataGroup(node);
|
||||
isEdit = true;
|
||||
currentId = node.id;
|
||||
|
||||
<q-item dense>
|
||||
<q-item-section class="q-py-sm">
|
||||
<div class="q-pa-sm surface-2 rounded">
|
||||
<q-toggle
|
||||
:id="`view-detail-btn-${node.name}-status`"
|
||||
dense
|
||||
size="sm"
|
||||
:label="
|
||||
node.status !== 'INACTIVE'
|
||||
drawerInfo = true;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-icon
|
||||
name="mdi-pencil-outline"
|
||||
class="col-3"
|
||||
size="xs"
|
||||
style="color: hsl(var(--cyan-6-hsl))"
|
||||
/>
|
||||
<span class="col-9 q-px-md flex items-center">
|
||||
{{ $t('edit') }}
|
||||
</span>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-close-popup
|
||||
:id="`view-detail-btn-${node.name}-delete`"
|
||||
dense
|
||||
:clickable="node.status === 'CREATED'"
|
||||
class="row"
|
||||
:class="{
|
||||
'surface-3': node.status !== 'CREATED',
|
||||
'app-text-muted': node.status !== 'CREATED',
|
||||
}"
|
||||
style="white-space: nowrap"
|
||||
@click.stop="
|
||||
() => {
|
||||
editByTree = node.type;
|
||||
|
||||
if (node.type === 'type') {
|
||||
deleteProductById(node.id);
|
||||
}
|
||||
if (node.type === 'group') {
|
||||
deleteProductById(node.id);
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-icon
|
||||
name="mdi-trash-can-outline"
|
||||
size="xs"
|
||||
class="col-3"
|
||||
:class="{
|
||||
'app-text-negative':
|
||||
node.status === 'CREATED',
|
||||
}"
|
||||
/>
|
||||
<span class="col-9 q-px-md flex items-center">
|
||||
{{ $t('delete') }}
|
||||
</span>
|
||||
</q-item>
|
||||
|
||||
<q-item dense>
|
||||
<q-item-section class="q-py-sm">
|
||||
<div class="q-pa-sm surface-2 rounded">
|
||||
<q-toggle
|
||||
:id="`view-detail-btn-${node.name}-status`"
|
||||
dense
|
||||
size="sm"
|
||||
:label="
|
||||
node.status !== 'INACTIVE'
|
||||
? $t('switchOnLabel')
|
||||
: $t('switchOffLabel')
|
||||
"
|
||||
@click="
|
||||
async () => {
|
||||
|
||||
|
||||
"
|
||||
@click.stop="
|
||||
async () => {
|
||||
if (node.type === 'type') {
|
||||
toggleStatusType(
|
||||
node.id,
|
||||
node.status,
|
||||
);
|
||||
}
|
||||
"
|
||||
:model-value="
|
||||
node.status === 'CREATED' ||
|
||||
node.status === 'ACTIVE'
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-tree> -->
|
||||
if (node.type === 'group') {
|
||||
toggleStatusGroup(
|
||||
node.id,
|
||||
node.status,
|
||||
);
|
||||
}
|
||||
}
|
||||
"
|
||||
:model-value="node.status !== 'INACTIVE'"
|
||||
/>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col row full-width">
|
||||
<div class="col- app-text-muted">{{ node.code }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -2978,14 +3124,46 @@ watch(inputSearchProductAndService, async () => {
|
|||
ref="formDialogRef"
|
||||
v-model:drawerOpen="drawerInfo"
|
||||
:title="
|
||||
$t(productMode === 'group' ? 'productGroup' : 'productType', {
|
||||
name: formDataGroup.code,
|
||||
})
|
||||
$t(
|
||||
editByTree !== undefined
|
||||
? editByTree === 'group'
|
||||
? 'productGroup'
|
||||
: editByTree === 'type'
|
||||
? 'productType'
|
||||
: undefined
|
||||
: productMode === 'group'
|
||||
? 'productGroup'
|
||||
: productMode === 'type'
|
||||
? 'productType'
|
||||
: undefined,
|
||||
{
|
||||
name: formDataGroup.code,
|
||||
},
|
||||
)
|
||||
"
|
||||
:undo="() => undoProductGroup()"
|
||||
:isEdit="isEdit"
|
||||
:editData="() => (isEdit = true)"
|
||||
:submit="() => (productMode === 'type' ? submitType() : submitGroup())"
|
||||
:submit="
|
||||
() => {
|
||||
if (editByTree !== undefined) {
|
||||
if (editByTree === 'group') {
|
||||
submitGroup();
|
||||
}
|
||||
if (editByTree === 'type') {
|
||||
submitType();
|
||||
}
|
||||
editByTree = undefined;
|
||||
} else {
|
||||
if (productMode === 'group') {
|
||||
submitGroup();
|
||||
}
|
||||
if (productMode === 'type') {
|
||||
submitType();
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
:delete-data="() => deleteProductById()"
|
||||
:close="() => (drawerInfo = false)"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue