feat: 07 => implement status toggle functionality in AgenciesDialog and MainPage components

This commit is contained in:
puriphatt 2025-02-10 11:34:36 +07:00
parent f18d34b02d
commit 4994792597
3 changed files with 97 additions and 7 deletions

View file

@ -199,16 +199,23 @@ watch(
<ProfileBanner
prefix="dialog"
active
use-toggle
hide-fade
hide-active
:toggle-title="$t('status.title')"
:icon="'ph-building-office'"
:img="imageState.imageUrl || null"
:title="data.name"
:caption="data.code"
:color="`hsla(var(--green-8-hsl)/1)`"
:bg-color="`hsla(var(--green-8-hsl)/0.1)`"
v-model:toggle-status="data.status"
@view="viewImage"
@edit="editImage"
@update:toggle-status="
() => {
data.status = data.status === 'CREATED' ? 'INACTIVE' : 'CREATED';
}
"
/>
</div>
@ -317,9 +324,10 @@ watch(
>
<ProfileBanner
:prefix="data.name"
active
hide-fade
hide-active
use-toggle
:active="data.status !== 'INACTIVE'"
:toggle-title="$t('status.title')"
:icon="'ph-building-office'"
:title="data.name"
:caption="data.code"
@ -330,8 +338,10 @@ watch(
imageState.refreshImageState ? `?ts=${Date.now()}` : '',
) || null
"
v-model:toggle-status="data.status"
@view="viewImage"
@edit="editImage"
@update:toggle-status="$emit('changeStatus')"
/>
</div>
@ -354,7 +364,10 @@ watch(
}"
style="position: absolute; z-index: 999; top: 0; right: 0"
>
<div v-if="true" class="surface-1 row rounded">
<div
v-if="data.status !== 'INACTIVE'"
class="surface-1 row rounded"
>
<UndoButton
v-if="isEdit"
id="btn-info-basic-undo"

View file

@ -97,6 +97,7 @@ const blankFormData: InstitutionPayload = {
districtId: '',
provinceId: '',
selectedImage: '',
status: 'CREATED',
};
const refAgenciesDialog = ref();
@ -155,6 +156,7 @@ function assignFormData(data: Institution) {
districtId: data.districtId,
provinceId: data.provinceId,
selectedImage: data.selectedImage,
status: data.status,
};
}
@ -175,6 +177,7 @@ async function submit(opt?: { selectedImage: string }) {
subDistrictId: formData.value.subDistrictId,
districtId: formData.value.districtId,
provinceId: formData.value.provinceId,
status: formData.value.status,
};
if (
(pageState.isDrawerEdit && currAgenciesData.value?.id) ||
@ -250,6 +253,54 @@ async function fetchData(mobileFetch?: boolean) {
}
}
async function triggerChangeStatus(data?: Institution) {
const targetId = (data && data.id) || currAgenciesData.value?.id;
const targetStatus = (data && data.status) || currAgenciesData.value?.status;
if (data) assignFormData(data);
if (targetId === undefined || targetStatus === undefined) return;
return await new Promise((resolve, reject) => {
dialog({
color: targetStatus !== 'INACTIVE' ? 'warning' : 'info',
icon:
targetStatus !== 'INACTIVE'
? 'mdi-alert'
: 'mdi-message-processing-outline',
title: t('dialog.title.confirmChangeStatus'),
actionText:
targetStatus !== 'INACTIVE' ? t('general.close') : t('general.open'),
message:
targetStatus !== 'INACTIVE'
? t('dialog.message.confirmChangeStatusOff')
: t('dialog.message.confirmChangeStatusOn'),
action: async () => {
await changeStatus(targetId).then(resolve).catch(reject);
},
cancel: () => {},
});
});
}
async function changeStatus(id?: string) {
const targetId = id || currAgenciesData.value?.id;
if (targetId === undefined) return;
formData.value.status =
formData.value.status !== 'INACTIVE' ? 'INACTIVE' : 'ACTIVE';
const res = await institutionStore.editInstitution({
id: targetId,
...formData.value,
});
if (res) {
formData.value.status = res.status;
if (currAgenciesData.value) {
currAgenciesData.value.status = res.status;
}
await fetchData();
}
}
onMounted(async () => {
navigatorStore.current.title = 'agencies.title';
navigatorStore.current.path = [{ text: 'agencies.caption', i18n: true }];
@ -540,6 +591,18 @@ watch(
</div>
</template>
</q-img>
<q-badge
class="absolute-bottom-right no-padding"
style="
border-radius: 50%;
min-width: 8px;
min-height: 8px;
"
:style="{
background: `var(--${props.row.status === 'INACTIVE' ? 'stone-5' : 'green-6'})`,
}"
></q-badge>
</q-avatar>
<span class="col q-pl-md">
<div>
@ -606,7 +669,6 @@ watch(
"
/>
<KebabAction
hide-toggle
:id-name="props.row.id"
:status="props.row.status"
@view="
@ -622,6 +684,7 @@ watch(
}
"
@delete="() => triggerDelete(props.row.id)"
@change-status="() => triggerChangeStatus(props.row)"
/>
</q-td>
</q-tr>
@ -649,6 +712,18 @@ watch(
</div>
</template>
</q-img>
<q-badge
class="absolute-bottom-right no-padding"
style="
border-radius: 50%;
min-width: 10px;
min-height: 10px;
"
:style="{
background: `var(--${props.row.status === 'INACTIVE' ? 'stone-5' : 'green-6'})`,
}"
></q-badge>
</q-avatar>
<span class="text-weight-bold column q-pl-md">
{{
@ -677,7 +752,6 @@ watch(
"
/>
<KebabAction
hide-toggle
:id-name="props.row.id"
:status="props.row.status"
@view="
@ -693,6 +767,7 @@ watch(
}
"
@delete="() => triggerDelete(props.row.id)"
@change-status="() => triggerChangeStatus(props.row)"
/>
</nav>
</header>
@ -814,6 +889,7 @@ watch(
if (v) await submit({ selectedImage: v });
}
"
@change-status="triggerChangeStatus"
:readonly="!pageState.isDrawerEdit"
:isEdit="pageState.isDrawerEdit"
v-model="pageState.addModal"

View file

@ -40,7 +40,7 @@ export const useInstitution = defineStore('institution-store', () => {
params,
},
)
: await api.get<PaginationResult<Institution>>(`/institution`, {
: await api.get<PaginationResult<Institution>>('/institution', {
params,
});
@ -80,6 +80,7 @@ export const useInstitution = defineStore('institution-store', () => {
const res = await api.put(`/institution/${data.id}`, {
...data,
id: undefined,
group: undefined,
});
if (res.status < 400) {
return res.data;