feat(04): role control

This commit is contained in:
puriphatt 2024-08-20 10:44:11 +07:00
parent 73bbc07e82
commit b55620b3d4

View file

@ -39,7 +39,7 @@ import useFlowStore from 'stores/flow';
import useMyBranchStore from 'stores/my-branch'; import useMyBranchStore from 'stores/my-branch';
import { dateFormat } from 'src/utils/datetime'; import { dateFormat } from 'src/utils/datetime';
import { formatNumberDecimal } from 'stores/utils'; import { formatNumberDecimal, isRoleInclude } from 'stores/utils';
const userBranchStore = useMyBranchStore(); const userBranchStore = useMyBranchStore();
@ -145,6 +145,27 @@ 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 priceDisplay = computed(() => ({
price: !isRoleInclude(['agency']),
agentPrice: isRoleInclude([
'admin',
'head_of_admin',
'system',
'owner',
'accountant',
'agency',
]),
serviceCharge: isRoleInclude([
'admin',
'head_of_admin',
'system',
'owner',
'accountant',
]),
}));
const actionDisplay = computed(() =>
isRoleInclude(['admin', 'head_of_admin', 'system', 'owner', 'accountant']),
);
const holdDialog = ref(false); const holdDialog = ref(false);
const imageDialog = ref(false); const imageDialog = ref(false);
const currentNode = ref<ProductGroup>(); const currentNode = ref<ProductGroup>();
@ -164,14 +185,14 @@ const treeProductTypeAndGroup = computed(() => {
type: 'group', type: 'group',
children: children:
item.id === currentIdGrop.value item.id === currentIdGrop.value
? recordTreeProductType.value[currentIdGrop.value]?.map((x) => ({ ? (recordTreeProductType.value[currentIdGrop.value]?.map((x) => ({
...x, ...x,
type: 'type', type: 'type',
})) ?? [] })) ?? [])
: recordTreeProductType.value[item.id]?.map((x) => ({ : (recordTreeProductType.value[item.id]?.map((x) => ({
...x, ...x,
type: 'type', type: 'type',
})) ?? item._count.type > 0 })) ?? item._count.type > 0)
? [ ? [
{ {
id: '', id: '',
@ -1365,7 +1386,7 @@ watch(
</script> </script>
<template> <template>
<ButtonAddComponent style="z-index: 999"> <ButtonAddComponent v-if="actionDisplay" style="z-index: 999">
<q-fab-action <q-fab-action
v-if="productMode === 'group'" v-if="productMode === 'group'"
id="btn-add-product-group" id="btn-add-product-group"
@ -1495,6 +1516,7 @@ watch(
label-key="name" label-key="name"
children-key="children" children-key="children"
type-tree="product" type-tree="product"
:action="actionDisplay"
@select=" @select="
async (v) => { async (v) => {
if (v.type === 'group') { if (v.type === 'group') {
@ -2243,6 +2265,7 @@ watch(
flat flat
@click.stop @click.stop
:key="props.row.id" :key="props.row.id"
v-if="actionDisplay"
> >
<q-menu class="bordered"> <q-menu class="bordered">
<q-list v-close-popup> <q-list v-close-popup>
@ -2424,6 +2447,7 @@ watch(
group: 'var(--pink-6-hsl)', group: 'var(--pink-6-hsl)',
}[productMode] || 'var(--pink-6-hsl)' }[productMode] || 'var(--pink-6-hsl)'
" "
:action="actionDisplay"
@toggleStatus=" @toggleStatus="
triggerChangeStatus(props.row.id, props.row.status) triggerChangeStatus(props.row.id, props.row.status)
" "
@ -3046,6 +3070,7 @@ watch(
disable: props.row.status === 'INACTIVE', disable: props.row.status === 'INACTIVE',
}" }"
style="min-width: 50px" style="min-width: 50px"
v-if="priceDisplay.price"
> >
<div class="col app-text-muted-2 text-caption"> <div class="col app-text-muted-2 text-caption">
{{ $t('salePrice') }} {{ $t('salePrice') }}
@ -3062,6 +3087,7 @@ watch(
disable: props.row.status === 'INACTIVE', disable: props.row.status === 'INACTIVE',
}" }"
style="min-width: 50px" style="min-width: 50px"
v-if="priceDisplay.agentPrice"
> >
<div class="col app-text-muted-2 text-caption"> <div class="col app-text-muted-2 text-caption">
{{ $t('agentPrice') }} {{ $t('agentPrice') }}
@ -3076,11 +3102,12 @@ watch(
</div> </div>
</div> </div>
<div <div
class="tags tags-color-pink col-4 column ellipsis-2-lines" class="tags tags-color-pink col column ellipsis-2-lines"
:class="{ :class="{
disable: props.row.status === 'INACTIVE', disable: props.row.status === 'INACTIVE',
}" }"
style="min-width: 50px" style="min-width: 50px"
v-if="priceDisplay.serviceCharge"
> >
<div class="col app-text-muted-2 text-caption"> <div class="col app-text-muted-2 text-caption">
{{ $t('processingPrice') }} {{ $t('processingPrice') }}
@ -3141,6 +3168,7 @@ watch(
round round
flat flat
@click.stop @click.stop
v-if="actionDisplay"
> >
<q-menu class="bordered"> <q-menu class="bordered">
<q-list v-close-popup> <q-list v-close-popup>
@ -3301,6 +3329,8 @@ watch(
:key="row.id" :key="row.id"
:title="row.name" :title="row.name"
:isDisabled="row.status === 'INACTIVE' ? true : false" :isDisabled="row.status === 'INACTIVE' ? true : false"
:action="actionDisplay"
:priceDisplay="priceDisplay"
@toggleStatus=" @toggleStatus="
() => { () => {
triggerChangeStatus(row.id, row.status, row.type); triggerChangeStatus(row.id, row.status, row.type);
@ -3571,7 +3601,7 @@ watch(
noImageAction noImageAction
:active="currentStatusGroupType !== 'INACTIVE'" :active="currentStatusGroupType !== 'INACTIVE'"
hideFade hideFade
useToggle :useToggle="actionDisplay"
:readonly="!isEdit" :readonly="!isEdit"
:icon="editByTree === 'group' ? 'mdi-folder' : 'mdi-folder-table'" :icon="editByTree === 'group' ? 'mdi-folder' : 'mdi-folder-table'"
:fallbackCover="`/images/product-service-${editByTree}-banner.png`" :fallbackCover="`/images/product-service-${editByTree}-banner.png`"
@ -3616,6 +3646,7 @@ watch(
<div <div
class="q-py-md q-px-lg" class="q-py-md q-px-lg"
style="position: absolute; z-index: 99999; top: 0; right: 0" style="position: absolute; z-index: 99999; top: 0; right: 0"
v-if="actionDisplay"
> >
<div class="surface-1 row rounded"> <div class="surface-1 row rounded">
<UndoButton <UndoButton
@ -3810,7 +3841,7 @@ watch(
no-time-img no-time-img
:index="selectProduct.findIndex((v) => v.id === i.id)" :index="selectProduct.findIndex((v) => v.id === i.id)"
:isAddProduct="!!selectProduct.find((v) => v.id === i.id)" :isAddProduct="!!selectProduct.find((v) => v.id === i.id)"
:isSelected="true" :action="false"
:data="{ ...i, type: 'product' }" :data="{ ...i, type: 'product' }"
:title="i.name" :title="i.name"
:status="i.status === 'INACTIVE' ? true : false" :status="i.status === 'INACTIVE' ? true : false"
@ -3985,8 +4016,10 @@ watch(
<div class="q-mx-lg q-mt-lg"> <div class="q-mx-lg q-mt-lg">
<ProfileBanner <ProfileBanner
hideFade hideFade
useToggle :useToggle="actionDisplay"
:active="formDataProduct.status !== 'INACTIVE'" :active="formDataProduct.status !== 'INACTIVE'"
:title="formDataProduct.name"
:caption="formDataProduct.code"
icon="mdi-shopping" icon="mdi-shopping"
fallbackImg="/images/product-avatar.png" fallbackImg="/images/product-avatar.png"
color="var(--teal-10)" color="var(--teal-10)"
@ -4024,7 +4057,8 @@ watch(
> >
<div <div
class="surface-1 rounded row q-mx-lg q-my-md" class="surface-1 rounded row q-mx-lg q-my-md"
style="position: absolute; z-index: 999" style="position: absolute; z-index: 999; top: 0; right: 0"
v-if="actionDisplay"
> >
<UndoButton <UndoButton
v-if="infoProductEdit" v-if="infoProductEdit"
@ -4112,6 +4146,7 @@ watch(
v-model:agent-price="formDataProduct.agentPrice" v-model:agent-price="formDataProduct.agentPrice"
v-model:service-charge="formDataProduct.serviceCharge" v-model:service-charge="formDataProduct.serviceCharge"
dense dense
:priceDisplay="priceDisplay"
/> />
</div> </div>
</div> </div>
@ -4355,11 +4390,13 @@ watch(
<div class="q-mx-lg q-mt-lg"> <div class="q-mx-lg q-mt-lg">
<ProfileBanner <ProfileBanner
hideFade hideFade
useToggle :useToggle="actionDisplay"
:title="formDataProductService.name"
:caption="formDataProductService.code"
:active="formDataProductService.status !== 'INACTIVE'" :active="formDataProductService.status !== 'INACTIVE'"
:readonly="!infoServiceEdit" :readonly="!infoServiceEdit"
:toggleTitle="$t('formDialogTitleUseStatus')" :toggleTitle="$t('formDialogTitleUseStatus')"
:img="profileUrl || '/images/service-avatar-add.png'" :img="profileUrl || '/images/service-avatar.png'"
fallbackCover="/images/service-banner.png" fallbackCover="/images/service-banner.png"
:bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`" :bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
:menu="[ :menu="[
@ -4397,6 +4434,7 @@ watch(
<div <div
class="surface-1 rounded q-my-md q-mx-lg row" class="surface-1 rounded q-my-md q-mx-lg row"
style="position: absolute; z-index: 999; top: 0; right: 0" style="position: absolute; z-index: 999; top: 0; right: 0"
v-if="actionDisplay"
> >
<UndoButton <UndoButton
v-if="infoServiceEdit" v-if="infoServiceEdit"
@ -4481,6 +4519,7 @@ watch(
:readonly="!infoServiceEdit" :readonly="!infoServiceEdit"
v-model:work-items="workItems" v-model:work-items="workItems"
dense dense
:priceDisplay="priceDisplay"
@addProduct=" @addProduct="
async (index) => { async (index) => {
await fetchListOfProductIsAdd(currentIdType); await fetchListOfProductIsAdd(currentIdType);
@ -4688,6 +4727,7 @@ watch(
v-model:image-url="profileUrl as string" v-model:image-url="profileUrl as string"
:hidden-footer="!infoProductEdit && !infoServiceEdit" :hidden-footer="!infoProductEdit && !infoServiceEdit"
clearButton clearButton
:change-disabled="!actionDisplay"
> >
<template #error> <template #error>
<div class="full-height full-width" style="background: var(--surface-1)"> <div class="full-height full-width" style="background: var(--surface-1)">