feat: implement reject request cancellation dialog and functionality
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 9s

This commit is contained in:
puriphatt 2025-03-13 11:47:55 +07:00
parent 366e2f5da8
commit 0da23733ab
3 changed files with 115 additions and 5 deletions

View file

@ -11,6 +11,9 @@ import NoData from 'src/components/NoData.vue';
import TableRequestList from './TableRequestList.vue'; import TableRequestList from './TableRequestList.vue';
import PaginationComponent from 'src/components/PaginationComponent.vue'; import PaginationComponent from 'src/components/PaginationComponent.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue'; import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import DialogFormContainer from 'src/components/dialog/DialogFormContainer.vue';
import DialogHeader from 'src/components/dialog/DialogHeader.vue';
import FormCancel from './FormCancel.vue';
// NOTE: Stores & Type // NOTE: Stores & Type
import { useNavigator } from 'src/stores/navigator'; import { useNavigator } from 'src/stores/navigator';
@ -19,6 +22,7 @@ import useFlowStore from 'src/stores/flow';
import { useRequestList } from 'src/stores/request-list'; import { useRequestList } from 'src/stores/request-list';
import { RequestData, RequestDataStatus } from 'src/stores/request-list/types'; import { RequestData, RequestDataStatus } from 'src/stores/request-list/types';
import { dialogWarningClose } from 'src/stores/utils'; import { dialogWarningClose } from 'src/stores/utils';
import { CancelButton, SaveButton } from 'src/components/button';
const $q = useQuasar(); const $q = useQuasar();
const navigatorStore = useNavigator(); const navigatorStore = useNavigator();
@ -37,6 +41,9 @@ const pageState = reactive({
fieldSelected: [...column.map((v) => v.name)], fieldSelected: [...column.map((v) => v.name)],
gridView: false, gridView: false,
total: 0, total: 0,
rejectCancelDialog: false,
rejectCancelReason: '',
requestId: '',
}); });
const fieldSelectedOption = computed(() => { const fieldSelectedOption = computed(() => {
@ -93,6 +100,23 @@ function triggerView(opts: { requestData: RequestData }) {
window.open(url.toString(), '_blank'); window.open(url.toString(), '_blank');
} }
async function submitRejectCancel() {
const res = await requestListStore.rejectRequest(pageState.requestId, {
reason: pageState.rejectCancelReason,
});
if (res) {
const indexRequest = data.value?.findIndex(
(v) => v.id === pageState.requestId,
);
data.value[indexRequest].rejectRequestCancel = true;
data.value[indexRequest].rejectRequestCancelReason =
pageState.rejectCancelReason;
pageState.rejectCancelDialog = false;
}
}
onMounted(async () => { onMounted(async () => {
pageState.gridView = $q.screen.lt.md ? true : false; pageState.gridView = $q.screen.lt.md ? true : false;
navigatorStore.current.title = 'requestList.title'; navigatorStore.current.title = 'requestList.title';
@ -357,6 +381,13 @@ watch([() => pageState.inputSearch, () => pageState.statusFilter], () => {
:visible-columns="pageState.fieldSelected" :visible-columns="pageState.fieldSelected"
@view="(data) => triggerView({ requestData: data })" @view="(data) => triggerView({ requestData: data })"
@delete="(data) => triggerCancel(data.id)" @delete="(data) => triggerCancel(data.id)"
@reject-cancel="
(data) => {
pageState.rejectCancelDialog = true;
pageState.rejectCancelReason = '';
pageState.requestId = data.id;
}
"
/> />
<template v-slot:loading> <template v-slot:loading>
<div <div
@ -409,6 +440,36 @@ watch([() => pageState.inputSearch, () => pageState.statusFilter], () => {
</footer> </footer>
</div> </div>
</section> </section>
<DialogFormContainer
width="60vw"
height="40vh"
v-model="pageState.rejectCancelDialog"
@submit="() => submitRejectCancel()"
>
<template #header>
<DialogHeader :title="$t('requestList.status.work.RejectCancel')" />
</template>
<section class="col q-pa-md scroll">
<FormCancel v-model:reason="pageState.rejectCancelReason" />
</section>
<template #footer>
<CancelButton
class="q-ml-auto"
outlined
@click="() => (pageState.rejectCancelDialog = false)"
/>
<SaveButton
label="ยืนยัน"
class="q-ml-sm"
icon="mdi-check"
solid
type="submit"
/>
</template>
</DialogFormContainer>
</div> </div>
</template> </template>
<style></style> <style></style>

View file

@ -182,6 +182,7 @@ async function triggerChangeStatusWork(step: Step, responsibleUserId?: string) {
if (step.workStatus === 'RejectCancel') { if (step.workStatus === 'RejectCancel') {
pageState.rejectCancelDialog = true; pageState.rejectCancelDialog = true;
pageState.rejectCancelReason = '';
pageState.requestWorkId = step.requestWorkId; pageState.requestWorkId = step.requestWorkId;
return; return;
} }
@ -971,7 +972,7 @@ async function submitRejectCancel() {
<DialogFormContainer <DialogFormContainer
width="60vw" width="60vw"
height="50%" height="40vh"
v-model="pageState.rejectCancelDialog" v-model="pageState.rejectCancelDialog"
@submit="() => submitRejectCancel()" @submit="() => submitRejectCancel()"
> >

View file

@ -32,6 +32,7 @@ const props = withDefaults(
defineEmits<{ defineEmits<{
(e: 'view', data: RequestData): void; (e: 'view', data: RequestData): void;
(e: 'delete', data: RequestData): void; (e: 'delete', data: RequestData): void;
(e: 'rejectCancel', data: RequestData): void;
}>(); }>();
function responsiblePerson(quotation: QuotationFull): CreatedBy[] | undefined { function responsiblePerson(quotation: QuotationFull): CreatedBy[] | undefined {
@ -188,15 +189,24 @@ function getEmployeeName(
props.row.customerRequestCancel && props.row.customerRequestCancel &&
props.row.requestDataStatus !== RequestDataStatus.Canceled props.row.requestDataStatus !== RequestDataStatus.Canceled
" "
:hsla-color="'--red-5-hsl'" :hsla-color="
props.row.rejectRequestCancel ? '--blue-6-hsl' : '--red-5-hsl'
"
:title="
props.row.rejectRequestCancel
? $t('requestList.status.RejectedCancel') || '-'
: $t(`requestList.status.CancelRequested`) || '-'
"
class="q-ml-sm" class="q-ml-sm"
:title="$t(`requestList.status.CancelRequested`) || '-'"
> >
<template #append> <template #append>
<q-tooltip> <q-tooltip>
{{ {{
props.row.customerRequestCancelReason || props.row.rejectRequestCancel
$t('general.noReason') ? props.row.rejectRequestCancelReason ||
$t('general.noReason')
: props.row.customerRequestCancelReason ||
$t('general.noReason')
}} }}
</q-tooltip> </q-tooltip>
</template> </template>
@ -220,11 +230,15 @@ function getEmployeeName(
hide-view hide-view
hide-delete hide-delete
use-cancel use-cancel
:use-reject-cancel="
props.row.customerRequestCancel && !props.row.rejectRequestCancel
"
:disable-cancel=" :disable-cancel="
props.row.requestDataStatus === RequestDataStatus.Canceled || props.row.requestDataStatus === RequestDataStatus.Canceled ||
props.row.requestDataStatus === RequestDataStatus.Completed props.row.requestDataStatus === RequestDataStatus.Completed
" "
@cancel="$emit('delete', props.row)" @cancel="$emit('delete', props.row)"
@reject-cancel="$emit('rejectCancel', props.row)"
/> />
</q-td> </q-td>
</q-tr> </q-tr>
@ -242,6 +256,10 @@ function getEmployeeName(
hide-kebab-edit hide-kebab-edit
hide-kebab-delete hide-kebab-delete
use-cancel use-cancel
class="full-height"
:use-reject-cancel="
props.row.customerRequestCancel && !props.row.rejectRequestCancel
"
:disable-cancel=" :disable-cancel="
props.row.requestDataStatus === RequestDataStatus.Canceled || props.row.requestDataStatus === RequestDataStatus.Canceled ||
props.row.requestDataStatus === RequestDataStatus.Completed props.row.requestDataStatus === RequestDataStatus.Completed
@ -285,6 +303,7 @@ function getEmployeeName(
]" ]"
@view="$emit('view', props.row)" @view="$emit('view', props.row)"
@cancel="$emit('delete', props.row)" @cancel="$emit('delete', props.row)"
@reject-cancel="$emit('rejectCancel', props.row)"
> >
<template v-slot:responsiblePerson="{ props: subProps }"> <template v-slot:responsiblePerson="{ props: subProps }">
<div class="col-4 app-text-muted q-pr-sm"> <div class="col-4 app-text-muted q-pr-sm">
@ -312,6 +331,35 @@ function getEmployeeName(
<span v-else>-</span> <span v-else>-</span>
</div> </div>
</template> </template>
<template #badge>
<BadgeComponent
v-if="
props.row.customerRequestCancel &&
props.row.requestDataStatus !== RequestDataStatus.Canceled
"
:hsla-color="
props.row.rejectRequestCancel ? '--blue-6-hsl' : '--red-5-hsl'
"
:title="
props.row.rejectRequestCancel
? $t('requestList.status.RejectedCancel') || '-'
: $t(`requestList.status.CancelRequested`) || '-'
"
>
<template #append>
<q-tooltip>
{{
props.row.rejectRequestCancel
? props.row.rejectRequestCancelReason ||
$t('general.noReason')
: props.row.customerRequestCancelReason ||
$t('general.noReason')
}}
</q-tooltip>
</template>
</BadgeComponent>
</template>
</QuotationCard> </QuotationCard>
</div> </div>
</template> </template>