refactor: header status INACTIVE can't edit

This commit is contained in:
Net 2024-08-23 17:29:15 +07:00
parent 5d88c074c0
commit d5f1d5b378

View file

@ -1,11 +1,11 @@
<script setup lang="ts">
import { ref, watch, reactive } from 'vue';
import { ref, watch, reactive, handleError } from 'vue';
import { useI18n } from 'vue-i18n';
import { onMounted } from 'vue';
import { getUserId, getRole } from 'src/services/keycloak';
import { storeToRefs } from 'pinia';
import { useQuasar, type QTableProps } from 'quasar';
import ItemCard from 'components/ItemCard.vue';
import ProductCardComponent from 'components/04_product-service/ProductCardComponent.vue';
import StatCard from 'components/StatCardComponent.vue';
import DrawerInfo from 'components/DrawerInfo.vue';
@ -60,7 +60,6 @@ import {
ServiceById,
WorkItems,
Attributes,
ServiceAndProduct,
} from 'stores/product-service/types';
import { computed } from 'vue';
@ -168,43 +167,36 @@ const actionDisplay = computed(() =>
);
const holdDialog = ref(false);
const imageDialog = ref(false);
const currentNode = ref<ProductGroup>();
const currentNode = ref<ProductGroup & { type: string }>();
const expandedTree = ref<string[]>([]);
const editByTree = ref<'group' | 'type' | undefined>();
const treeProductTypeAndGroup = computed(() => {
const tempValue =
productGroup.value?.map((item) => {
return {
...item,
_count: {
type:
recordTreeProductType.value[item.id]?.length ?? item._count.type,
service: item._count.service,
product: item._count.product,
},
type: 'group',
children:
item.id === currentIdGrop.value
? (recordTreeProductType.value[currentIdGrop.value]?.map((x) => ({
const treeProductTypeAndGroup = computed(
() =>
productGroup.value?.map((item) => ({
...item,
_count: {
type: item._count.type,
service: item._count.service,
product: item._count.product,
},
type: 'group',
actionDisabled: item.status === 'INACTIVE',
children:
item.id === currentIdGrop.value
? (recordTreeProductType.value[currentIdGrop.value]?.map((x) => ({
...x,
type: 'type',
actionDisabled: item.status === 'INACTIVE',
})) ?? [])
: (recordTreeProductType.value[item.id]?.map((x) => ({
...x,
actionDisabled: item.status === 'INACTIVE',
type: 'type',
})) ?? [])
: (recordTreeProductType.value[item.id]?.map((x) => ({
...x,
type: 'type',
})) ?? item._count.type > 0)
? [
{
id: '',
name: '',
},
]
: [],
};
}) ?? [];
return tempValue;
});
})) ?? item._count.type > 0)
? [{ id: '', name: '' }]
: [],
})) ?? [],
);
const profileFileImg = ref<File | null>(null);
const refImageUpload = ref<InstanceType<typeof ImageUploadDialog>>();
@ -743,7 +735,7 @@ async function triggerChangeStatus(
: t('confirmChangeStatusOnMessage'),
action: async () => {
if (type === 'group' || productMode.value === 'group') {
await toggleStatusGroup(id, status as Status)
const res = await toggleStatusGroup(id, status as Status)
.then(resolve)
.catch(reject);
} else if (type === 'type' || productMode.value === 'type') {
@ -759,6 +751,9 @@ async function triggerChangeStatus(
.then(resolve)
.catch(reject);
}
currentNoAction.value = handleStatus();
console.log(currentNoAction.value);
},
cancel: () => {},
});
@ -969,6 +964,7 @@ async function assignFormDataProductService(id: string) {
}
}
const currentNoAction = ref(false);
const prevProduct = ref<ProductCreate>({
productTypeId: '',
remark: '',
@ -1288,17 +1284,19 @@ function cloneData() {
});
}
async function enterGroup(id: string, name: string) {
const currentStatusList = ref<Status[]>([]);
async function enterGroup(id: string, name: string, status: Status) {
expandedTree.value = [];
expandedTree.value.push(id);
pathGroupName.value = name;
currentIdGrop.value = id;
currentStatusList.value.push(status);
await fetchListType();
productMode.value = 'type';
flowStore.rotate();
}
async function enterType(id: string, name: string) {
async function enterType(id: string, name: string, status: Status) {
if (
expandedTree.value.length > 1 &&
expandedTree.value[expandedTree.value.length - 1] !== id
@ -1312,6 +1310,7 @@ async function enterType(id: string, name: string) {
currentIdType.value = id;
productMode.value = 'service';
productAndServiceTab.value = 'service';
currentStatusList.value.push(status);
await fetchListOfProduct();
await fetchListOfService();
@ -1319,14 +1318,26 @@ async function enterType(id: string, name: string) {
flowStore.rotate();
}
function handleHold(node: ProductGroup) {
if ($q.screen.gt.xs) return;
return function (props: unknown) {
holdDialog.value = true;
currentNode.value = node;
};
function handleStatus() {
let tempValue = false;
currentStatusList.value.forEach((item) => {
if (item === 'INACTIVE') {
tempValue = true;
}
});
return tempValue;
}
// function handleHold(node: ProductGroup & { type: string}) {
// if ($q.screen.gt.xs) return;
// return function (props: unknown) {
// holdDialog.value = true;
// currentNode.value = node;
// };
// }
onMounted(async () => {
utilsStore.currentTitle.title = 'mainProductTitle';
utilsStore.currentTitle.path = [
@ -1364,6 +1375,7 @@ watch(
currentIdGrop.value = '';
currentIdType.value = '';
filterStat.value = [];
currentStatusList.value = [];
},
},
];
@ -1378,13 +1390,19 @@ watch(
i18n: true,
argsi18n: { name: pathGroupName.value },
handler: () => {
currentIdType.value = '';
productMode.value = 'type';
filterStat.value = filterStat.value.filter((item) => {
return item !== 'type';
});
expandedTree.value.pop();
utilsStore.currentTitle.path.pop();
if (productMode.value === 'service') {
currentIdType.value = '';
productMode.value = 'type';
filterStat.value = filterStat.value.filter((item) => {
return item !== 'type';
});
currentStatusList.value.splice(1);
expandedTree.value.pop();
utilsStore.currentTitle.path.pop();
}
},
});
if (expandedTree.value.length === 0) {
@ -1436,10 +1454,19 @@ watch(
if (v) modeView.value = true;
},
);
watch([currentStatusList, productMode], () => {
currentNoAction.value = handleStatus();
console.log(currentStatusList.value);
});
</script>
<template>
<ButtonAddComponent v-if="actionDisplay" style="z-index: 999">
<ButtonAddComponent
v-if="actionDisplay && !currentNoAction"
style="z-index: 999"
>
<q-fab-action
v-if="productMode === 'group'"
id="btn-add-product-group"
@ -1571,11 +1598,13 @@ watch(
type-tree="product"
:action="actionDisplay"
@select="
async (v) => {
async (v: (typeof treeProductTypeAndGroup)[number]) => {
if (v.type === 'group') {
if (currentIdGrop !== v.id) {
filterStat.push('group');
await enterGroup(v.id, v.name);
currentStatusList = [];
await enterGroup(v.id, v.name, v.status);
return;
}
@ -1585,21 +1614,31 @@ watch(
expandedTree = expandedTree.filter((i) => v.id !== i);
currentIdGrop = '';
currentIdType = '';
currentStatusList = [];
productMode = 'group';
return;
}
}
if (v.type === 'type') {
currentStatusList = [];
if (v.actionDisabled) {
currentStatusList.push('INACTIVE');
}
if (!v.actionDisabled) {
currentStatusList.push('ACTIVE');
}
if (currentIdType !== v.id) {
filterStat.push('group', 'type');
await enterType(v.id, v.name);
await enterType(v.id, v.name, v.status);
return;
}
if (currentIdType === v.id) {
filterStat = filterStat.filter((item) => {
return item !== 'type';
});
currentStatusList.splice(1);
currentIdType = '';
productMode = 'type';
expandedTree.pop();
@ -1609,7 +1648,7 @@ watch(
}
"
@view="
(v) => {
(v: (typeof treeProductTypeAndGroup)[number]) => {
if (v.type === 'type') {
editByTree = 'type';
currentStatusProduct = v.status === 'INACTIVE';
@ -1631,8 +1670,8 @@ watch(
}
"
@edit="
(v) => {
editByTree = v.type;
(v: (typeof treeProductTypeAndGroup)[number]) => {
editByTree = v.type as typeof editByTree;
if (v.type === 'type') {
clearFormGroup();
currentIdType = v.id;
@ -1650,8 +1689,8 @@ watch(
}
"
@delete="
(v) => {
editByTree = v.type;
(v: (typeof treeProductTypeAndGroup)[number]) => {
editByTree = v.type as typeof editByTree;
if (v.type === 'type') {
deleteProductById(v.id);
@ -1662,323 +1701,24 @@ watch(
}
"
@change-status="
async (v) => {
async (v: (typeof treeProductTypeAndGroup)[number]) => {
console.log(currentStatusList);
if (v.type === 'type') {
triggerChangeStatus(v.id, v.status, v.type);
await triggerChangeStatus(v.id, v.status, v.type);
currentStatusList[0] =
v.status === 'INACTIVE' ? 'ACTIVE' : 'INACTIVE';
}
if (v.type === 'group') {
triggerChangeStatus(v.id, v.status, v.type);
await triggerChangeStatus(v.id, v.status, v.type);
currentStatusList[0] =
v.status === 'INACTIVE' ? 'ACTIVE' : 'INACTIVE';
}
}
"
/>
<!-- <q-tree
:nodes="treeProductTypeAndGroup"
color="transparent"
node-key="id"
label-key="name"
children-key="children"
v-model:expanded="expandedTree"
style="color: var(--foreground)"
>
<template #default-header="{ node }">
<div
class="full-width q-py-xs clickable-node"
:class="{
'cursor-pointer':
node.type === 'group' || node.type === 'type',
'active-node':
expandedTree[expandedTree.length - 1] === node.id,
}"
v-touch-hold.mouse="handleHold(node)"
@click.stop="
async () => {
if (node.type === 'group') {
if (currentIdGrop !== node.id) {
filterStat.push('group');
await enterGroup(node.id, node.name);
return;
}
if (currentIdGrop === node.id) {
expandedTree = [];
filterStat = [];
expandedTree = expandedTree.filter(
(i) => node.id !== i,
);
currentIdGrop = '';
currentIdType = '';
productMode = 'group';
return;
}
}
if (node.type === 'type') {
if (currentIdType !== node.id) {
filterStat.push('group', 'type');
await enterType(node.id, node.name);
return;
}
if (currentIdType === node.id) {
filterStat = filterStat.filter((item) => {
return item !== 'type';
});
currentIdType = '';
productMode = 'type';
expandedTree.pop();
return;
}
}
}
"
>
<div
class="row col items-center justify-between full-width no-wrap"
>
<q-icon
v-if="node.type === 'group' && node._count.type > 0"
name="mdi-triangle-down"
size="12px"
class="app-text-muted q-mr-md q-ml-sm"
:style="`rotate: ${expandedTree[0] === node.id ? '0deg' : '30deg'}`"
/>
<div
class="col row"
:class="{ 'q-pl-sm': node.type === 'type' }"
:style="`padding-left:${node.type === 'group' && node._count.type === 0 ? '36px' : ''}`"
>
<span
class="ellipsis col-12"
style="white-space: nowrap"
:class="{
'text-weight-bold':
expandedTree[expandedTree.length - 1] ===
node.id,
'app-text-info':
expandedTree[expandedTree.length - 1] ===
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 app-text-muted-2"
v-if="$q.screen.gt.xs"
>
<q-btn
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;
currentIdGrop = node.id;
drawerInfo = true;
}
}
"
/>
<q-btn
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;
currentIdGrop = node.id;
drawerInfo = true;
}
}
"
dense
class="row q-py-sm"
style="white-space: nowrap"
>
<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">
{{ $t('viewDetail') }}
</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;
currentIdGrop = node.id;
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.stop="
async () => {
if (node.type === 'type') {
triggerChangeStatus(
node.id,
node.status,
node.type,
);
}
if (node.type === 'group') {
triggerChangeStatus(
node.id,
node.status,
node.type,
);
}
}
"
:model-value="
node.status !== 'INACTIVE'
"
/>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</div>
</div>
</div>
</template>
</q-tree> -->
</div>
</div>
</div>
@ -2178,10 +1918,18 @@ watch(
async () => {
filterStat.push(productMode);
if (productMode === 'type') {
await enterType(props.row.id, props.row.name);
await enterType(
props.row.id,
props.row.name,
props.row.status,
);
}
if (productMode === 'group') {
await enterGroup(props.row.id, props.row.name);
await enterGroup(
props.row.id,
props.row.name,
props.row.status,
);
}
}
"
@ -2368,19 +2116,16 @@ watch(
</q-item>
<q-item
v-if="
props.row.status !== 'INACTIVE' &&
currentNoAction
"
:id="`view-detail-btn-${props.row.name}-edit`"
:class="{
'surface-3':
props.row.status === 'INACTIVE',
'app-text-muted':
props.row.status === 'INACTIVE',
}"
v-close-popup
clickable
dense
class="row q-py-sm"
style="white-space: nowrap"
:disable="props.row.status === 'INACTIVE'"
@click="
() => {
if (productMode === 'type') {
@ -2407,14 +2152,19 @@ watch(
name="mdi-pencil-outline"
class="col-3"
size="xs"
:style="`color: ${props.row.status !== 'INACTIVE' ? 'hsl(var(--cyan-6-hsl))' : 'none'}`"
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
v-if="
props.row.status !== 'INACTIVE' &&
currentNoAction
"
:id="`view-detail-btn-${props.row.name}-delete`"
dense
:disable="props.row.status !== 'CREATED'"
@ -2501,7 +2251,8 @@ watch(
:status="props.row.status"
:id="`enter-${props.row.name}`"
:for="`enter-${props.row.name}`"
:isDisabled="props.row.status === 'INACTIVE'"
:is-disabled="props.row.status === 'INACTIVE'"
:no-action="handleStatus()"
:color="
{
type: $q.dark.isActive
@ -2571,10 +2322,18 @@ watch(
async () => {
filterStat.push(productMode);
if (productMode === 'type') {
await enterType(props.row.id, props.row.name);
await enterType(
props.row.id,
props.row.name,
props.row.status,
);
}
if (productMode === 'group') {
await enterGroup(props.row.id, props.row.name);
await enterGroup(
props.row.id,
props.row.name,
props.row.status,
);
}
}
"
@ -3723,7 +3482,7 @@ watch(
>
<div
class="surface-1 row rounded"
v-if="currentStatusGroupType !== 'INACTIVE'"
v-if="currentStatusGroupType !== 'INACTIVE' && !currentNoAction"
>
<UndoButton
v-if="isEdit"
@ -4156,7 +3915,7 @@ watch(
<div
class="surface-1 rounded row q-mx-lg q-my-md"
style="position: absolute; z-index: 999; top: 0; right: 0"
v-if="actionDisplay"
v-if="actionDisplay && !currentNoAction"
>
<UndoButton
v-if="infoProductEdit"
@ -4532,7 +4291,7 @@ watch(
<div
class="surface-1 rounded q-my-md q-mx-lg row"
style="position: absolute; z-index: 999; top: 0; right: 0"
v-if="actionDisplay"
v-if="actionDisplay && !currentNoAction"
>
<UndoButton
v-if="infoServiceEdit"