Files
alla-allaos-fullstack/src/features/foundation/approval/mutations.ts
phaichayon 56683ee7b9 Hotfix Rule: Force Fresh Data After CRUD Mutation
Task-h not implements
2026-06-16 11:59:41 +07:00

117 lines
3.8 KiB
TypeScript

import { mutationOptions } from '@tanstack/react-query';
import { quotationDocumentKeys } from '@/features/crm/quotations/document/queries';
import { getQueryClient } from '@/lib/query-client';
import {
approveApproval,
cancelApproval,
rejectApproval,
returnApproval,
submitApproval,
submitQuotationForApproval
} from './service';
import { approvalKeys } from './queries';
import { quotationKeys } from '@/features/crm/quotations/api/queries';
import type { ApprovalActionPayload, SubmitApprovalPayload } from './types';
async function invalidateApprovalLists() {
await getQueryClient().invalidateQueries({ queryKey: approvalKeys.lists() });
}
async function invalidateApprovalDetail(id: string) {
await getQueryClient().invalidateQueries({ queryKey: approvalKeys.detail(id) });
}
async function invalidateQuotationQueries(quotationId: string) {
const queryClient = getQueryClient();
await Promise.all([
queryClient.invalidateQueries({ queryKey: quotationKeys.lists() }),
queryClient.invalidateQueries({ queryKey: quotationKeys.detail(quotationId) }),
queryClient.invalidateQueries({ queryKey: quotationDocumentKeys.data(quotationId) }),
queryClient.invalidateQueries({ queryKey: quotationDocumentKeys.preview(quotationId) })
]);
}
async function invalidateRelatedEntityQueries(approvalId: string) {
const queryClient = getQueryClient();
const cachedDetail = queryClient.getQueryData<{ approval: { request: { entityType: string; entityId: string } } }>(
approvalKeys.detail(approvalId)
);
if (cachedDetail?.approval.request.entityType === 'quotation') {
await invalidateQuotationQueries(cachedDetail.approval.request.entityId);
}
}
export const submitApprovalMutation = mutationOptions({
mutationFn: (data: SubmitApprovalPayload) => submitApproval(data),
onSettled: async (_data, error) => {
if (!error) {
await invalidateApprovalLists();
}
}
});
export const submitQuotationApprovalMutation = mutationOptions({
mutationFn: ({ id, remark }: { id: string; remark?: string }) => submitQuotationForApproval(id, remark),
onSettled: async (_data, error, variables) => {
if (!error) {
await Promise.all([invalidateApprovalLists(), invalidateQuotationQueries(variables.id)]);
}
}
});
export const cancelApprovalMutation = mutationOptions({
mutationFn: (id: string) => cancelApproval(id),
onSettled: async (_data, error, id) => {
if (!error) {
await Promise.all([
invalidateApprovalLists(),
invalidateApprovalDetail(id),
invalidateRelatedEntityQueries(id)
]);
}
}
});
export const approveApprovalMutation = mutationOptions({
mutationFn: ({ id, values }: { id: string; values: ApprovalActionPayload }) =>
approveApproval(id, values),
onSettled: async (_data, error, variables) => {
if (!error) {
await Promise.all([
invalidateApprovalLists(),
invalidateApprovalDetail(variables.id),
invalidateRelatedEntityQueries(variables.id)
]);
}
}
});
export const rejectApprovalMutation = mutationOptions({
mutationFn: ({ id, values }: { id: string; values: ApprovalActionPayload }) =>
rejectApproval(id, values),
onSettled: async (_data, error, variables) => {
if (!error) {
await Promise.all([
invalidateApprovalLists(),
invalidateApprovalDetail(variables.id),
invalidateRelatedEntityQueries(variables.id)
]);
}
}
});
export const returnApprovalMutation = mutationOptions({
mutationFn: ({ id, values }: { id: string; values: ApprovalActionPayload }) =>
returnApproval(id, values),
onSettled: async (_data, error, variables) => {
if (!error) {
await Promise.all([
invalidateApprovalLists(),
invalidateApprovalDetail(variables.id),
invalidateRelatedEntityQueries(variables.id)
]);
}
}
});