feat(ticket): refine repair report and history timeline UI
This commit is contained in:
@@ -49,8 +49,10 @@ function patchTicketLists(
|
||||
ticket.id === eventId
|
||||
? {
|
||||
...ticket,
|
||||
...event,
|
||||
id: ticket.id,
|
||||
status: event.status ?? ticket.status,
|
||||
updated_at: event.timestamps?.updated_at ?? ticket.updated_at,
|
||||
chainage_id: event.chainage_id ?? ticket.chainage_id,
|
||||
video_id: event.video_id ?? ticket.video_id,
|
||||
}
|
||||
: ticket,
|
||||
),
|
||||
|
||||
@@ -9,6 +9,8 @@ import type {
|
||||
AssignTicketPayload,
|
||||
ReviewRepairPayload,
|
||||
SubmitRepairPayload,
|
||||
SubmitRepairUploadPayload,
|
||||
TicketDetail,
|
||||
TicketListParams,
|
||||
TicketStatus,
|
||||
} from '@/types';
|
||||
@@ -60,11 +62,24 @@ export function useTicketDetailQuery(ticketId: string | undefined) {
|
||||
export function useAssignableTicketUsersQuery(enabled: boolean) {
|
||||
return useQuery({
|
||||
queryKey: ticketKeys.assignableUsers(),
|
||||
queryFn: ticketService.getAssignableUsers,
|
||||
queryFn: () => ticketService.getAssignableUsers(),
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
|
||||
function mergeTicketDetailResponse(
|
||||
current: TicketDetail | undefined,
|
||||
next: TicketDetail,
|
||||
) {
|
||||
if (!current) return next;
|
||||
|
||||
return {
|
||||
...current,
|
||||
...next,
|
||||
history: next.history ?? current.history,
|
||||
};
|
||||
}
|
||||
|
||||
export function useAssignTicketMutation(ticketId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -73,7 +88,10 @@ export function useAssignTicketMutation(ticketId: string) {
|
||||
ticketService.assignTicket(ticketId, payload),
|
||||
onSuccess: (ticket) => {
|
||||
toast.success('Ticket assigned');
|
||||
queryClient.setQueryData(ticketKeys.detail(ticketId), ticket);
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to assign ticket'),
|
||||
@@ -87,7 +105,10 @@ export function useStartTicketMutation(ticketId: string) {
|
||||
mutationFn: () => ticketService.startTicket(ticketId),
|
||||
onSuccess: (ticket) => {
|
||||
toast.success('Ticket started');
|
||||
queryClient.setQueryData(ticketKeys.detail(ticketId), ticket);
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to start ticket'),
|
||||
@@ -102,13 +123,34 @@ export function useSubmitRepairMutation(ticketId: string) {
|
||||
ticketService.submitRepair(ticketId, payload),
|
||||
onSuccess: (ticket) => {
|
||||
toast.success('Repair submitted');
|
||||
queryClient.setQueryData(ticketKeys.detail(ticketId), ticket);
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to submit repair'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useSubmitRepairUploadMutation(ticketId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (payload: SubmitRepairUploadPayload) =>
|
||||
ticketService.submitRepairUpload(ticketId, payload),
|
||||
onSuccess: (ticket) => {
|
||||
toast.success('Repair evidence uploaded');
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to upload repair evidence'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useReviewRepairMutation(ticketId: string) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -119,7 +161,10 @@ export function useReviewRepairMutation(ticketId: string) {
|
||||
toast.success(
|
||||
payload.action === 'approve' ? 'Repair approved' : 'Repair rejected',
|
||||
);
|
||||
queryClient.setQueryData(ticketKeys.detail(ticketId), ticket);
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to review repair'),
|
||||
@@ -133,7 +178,10 @@ export function useCloseTicketMutation(ticketId: string) {
|
||||
mutationFn: () => ticketService.closeTicket(ticketId),
|
||||
onSuccess: (ticket) => {
|
||||
toast.success('Ticket closed');
|
||||
queryClient.setQueryData(ticketKeys.detail(ticketId), ticket);
|
||||
queryClient.setQueryData<TicketDetail>(
|
||||
ticketKeys.detail(ticketId),
|
||||
(current) => mergeTicketDetailResponse(current, ticket),
|
||||
);
|
||||
queryClient.invalidateQueries({ queryKey: ticketKeys.lists() });
|
||||
},
|
||||
onError: () => toast.error('Failed to close ticket'),
|
||||
|
||||
Reference in New Issue
Block a user