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

This commit is contained in:
puriphatt 2025-03-13 09:47:12 +07:00
parent e1d1ee7d8b
commit c1adc9dee3
2 changed files with 99 additions and 14 deletions

View file

@ -20,6 +20,8 @@ const props = defineProps<{
imgUrl?: string;
requestCancel?: boolean;
requestCancelReason?: string;
rejectRequestCancel?: boolean;
rejectRequestCancelReason?: string;
installmentInfo?: {
total: number;
paid?: number;
@ -37,7 +39,9 @@ function changeableStatus(currentStatus?: RequestWorkStatus) {
case RequestWorkStatus.Ready:
case RequestWorkStatus.Waiting:
case RequestWorkStatus.InProgress:
return [RequestWorkStatus.Canceled];
return props.requestCancel && !props.rejectRequestCancel
? [RequestWorkStatus.Canceled, RequestWorkStatus.RejectCancel]
: [RequestWorkStatus.Canceled];
case RequestWorkStatus.Validate:
case RequestWorkStatus.Ended:
case RequestWorkStatus.Completed:
@ -45,12 +49,15 @@ function changeableStatus(currentStatus?: RequestWorkStatus) {
return [];
default:
if (props.readonly) return [];
const statuses = [
RequestWorkStatus.Ready,
RequestWorkStatus.Ended,
RequestWorkStatus.Canceled,
];
if (props.orderAble) {
return [
RequestWorkStatus.Ready,
RequestWorkStatus.Ended,
RequestWorkStatus.Canceled,
];
return props.requestCancel && !props.rejectRequestCancel
? [...statuses, RequestWorkStatus.RejectCancel]
: statuses;
} else {
return [RequestWorkStatus.Ended, RequestWorkStatus.Canceled];
}
@ -103,11 +110,19 @@ function changeableStatus(currentStatus?: RequestWorkStatus) {
v-if="requestCancel && !cancel"
:hsla-color="'--red-5-hsl'"
class="q-ml-sm"
:title="$t(`requestList.status.CancelRequested`) || '-'"
:title="
rejectRequestCancel
? $t('requestList.status.RejectedCancel') || '-'
: $t(`requestList.status.CancelRequested`) || '-'
"
>
<template #append>
<q-tooltip>
{{ requestCancelReason || $t('general.noReason') }}
{{
rejectRequestCancel
? rejectRequestCancelReason || $t('general.noReason')
: requestCancelReason || $t('general.noReason')
}}
</q-tooltip>
</template>
</BadgeComponent>
@ -171,10 +186,11 @@ function changeableStatus(currentStatus?: RequestWorkStatus) {
clickable
v-close-popup
class="row items-center"
:class="{ 'bordered-t': value === 'RejectCancel' }"
@click="
$emit('changeStatus', {
step: status,
requestWorkStatus: value,
requestWorkStatus: value as RequestWorkStatus,
})
"
>

View file

@ -11,10 +11,13 @@ import PropertiesExpansion from './PropertiesExpansion.vue';
import FormGroupHead from './FormGroupHead.vue';
import AvatarGroup from 'src/components/shared/AvatarGroup.vue';
import { StateButton } from 'components/button';
import { CancelButton, MainButton } from 'components/button';
import { CancelButton, MainButton, SaveButton } from 'components/button';
import DutyExpansion from './DutyExpansion.vue';
import MessengerExpansion from './MessengerExpansion.vue';
import RequestAction from './RequestAction.vue';
import DialogFormContainer from 'src/components/dialog/DialogFormContainer.vue';
import DialogHeader from 'src/components/dialog/DialogHeader.vue';
import FormCancel from './FormCancel.vue';
// NOTE: Store
import {
@ -104,6 +107,9 @@ const pageState = reactive({
hideMetaData: false,
currentStep: 1,
requestActionDialog: false,
rejectCancelDialog: false,
rejectCancelReason: '',
requestWorkId: '',
});
// NOTE: Function
@ -173,6 +179,13 @@ async function triggerChangeStatusWork(step: Step, responsibleUserId?: string) {
});
return;
}
if (step.workStatus === 'RejectCancel') {
pageState.rejectCancelDialog = true;
pageState.requestWorkId = step.requestWorkId;
return;
}
const res = await requestListStore.editStatusRequestWork(step);
if (res) {
const indexWork = workList.value?.findIndex(
@ -400,6 +413,30 @@ async function submitRequestAction(data: {
pageState.requestActionDialog = false;
}
}
async function submitRejectCancel() {
const current = route.params['requestListId'];
if (typeof current !== 'string') return;
const res = await requestListStore.rejectRequestWork(
current,
pageState.requestWorkId,
{
reason: pageState.rejectCancelReason,
},
);
if (res) {
const indexWork = workList.value?.findIndex(
(v) => v.id === pageState.requestWorkId,
);
workList.value[indexWork].rejectRequestCancel = true;
workList.value[indexWork].rejectRequestCancelReason =
pageState.rejectCancelReason;
pageState.rejectCancelDialog = false;
}
}
</script>
<template>
<div class="column surface-0 fullscreen" v-if="data">
@ -599,8 +636,8 @@ async function submitRequestAction(data: {
data.quotation?.invoice?.map((i: Invoice) => i.code)
"
@label-click="
(_: string, i: number) => {
if (!data) return;
(value: string, index: number | null) => {
if (!data || index === null) return;
data.quotation.isDebitNote
? goToDebitNote({
@ -609,8 +646,8 @@ async function submitRequestAction(data: {
})
: goToQuotation(data.quotation, {
tab: 'invoice',
id: data.quotation.invoice?.[i]?.id,
amount: data.quotation.invoice?.[i]?.amount,
id: data.quotation.invoice?.[index]?.id,
amount: data.quotation.invoice?.[index]?.amount,
});
}
"
@ -733,6 +770,8 @@ async function submitRequestAction(data: {
<ProductExpansion
:request-cancel="value.customerRequestCancel"
:request-cancel-reason="value.customerRequestCancelReason"
:reject-request-cancel="value.rejectRequestCancel"
:reject-request-cancel-reason="value.rejectRequestCancelReason"
:cancel="data.requestDataStatus === RequestDataStatus.Canceled"
:readonly="
data.requestDataStatus === RequestDataStatus.Canceled ||
@ -929,5 +968,35 @@ async function submitRequestAction(data: {
:responsible-district-id="data?.quotation.customerBranch.districtId || ''"
@submit="submitRequestAction"
/>
<DialogFormContainer
width="60vw"
height="50%"
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>
</template>
<style scoped></style>