diff --git a/src/app/(modules)/ticket/[ticketId]/components/TicketDefectClassTabs.tsx b/src/app/(modules)/ticket/[ticketId]/components/TicketDefectClassTabs.tsx new file mode 100644 index 0000000..9ed0468 --- /dev/null +++ b/src/app/(modules)/ticket/[ticketId]/components/TicketDefectClassTabs.tsx @@ -0,0 +1,100 @@ +'use client'; + +import { useEffect, useMemo, useState } from 'react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { CheckCircle2 } from 'lucide-react'; + +import { Card, CardContent } from '@/components/ui/card'; +import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'; + +import { useTicketDefectClassesQuery } from '../../hooks/useTicketQueries'; + +interface TicketDefectClassTabsProps { + ticketId: string; +} + +export function TicketDefectClassTabs({ + ticketId, +}: TicketDefectClassTabsProps) { + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const defectClassParam = searchParams.get('defect_class'); + const defectClassesQuery = useTicketDefectClassesQuery(ticketId); + const defectClasses = useMemo( + () => defectClassesQuery.data?.defect_classes ?? [], + [defectClassesQuery.data?.defect_classes], + ); + const [selectedClass, setSelectedClass] = useState(); + + useEffect(() => { + if (!defectClasses.length) return; + + const hasUrlClass = defectClasses.some( + (item) => item.class_name === defectClassParam, + ); + + setSelectedClass((current) => { + if (hasUrlClass) return defectClassParam ?? undefined; + + return current && + defectClasses.some((item) => item.class_name === current) + ? current + : defectClasses[0].class_name; + }); + }, [defectClassParam, defectClasses]); + + const handleClassChange = (className: string) => { + const nextParams = new URLSearchParams(searchParams.toString()); + + nextParams.set('defect_class', className); + setSelectedClass(className); + console.log(className); + router.replace(`${pathname}?${nextParams.toString()}`, { scroll: false }); + }; + + if (defectClassesQuery.isLoading) { + return ( + + + {Array.from({ length: 3 }).map((_, index) => ( +
+ ))} + + + ); + } + + if (defectClassesQuery.isError || !defectClasses.length || !selectedClass) { + return null; + } + + return ( + + + + + {defectClasses.map((item) => ( + + + {item.display_name} + + ))} + + + + + ); +} diff --git a/src/app/(modules)/ticket/[ticketId]/components/TicketOverviewCard.tsx b/src/app/(modules)/ticket/[ticketId]/components/TicketOverviewCard.tsx index af2693e..b4ed5b7 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/TicketOverviewCard.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/TicketOverviewCard.tsx @@ -3,10 +3,6 @@ import type { TicketActor, TicketDetail } from '@/types'; import { formatDate } from '@/utils/date'; -import { - TicketStatusBadge, -} from '../../components/TicketStatusBadge'; - function formatCreatedDate(value: string | null | undefined) { if (!value) return '-'; return new Intl.DateTimeFormat('en-IN', { dateStyle: 'medium' }).format( @@ -84,9 +80,7 @@ export function TicketOverviewCard({ ticket }: { ticket: TicketDetail }) { return (
-

- Overview -

+

Overview

@@ -105,27 +99,10 @@ export function TicketOverviewCard({ ticket }: { ticket: TicketDetail }) { - {formatCreatedDate(ticket.timestamps.created_at)} + + {formatCreatedDate(ticket.timestamps.created_at)} + - - - - - - - - - - - {formatDate(ticket.worker?.assigned_at)} - -
{ticket.ai_result?.completed_at ? ( diff --git a/src/app/(modules)/ticket/[ticketId]/components/TicketStatusActions.tsx b/src/app/(modules)/ticket/[ticketId]/components/TicketStatusActions.tsx index e0a08a3..49eaf83 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/TicketStatusActions.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/TicketStatusActions.tsx @@ -11,16 +11,17 @@ import { NoTicketAction } from './actions/NoTicketAction'; import { ProcessingTicketAction } from './actions/ProcessingTicketAction'; import { ReviewRepairAction } from './actions/ReviewRepairAction'; import { SubmitRepairAction } from './actions/SubmitRepairAction'; +import { TicketDefectClassTabs } from './TicketDefectClassTabs'; interface TicketStatusActionsProps { ticket: TicketDetail; liveState: TicketDetailLiveState; } -export function TicketStatusActions({ - ticket, - liveState, -}: TicketStatusActionsProps) { +function getTicketAction( + ticket: TicketDetail, + liveState: TicketDetailLiveState, +) { if (ticket.status === 'processing') { return ( ; } + +export function TicketStatusActions({ + ticket, + liveState, +}: TicketStatusActionsProps) { + return ( +
+ + {getTicketAction(ticket, liveState)} +
+ ); +} diff --git a/src/app/(modules)/ticket/[ticketId]/components/actions/AssignTicketAction.tsx b/src/app/(modules)/ticket/[ticketId]/components/actions/AssignTicketAction.tsx index d721abd..420e7d8 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/actions/AssignTicketAction.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/actions/AssignTicketAction.tsx @@ -43,6 +43,7 @@ export function AssignTicketAction({ ticket }: { ticket: TicketDetail }) { if (!selectedUserId) return; assignMutation.mutate({ assigned_to_user_id: Number(selectedUserId), + defect_class: ticket.defect_class, note: assignNote || undefined, }); }} diff --git a/src/app/(modules)/ticket/[ticketId]/components/actions/RepairEvidenceForm.tsx b/src/app/(modules)/ticket/[ticketId]/components/actions/RepairEvidenceForm.tsx index dfdc95c..5c416da 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/actions/RepairEvidenceForm.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/actions/RepairEvidenceForm.tsx @@ -131,9 +131,13 @@ function ImageSlot({ interface RepairEvidenceFormProps { ticketId: string; + defectClass: string; } -export function RepairEvidenceForm({ ticketId }: RepairEvidenceFormProps) { +export function RepairEvidenceForm({ + ticketId, + defectClass, +}: RepairEvidenceFormProps) { const imageInputRef = useRef(null); const [notes, setNotes] = useState(''); const [videoFile, setVideoFile] = useState(null); @@ -189,6 +193,7 @@ export function RepairEvidenceForm({ ticketId }: RepairEvidenceFormProps) { setError(null); try { await submitRepairUploadMutation.mutateAsync({ + defect_class: defectClass, notes: notes.trim(), video: videoFile, images: imageFiles, @@ -267,7 +272,10 @@ export function RepairEvidenceForm({ ticketId }: RepairEvidenceFormProps) { key={index} file={slot.file} previewUrl={slot.previewUrl} - disabled={isSubmitting || (!slot.file && imageFiles.length >= MAX_IMAGES)} + disabled={ + isSubmitting || + (!slot.file && imageFiles.length >= MAX_IMAGES) + } onAdd={() => imageInputRef.current?.click()} onRemove={() => removeImage(index)} /> diff --git a/src/app/(modules)/ticket/[ticketId]/components/actions/ReviewRepairAction.tsx b/src/app/(modules)/ticket/[ticketId]/components/actions/ReviewRepairAction.tsx index c2fdbe5..a71b7a7 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/actions/ReviewRepairAction.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/actions/ReviewRepairAction.tsx @@ -35,6 +35,7 @@ export function ReviewRepairAction({ ticket }: { ticket: TicketDetail }) { disabled={!reviewComment || reviewRepairMutation.isPending} onClick={() => reviewRepairMutation.mutate({ + defect_class: ticket.defect_class, action: 'approve', comment: reviewComment, }) @@ -48,6 +49,7 @@ export function ReviewRepairAction({ ticket }: { ticket: TicketDetail }) { disabled={!reviewComment || reviewRepairMutation.isPending} onClick={() => reviewRepairMutation.mutate({ + defect_class: ticket.defect_class, action: 'reject', comment: reviewComment, }) diff --git a/src/app/(modules)/ticket/[ticketId]/components/actions/SubmitRepairAction.tsx b/src/app/(modules)/ticket/[ticketId]/components/actions/SubmitRepairAction.tsx index 2a973dd..4cdf8d7 100644 --- a/src/app/(modules)/ticket/[ticketId]/components/actions/SubmitRepairAction.tsx +++ b/src/app/(modules)/ticket/[ticketId]/components/actions/SubmitRepairAction.tsx @@ -10,7 +10,10 @@ import { TicketActionCard } from './TicketActionCard'; export function SubmitRepairAction({ ticket }: { ticket: TicketDetail }) { return ( - + ); } diff --git a/src/app/(modules)/ticket/[ticketId]/page.tsx b/src/app/(modules)/ticket/[ticketId]/page.tsx index 45a9aef..cd90ae8 100644 --- a/src/app/(modules)/ticket/[ticketId]/page.tsx +++ b/src/app/(modules)/ticket/[ticketId]/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useParams, useRouter } from 'next/navigation'; +import { useParams, useRouter, useSearchParams } from 'next/navigation'; import { ArrowLeft } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -17,9 +17,11 @@ import { useTicketDetailQuery } from '../hooks/useTicketQueries'; export default function TicketDetailPage() { const router = useRouter(); + const searchParams = useSearchParams(); const { ticketId } = useParams() as { ticketId: string }; + const defectClass = searchParams.get('defect_class') ?? undefined; - const ticketQuery = useTicketDetailQuery(ticketId); + const ticketQuery = useTicketDetailQuery(ticketId, defectClass); const ticket = ticketQuery.data; const liveState = useTicketDetailEvents( diff --git a/src/app/(modules)/ticket/components/TicketColumns.tsx b/src/app/(modules)/ticket/components/TicketColumns.tsx index d9ef6e8..1973756 100644 --- a/src/app/(modules)/ticket/components/TicketColumns.tsx +++ b/src/app/(modules)/ticket/components/TicketColumns.tsx @@ -12,11 +12,11 @@ export function useTicketColumns(): ColumnDef[] { return useMemo( () => [ { - accessorKey: 'id', + accessorKey: 'ticket_name', header: 'Ticket', size: 180, cell: ({ row }) => ( - {row.original.id} + {row.original.ticket_name} ), }, { diff --git a/src/app/(modules)/ticket/hooks/useTenantTicketTableEvents.ts b/src/app/(modules)/ticket/hooks/useTenantTicketTableEvents.ts index ed7189b..a897bb0 100644 --- a/src/app/(modules)/ticket/hooks/useTenantTicketTableEvents.ts +++ b/src/app/(modules)/ticket/hooks/useTenantTicketTableEvents.ts @@ -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, diff --git a/src/app/(modules)/ticket/hooks/useTicketQueries.ts b/src/app/(modules)/ticket/hooks/useTicketQueries.ts index d53101a..8224173 100644 --- a/src/app/(modules)/ticket/hooks/useTicketQueries.ts +++ b/src/app/(modules)/ticket/hooks/useTicketQueries.ts @@ -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( - 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( - 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( - 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( - ticketKeys.detail(ticketId), + ticketKeys.detail(ticketId, payload.defect_class), (current) => mergeTicketDetailResponse(current, ticket), ); queryClient.invalidateQueries({ queryKey: ticketKeys.lists() }); diff --git a/src/app/(modules)/ticket/page.tsx b/src/app/(modules)/ticket/page.tsx index 2259cfc..1f6a5b7 100644 --- a/src/app/(modules)/ticket/page.tsx +++ b/src/app/(modules)/ticket/page.tsx @@ -44,7 +44,9 @@ export default function TicketPage() { const handleView = useCallback( (ticket: TicketListItem) => { - router.push(`/ticket/${ticket.id}`); + router.push( + `/ticket/${ticket.id}?defect_class=${encodeURIComponent(ticket.default_defect_class)}`, + ); }, [router], ); diff --git a/src/app/(modules)/ticket/queries/ticketKeys.ts b/src/app/(modules)/ticket/queries/ticketKeys.ts index 6d8c458..7d33da3 100644 --- a/src/app/(modules)/ticket/queries/ticketKeys.ts +++ b/src/app/(modules)/ticket/queries/ticketKeys.ts @@ -5,6 +5,9 @@ export const ticketKeys = { lists: () => [...ticketKeys.all, 'list'] as const, list: (params: TicketListParams) => [...ticketKeys.lists(), params] as const, details: () => [...ticketKeys.all, 'detail'] as const, - detail: (ticketId: string) => [...ticketKeys.details(), ticketId] as const, + detail: (ticketId: string, defectClass?: string) => + [...ticketKeys.details(), ticketId, defectClass] as const, + defectClasses: (ticketId: string) => + [...ticketKeys.detail(ticketId), 'defect-classes'] as const, assignableUsers: () => [...ticketKeys.all, 'assignable-users'] as const, }; diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx index 7281472..6abe13e 100644 --- a/src/components/ui/breadcrumb.tsx +++ b/src/components/ui/breadcrumb.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; +import Link from 'next/link'; import { ChevronRight, MoreHorizontal } from 'lucide-react'; -import { Slot } from 'radix-ui'; import { cn } from '@/lib/utils'; @@ -31,17 +31,11 @@ function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) { ); } -function BreadcrumbLink({ - asChild, - className, - ...props -}: React.ComponentProps<'a'> & { - asChild?: boolean; -}) { - const Comp = asChild ? Slot.Root : 'a'; +type BreadcrumbLinkProps = React.ComponentProps; +function BreadcrumbLink({ className, ...props }: BreadcrumbLinkProps) { return ( - ) { + return ( + + ) +} + +const tabsListVariants = cva( + "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none", + { + variants: { + variant: { + default: "bg-muted", + line: "gap-1 bg-transparent", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function TabsList({ + className, + variant = "default", + ...props +}: React.ComponentProps & + VariantProps) { + return ( + + ) +} + +function TabsTrigger({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function TabsContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants } diff --git a/src/constants/apiRoutes.ts b/src/constants/apiRoutes.ts index c9c6d14..64cd38a 100644 --- a/src/constants/apiRoutes.ts +++ b/src/constants/apiRoutes.ts @@ -54,12 +54,14 @@ export const API_ROUTES = { }, TICKETS: { BASE: '/biz/api/v1/tickets', - DETAIL: (id: string) => `/biz/api/v1/tickets/${id}`, + DETAIL: (id: string, defectClass: string) => + `/biz/api/v1/tickets/${id}/class-detail?defect_class=${defectClass}`, + DEFECT_CLASSES: (id: string) => `/biz/api/v1/tickets/${id}/defect-classes`, ASSIGN: (id: string) => `/biz/api/v1/tickets/${id}/assign`, START: (id: string) => `/biz/api/v1/tickets/${id}/start`, SUBMIT_REPAIR: (id: string) => `/biz/api/v1/tickets/${id}/submit-repair`, SUBMIT_REPAIR_UPLOAD: (id: string) => - `/biz/api/v1/tickets/${id}/submit-repair/upload`, + `/biz/api/v1/tickets/${id}/repair-proof`, REVIEW: (id: string) => `/biz/api/v1/tickets/${id}/review`, CLOSE: (id: string) => `/biz/api/v1/tickets/${id}/close`, DETAIL_EVENTS_TOKEN: (id: string) => diff --git a/src/services/api/ticket.service.ts b/src/services/api/ticket.service.ts index 6df5d56..ed10bce 100644 --- a/src/services/api/ticket.service.ts +++ b/src/services/api/ticket.service.ts @@ -4,11 +4,13 @@ import type { AssignTicketPayload, AssignableTicketUsersResponse, AssignableTicketUsersParams, + CloseTicketPayload, ReviewRepairPayload, SseTokenResponse, SubmitRepairPayload, SubmitRepairUploadPayload, TicketDetail, + TicketDefectClassesResponse, TicketListParams, TicketListResponse, } from '@/types'; @@ -31,9 +33,21 @@ export const ticketService = { return response.data; }, - getTicketDetail: async (ticketId: string): Promise => { + getTicketDetail: async ( + ticketId: string, + defectClass: string, + ): Promise => { const response = await axiosClient.get( - API_ROUTES.TICKETS.DETAIL(ticketId), + API_ROUTES.TICKETS.DETAIL(ticketId, defectClass), + ); + return response.data; + }, + + getTicketDefectClasses: async ( + ticketId: string, + ): Promise => { + const response = await axiosClient.get( + API_ROUTES.TICKETS.DEFECT_CLASSES(ticketId), ); return response.data; }, @@ -88,6 +102,7 @@ export const ticketService = { payload: SubmitRepairUploadPayload, ): Promise => { const formData = new FormData(); + formData.append('defect_class', payload.defect_class); formData.append('notes', payload.notes); formData.append('video', payload.video); payload.images.forEach((image) => { @@ -117,9 +132,13 @@ export const ticketService = { return response.data; }, - closeTicket: async (ticketId: string): Promise => { + closeTicket: async ( + ticketId: string, + payload: CloseTicketPayload, + ): Promise => { const response = await axiosClient.post( API_ROUTES.TICKETS.CLOSE(ticketId), + payload, ); return response.data; }, diff --git a/src/types/ticket/actions.ts b/src/types/ticket/actions.ts index c10e381..b39b706 100644 --- a/src/types/ticket/actions.ts +++ b/src/types/ticket/actions.ts @@ -18,7 +18,7 @@ export interface AssignableTicketUsersResponse { export interface AssignTicketPayload { assigned_to_user_id: number; - assigned_to_email?: string; + defect_class: string; note?: string; } @@ -28,12 +28,38 @@ export interface SubmitRepairPayload { } export interface SubmitRepairUploadPayload { + defect_class: string; notes: string; video: File; images: File[]; } export interface ReviewRepairPayload { + defect_class: string; action: 'approve' | 'reject'; comment: string; } + +export interface CloseTicketPayload { + defect_class: string; +} + +export type TicketDefectClassTicketStatus = + | 'unassigned' + | 'assigned' + | 'under_review' + | 'approved' + | 'rejected'; + +export interface TicketDefectClassItem { + class_name: string; + display_name: string; + assignment_status: TicketDefectClassTicketStatus; +} + +export interface TicketDefectClassesResponse { + ticket_id: string; + video_id: string; + ticket_status: TicketDefectClassTicketStatus; + defect_classes: TicketDefectClassItem[]; +} diff --git a/src/types/ticket/detail.ts b/src/types/ticket/detail.ts index 74764df..a512033 100644 --- a/src/types/ticket/detail.ts +++ b/src/types/ticket/detail.ts @@ -1,3 +1,4 @@ +import type { TicketDefectClassTicketStatus } from './actions'; import type { TicketStatus } from './status'; export interface TicketActor { @@ -52,6 +53,7 @@ export interface TicketReviewer extends TicketActor { export interface TicketAiResult { detection_count: number; completed_at: string | null; + available_defect_classes: string[]; } export interface TicketTenant { @@ -69,6 +71,9 @@ export interface TicketDetail { video_id: string; chainage_id: string | null; status: TicketStatus; + defect_class: string; + defect_display_name: string; + assignment_status: TicketDefectClassTicketStatus; status_metadata: TicketStatusMetadata | null; video: TicketVideo | null; uploader: TicketActor | null; diff --git a/src/types/ticket/events.ts b/src/types/ticket/events.ts index a16bab5..0372de6 100644 --- a/src/types/ticket/events.ts +++ b/src/types/ticket/events.ts @@ -10,9 +10,11 @@ export type TicketTableStatusEvent = { type?: 'ticket_status'; kind?: 'created' | 'transitioned'; id: string; + ticket_name?: string; chainage_id?: string | null; chainage_name?: string | null; status?: TicketStatus; + default_defect_class?: string; assigned_to_name?: string | null; detection_count?: number; created_by_name?: string | null; diff --git a/src/types/ticket/list.ts b/src/types/ticket/list.ts index 4b2ad4d..6667e63 100644 --- a/src/types/ticket/list.ts +++ b/src/types/ticket/list.ts @@ -8,9 +8,11 @@ export interface TicketListParams extends PaginationParams { export interface TicketListItem { id: string; + ticket_name: string; chainage_id: string | null; chainage_name: string | null; status: TicketStatus; + default_defect_class: string; assigned_to_name: string | null; detection_count: number; created_by_name: string | null;