feat(ticket): support defect-class ticket workflows

This commit is contained in:
2026-06-26 00:50:52 +05:30
parent 8665762ba2
commit 1f8ca87bd0
21 changed files with 343 additions and 70 deletions

View File

@@ -86,7 +86,9 @@ function buildTicketListItem(
): TicketListItem | null {
if (
!event.id ||
!event.ticket_name ||
!event.status ||
!event.default_defect_class ||
event.detection_count === undefined ||
!event.updated_at
) {
@@ -95,9 +97,11 @@ function buildTicketListItem(
return {
id: event.id,
ticket_name: event.ticket_name,
chainage_id: event.chainage_id ?? null,
chainage_name: event.chainage_name ?? null,
status: event.status,
default_defect_class: event.default_defect_class,
assigned_to_name: event.assigned_to_name ?? null,
detection_count: event.detection_count,
created_by_name: event.created_by_name ?? null,
@@ -112,9 +116,12 @@ function mergeTicketListItem(
): TicketListItem {
return {
...current,
ticket_name: event.ticket_name ?? current.ticket_name,
chainage_id: event.chainage_id ?? current.chainage_id,
chainage_name: event.chainage_name ?? current.chainage_name,
status: event.status ?? current.status,
default_defect_class:
event.default_defect_class ?? current.default_defect_class,
assigned_to_name: event.assigned_to_name ?? current.assigned_to_name,
detection_count: event.detection_count ?? current.detection_count,
created_by_name: event.created_by_name ?? current.created_by_name,

View File

@@ -7,6 +7,7 @@ import { toast } from 'sonner';
import { ticketService } from '@/services/api';
import type {
AssignTicketPayload,
CloseTicketPayload,
ReviewRepairPayload,
SubmitRepairPayload,
SubmitRepairUploadPayload,
@@ -55,10 +56,22 @@ export function useTicketsQuery(params: UseTicketsQueryParams) {
});
}
export function useTicketDetailQuery(ticketId: string | undefined) {
export function useTicketDetailQuery(
ticketId: string | undefined,
defectClass: string | undefined,
) {
return useQuery({
queryKey: ticketKeys.detail(ticketId ?? ''),
queryFn: () => ticketService.getTicketDetail(ticketId as string),
queryKey: ticketKeys.detail(ticketId ?? '', defectClass),
queryFn: () =>
ticketService.getTicketDetail(ticketId as string, defectClass as string),
enabled: Boolean(ticketId && defectClass),
});
}
export function useTicketDefectClassesQuery(ticketId: string | undefined) {
return useQuery({
queryKey: ticketKeys.defectClasses(ticketId ?? ''),
queryFn: () => ticketService.getTicketDefectClasses(ticketId as string),
enabled: Boolean(ticketId),
});
}
@@ -90,10 +103,10 @@ export function useAssignTicketMutation(ticketId: string) {
return useMutation({
mutationFn: (payload: AssignTicketPayload) =>
ticketService.assignTicket(ticketId, payload),
onSuccess: (ticket) => {
onSuccess: (ticket, payload) => {
toast.success('Ticket assigned');
queryClient.setQueryData<TicketDetail>(
ticketKeys.detail(ticketId),
ticketKeys.detail(ticketId, payload.defect_class),
(current) => mergeTicketDetailResponse(current, ticket),
);
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
@@ -143,10 +156,10 @@ export function useSubmitRepairUploadMutation(ticketId: string) {
return useMutation({
mutationFn: (payload: SubmitRepairUploadPayload) =>
ticketService.submitRepairUpload(ticketId, payload),
onSuccess: (ticket) => {
onSuccess: (ticket, payload) => {
toast.success('Repair evidence uploaded');
queryClient.setQueryData<TicketDetail>(
ticketKeys.detail(ticketId),
ticketKeys.detail(ticketId, payload.defect_class),
(current) => mergeTicketDetailResponse(current, ticket),
);
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
@@ -166,7 +179,7 @@ export function useReviewRepairMutation(ticketId: string) {
payload.action === 'approve' ? 'Repair approved' : 'Repair rejected',
);
queryClient.setQueryData<TicketDetail>(
ticketKeys.detail(ticketId),
ticketKeys.detail(ticketId, payload.defect_class),
(current) => mergeTicketDetailResponse(current, ticket),
);
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
@@ -179,11 +192,12 @@ export function useCloseTicketMutation(ticketId: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => ticketService.closeTicket(ticketId),
onSuccess: (ticket) => {
mutationFn: (payload: CloseTicketPayload) =>
ticketService.closeTicket(ticketId, payload),
onSuccess: (ticket, payload) => {
toast.success('Ticket closed');
queryClient.setQueryData<TicketDetail>(
ticketKeys.detail(ticketId),
ticketKeys.detail(ticketId, payload.defect_class),
(current) => mergeTicketDetailResponse(current, ticket),
);
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });