fix: 01, 04 active tree & functional hold dialog

This commit is contained in:
puriphatt 2024-07-19 10:35:18 +00:00
parent bc894192a3
commit f23916b2ea
3 changed files with 202 additions and 43 deletions

View file

@ -636,6 +636,7 @@ watch(
<template #default-header="{ node }"> <template #default-header="{ node }">
<div <div
class="full-width q-py-sm" class="full-width q-py-sm"
:class="{ 'clickable-node': node.isHeadOffice }"
v-touch-hold.mouse="handleHold(node)" v-touch-hold.mouse="handleHold(node)"
@click.stop=" @click.stop="
() => { () => {
@ -1695,7 +1696,7 @@ watch(
</DrawerInfo> </DrawerInfo>
<q-dialog v-model="holdDialog" position="bottom"> <q-dialog v-model="holdDialog" position="bottom">
<div class="surface-1 full-width rounded column" style="height: 280px"> <div class="surface-1 full-width rounded column q-pb-md">
<div class="flex q-py-sm justify-center full-width"> <div class="flex q-py-sm justify-center full-width">
<div <div
class="rounded" class="rounded"
@ -1790,7 +1791,7 @@ watch(
<q-item-section>{{ $t('delete') }}</q-item-section> <q-item-section>{{ $t('delete') }}</q-item-section>
</q-item> </q-item>
<q-item clickable v-ripple v-close-popup> <q-item clickable v-ripple>
<q-item-section avatar> <q-item-section avatar>
<q-toggle <q-toggle
dense dense
@ -1914,30 +1915,4 @@ watch(
transform: translateY(-20px); transform: translateY(-20px);
opacity: 0; opacity: 0;
} }
:deep(i.q-icon.mdi.mdi-play.q-tree__arrow) {
color: hsl(var(--text-mute));
}
:deep(.q-tree__node-header:before) {
color: hsl(var(--text-mute));
}
:deep(.q-tree__node-header.relative-position.row.no-wrap.items-center) {
padding-block: 0px;
}
:deep(.q-tree__node-header.relative-position.row.no-wrap.items-center):has(
i.q-icon.mdi.mdi-play.q-tree__arrow
):hover {
background-color: hsla(var(--info-bg) / 0.1);
}
:deep(
.q-tree__node-header.relative-position.row.no-wrap.items-center.q-tree__node--link.q-hoverable.q-focusable:has(
i.q-icon.mdi.mdi-play.q-tree__arrow.q-tree__arrow--rotate
)
) {
background-color: hsla(var(--info-bg) / 0.1);
}
</style> </style>

View file

@ -140,6 +140,8 @@ const stat = ref<
const { t } = useI18n(); const { t } = useI18n();
const baseUrl = ref<string>(import.meta.env.VITE_API_BASE_URL); const baseUrl = ref<string>(import.meta.env.VITE_API_BASE_URL);
const holdDialog = ref(false);
const currentNode = ref<ProductGroup>();
const expandedTree = ref<string[]>([]); const expandedTree = ref<string[]>([]);
const editByTree = ref<'group' | 'type' | undefined>(); const editByTree = ref<'group' | 'type' | undefined>();
const treeProductTypeAndGroup = computed(() => { const treeProductTypeAndGroup = computed(() => {
@ -521,6 +523,14 @@ async function fetchListGroups() {
totalGroup.value = res.total; totalGroup.value = res.total;
maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value); maxPageGroup.value = Math.ceil(res.total / pageSizeGroup.value);
productGroup.value = res.result; productGroup.value = res.result;
// if(currentNode.value){
// currentNode.value.status = currentStatus.value === 'All'
// ? undefined
// : currentStatus.value === 'ACTIVE'
// ? 'ACTIVE'
// : 'INACTIVE',
// }
} }
} }
@ -1198,6 +1208,14 @@ function cloneData() {
}); });
} }
function handleHold(node: ProductGroup) {
if ($q.screen.gt.xs) return;
return function (props: unknown) {
holdDialog.value = true;
currentNode.value = node;
};
}
onMounted(async () => { onMounted(async () => {
utilsStore.currentTitle.title = 'mainProductTitle'; utilsStore.currentTitle.title = 'mainProductTitle';
utilsStore.currentTitle.path = [ utilsStore.currentTitle.path = [
@ -1396,26 +1414,27 @@ watch(
<template v-slot:before> <template v-slot:before>
<div class="surface-1 column full-height"> <div class="surface-1 column full-height">
<div <div
class="row bordered-b surface-3 q-px-md q-py-sm text-weight-bold items-center" class="row no-wrap full-width bordered-b text-weight-bold surface-3 items-center q-px-md q-py-sm"
:style="`min-height: ${$q.screen.gt.sm ? '57px' : '100.8px'}`" :style="`min-height: ${$q.screen.gt.sm ? '57px' : '100.8px'}`"
> >
<div class="col">ดการสาขาทงหมด</div> <div class="col ellipsis-2-lines">ดการสาขาทงหมด</div>
</div> </div>
<div class="col" style="position: relative"> <div class="col full-width">
<div <div class="q-pa-md">
class="q-pa-md scroll surface-1"
style="position: absolute; inset: 0"
>
<q-tree <q-tree
:nodes="treeProductTypeAndGroup" :nodes="treeProductTypeAndGroup"
color="transparent"
node-key="id" node-key="id"
label-key="name" label-key="name"
children-key="children" children-key="children"
v-model:expanded="expandedTree" v-model:expanded="expandedTree"
style="color: var(--foreground)"
> >
<template #default-header="{ node }"> <template #default-header="{ node }">
<div <div
class="full-width q-py-sm clickable-node"
v-touch-hold.mouse="handleHold(node)"
@click.stop=" @click.stop="
async () => { async () => {
if (node.type === 'group' && node._count.type > 0) { if (node.type === 'group' && node._count.type > 0) {
@ -1428,7 +1447,6 @@ watch(
} }
} }
" "
class="column full-width items-center no-wrap"
:class="{ :class="{
'cursor-pointer': 'cursor-pointer':
node.type === 'group' && node._count.type > 0, node.type === 'group' && node._count.type > 0,
@ -1436,9 +1454,29 @@ watch(
node.type === 'group' && node._count.type > 0, node.type === 'group' && node._count.type > 0,
}" }"
> >
<div class="col row full-width"> <div
<div class="col-9">{{ node.name }}</div> class="row col items-center justify-between full-width no-wrap"
<div class="col no-wrap"> >
<div class="col row">
<span
class="ellipsis col-12"
style="white-space: nowrap"
:class="{
'text-weight-bold': expandedTree[0] === node.id,
'app-text-info': expandedTree[0] === node.id,
}"
>
{{ node.name }}
</span>
<span class="app-text-muted text-caption ellipsis">
{{ node.code }}
</span>
</div>
<div
class="row q-gutter-xs items-center no-wrap"
v-if="$q.screen.gt.xs"
>
<q-btn <q-btn
icon="mdi-eye-outline" icon="mdi-eye-outline"
:id="`btn-tree-eye-${node.name}`" :id="`btn-tree-eye-${node.name}`"
@ -1642,10 +1680,6 @@ watch(
</q-btn> </q-btn>
</div> </div>
</div> </div>
<div class="col row full-width">
<div class="col- app-text-muted">{{ node.code }}</div>
</div>
</div> </div>
</template> </template>
</q-tree> </q-tree>
@ -1822,6 +1856,7 @@ watch(
<template v-slot:body="props"> <template v-slot:body="props">
<q-tr <q-tr
class="cursor-pointer"
:class="{ :class="{
'app-text-muted': props.row.status === 'INACTIVE', 'app-text-muted': props.row.status === 'INACTIVE',
'status-active': props.row.status !== 'INACTIVE', 'status-active': props.row.status !== 'INACTIVE',
@ -3719,6 +3754,154 @@ watch(
/> />
</template> </template>
</FormDialog> </FormDialog>
<q-dialog v-model="holdDialog" position="bottom">
<div class="surface-1 full-width rounded column q-pb-md">
<div class="flex q-py-sm justify-center full-width">
<div
class="rounded"
style="
width: 8%;
height: 4px;
background-color: hsla(0, 0%, 50%, 0.75);
"
></div>
</div>
<q-list v-if="currentNode">
<q-item
clickable
v-ripple
v-close-popup
@click.stop="
() => {
if (!currentNode) return;
if (currentNode.type === 'type') {
editByTree = 'type';
currentStatusProduct = currentNode.status === 'INACTIVE';
clearFormGroup();
currentIdType = currentNode.id;
assignFormDataGroup(currentNode);
isEdit = false;
drawerInfo = true;
}
if (currentNode.type === 'group') {
editByTree = 'group';
currentStatusProduct = currentNode.status === 'INACTIVE';
clearFormGroup();
assignFormDataGroup(currentNode);
isEdit = false;
currentId = currentNode.id;
drawerInfo = true;
}
}
"
>
<q-item-section avatar>
<q-icon
name="mdi-eye-outline"
style="color: hsl(var(--green-6-hsl))"
/>
</q-item-section>
<q-item-section>{{ $t('viewDetail') }}</q-item-section>
</q-item>
<q-item
clickable
v-ripple
v-close-popup
@click.stop="
() => {
if (!currentNode) return;
editByTree = currentNode.type as 'type' | 'group';
if (currentNode.type === 'type') {
clearFormGroup();
currentIdType = currentNode.id;
assignFormDataGroup(currentNode);
isEdit = true;
drawerInfo = true;
}
if (currentNode.type === 'group') {
clearFormGroup();
assignFormDataGroup(currentNode);
isEdit = true;
currentId = currentNode.id;
drawerInfo = true;
}
}
"
>
<q-item-section avatar>
<q-icon
name="mdi-pencil-outline"
style="color: hsl(var(--cyan-6-hsl))"
/>
</q-item-section>
<q-item-section>{{ $t('edit') }}</q-item-section>
</q-item>
<q-item
clickable
v-ripple
v-close-popup
@click.stop="
() => {
if (!currentNode) return;
editByTree = currentNode.type as 'type' | 'group';
if (currentNode.type === 'type') {
deleteProductById(currentNode.id);
}
if (currentNode.type === 'group') {
deleteProductById(currentNode.id);
}
}
"
>
<q-item-section avatar>
<q-icon name="mdi-trash-can-outline" class="app-text-negative" />
</q-item-section>
<q-item-section>{{ $t('delete') }}</q-item-section>
</q-item>
<q-item clickable v-ripple>
<q-item-section avatar>
<q-toggle
dense
:id="`view-detail-btn-${currentNode.name}-status`"
size="sm"
@click.stop="
async () => {
if (!currentNode) return;
if (currentNode.type === 'type') {
toggleStatusType(currentNode.id, currentNode.status);
currentNode.status === 'ACTIVE'
? (currentNode.status = 'INACTIVE')
: (currentNode.status = 'ACTIVE');
}
if (currentNode.type === 'group') {
toggleStatusGroup(currentNode.id, currentNode.status);
currentNode.status === 'ACTIVE'
? (currentNode.status = 'INACTIVE')
: (currentNode.status = 'ACTIVE');
}
}
"
:model-value="currentNode.status !== 'INACTIVE'"
/>
</q-item-section>
<q-item-section>
{{
currentNode.status !== 'INACTIVE'
? $t('switchOnLabel')
: $t('switchOffLabel')
}}
</q-item-section>
</q-item>
</q-list>
</div>
</q-dialog>
</template> </template>
<style scoped> <style scoped>

View file

@ -167,6 +167,7 @@ export type ProductGroup = {
detail: string; detail: string;
remark: string; remark: string;
status: Status; status: Status;
type: string;
createdBy: CreatedBy; createdBy: CreatedBy;
createdAt: string; createdAt: string;
updatedBy: UpdatedBy; updatedBy: UpdatedBy;