Files
edr-platform/apps/edr-freight-web/backoffice/src/hooks/rule-engine/useRuleEngine.ts

130 lines
3.8 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import toast from "react-hot-toast";
import { QUERY_KEYS } from "@/constants/TANSTACK_QUEY_KEY";
import {
ruleEngineService,
type RuleEngineListParams,
} from "@/services/ruleEngine/ruleEngine.service";
import { RULE_ENGINE_SELECT_NONE } from "@/pages/ruleEngine/config/resources";
import type {
ApproveRatePayload,
RuleEngineRecord,
RuleEngineResourceSlug,
} from "@/types/rule-engine";
const CARGO_TYPE_PARENT_PAGE_SIZE = 500;
export const useRuleEngineList = (
resource: RuleEngineResourceSlug,
params: RuleEngineListParams,
) =>
useQuery({
queryKey: [...QUERY_KEYS.RULE_ENGINE.list(resource), params],
queryFn: () => ruleEngineService.list<RuleEngineRecord>(resource, params),
});
export const useCargoTypeParentOptions = (excludeId?: string, enabled = true) =>
useQuery({
queryKey: [
...QUERY_KEYS.RULE_ENGINE.list("cargo-types"),
"parent-options",
excludeId ?? "",
],
queryFn: () =>
ruleEngineService.list<RuleEngineRecord>("cargo-types", {
page: 1,
pageSize: CARGO_TYPE_PARENT_PAGE_SIZE,
}),
enabled,
select: (result) => {
const noneOption = { label: "None", value: RULE_ENGINE_SELECT_NONE };
const parents = (result.data ?? [])
.filter((row) => row.id && String(row.id) !== excludeId)
.map((row) => {
const name = String(row.cargoTypeName ?? "").trim();
const code = String(row.code ?? "").trim();
const label =
name && code ? `${name} (${code})` : name || code || String(row.id);
return { label, value: String(row.id) };
});
return [noneOption, ...parents];
},
});
export const useApprovalChain = (enabled: boolean) =>
useQuery({
queryKey: QUERY_KEYS.RULE_ENGINE.chain,
queryFn: () => ruleEngineService.getApprovalChain(),
enabled,
});
export const useRuleEngineMutations = (resource: RuleEngineResourceSlug) => {
const qc = useQueryClient();
const invalidate = () =>
qc.invalidateQueries({ queryKey: QUERY_KEYS.RULE_ENGINE.list(resource) });
const create = useMutation({
mutationFn: (payload: Record<string, unknown>) =>
ruleEngineService.create(resource, payload),
onSuccess: () => {
toast.success("Created successfully");
invalidate();
},
onError: () => toast.error("Failed to create record"),
});
const update = useMutation({
mutationFn: ({
id,
payload,
}: {
id: string;
payload: Record<string, unknown>;
}) => ruleEngineService.update(resource, id, payload),
onSuccess: () => {
toast.success("Updated successfully");
invalidate();
},
onError: () => toast.error("Failed to update record"),
});
const remove = useMutation({
mutationFn: (id: string) => ruleEngineService.remove(resource, id),
onSuccess: () => {
toast.success("Deleted successfully");
invalidate();
},
onError: () => toast.error("Failed to delete record"),
});
return { create, update, remove };
};
export const useRateWorkflow = () => {
const qc = useQueryClient();
const invalidate = () =>
qc.invalidateQueries({ queryKey: QUERY_KEYS.RULE_ENGINE.list("rates") });
const submit = useMutation({
mutationFn: (id: string) => ruleEngineService.submitRate(id),
onSuccess: () => {
toast.success("Rate submitted for approval");
invalidate();
},
onError: () => toast.error("Failed to submit rate"),
});
const approve = useMutation({
mutationFn: ({ id, payload }: { id: string; payload: ApproveRatePayload }) =>
ruleEngineService.approveRate(id, payload),
onSuccess: () => {
toast.success("Rate approved");
invalidate();
},
onError: () => toast.error("Failed to approve rate"),
});
return { submit, approve };
};