Openstatus www.openstatus.dev
at main 137 lines 4.6 kB view raw
1"use client"; 2 3import { ProcessMessage } from "@/components/content/process-message"; 4import { TableCellDate } from "@/components/data-table/table-cell-date"; 5import { FormSheetStatusReportUpdate } from "@/components/forms/status-report-update/sheet"; 6import { Button } from "@/components/ui/button"; 7import { 8 Table, 9 TableBody, 10 TableCell, 11 TableHead, 12 TableHeader, 13 TableRow, 14} from "@/components/ui/table"; 15import { 16 Tooltip, 17 TooltipContent, 18 TooltipProvider, 19 TooltipTrigger, 20} from "@/components/ui/tooltip"; 21import { icons } from "@/data/icons"; 22import { colors } from "@/data/status-report-updates.client"; 23import { useTRPC } from "@/lib/trpc/client"; 24import { cn } from "@/lib/utils"; 25import type { RouterOutputs } from "@openstatus/api"; 26import { useMutation, useQueryClient } from "@tanstack/react-query"; 27import { Plus } from "lucide-react"; 28import { useParams } from "next/navigation"; 29import { DataTableRowActions } from "./data-table-row-actions"; 30 31type StatusReportUpdates = 32 RouterOutputs["statusReport"]["list"][number]["updates"]; 33 34export function DataTable({ 35 updates, 36 reportId, 37}: { 38 updates: StatusReportUpdates; 39 reportId: number; 40}) { 41 const trpc = useTRPC(); 42 const { id } = useParams<{ id: string }>(); 43 const queryClient = useQueryClient(); 44 const sendStatusReportUpdateMutation = useMutation( 45 trpc.emailRouter.sendStatusReport.mutationOptions(), 46 ); 47 const createStatusReportUpdateMutation = useMutation( 48 trpc.statusReport.createStatusReportUpdate.mutationOptions({ 49 onSuccess: (update) => { 50 // TODO: move to server 51 if (update?.notifySubscribers) { 52 sendStatusReportUpdateMutation.mutateAsync({ id: update.id }); 53 } 54 // 55 queryClient.invalidateQueries({ 56 queryKey: trpc.statusReport.list.queryKey({ 57 pageId: Number.parseInt(id), 58 }), 59 }); 60 queryClient.invalidateQueries({ 61 queryKey: trpc.page.list.queryKey(), 62 }); 63 queryClient.invalidateQueries({ 64 queryKey: trpc.statusReport.list.queryKey({ 65 period: "7d", 66 }), 67 }); 68 }, 69 }), 70 ); 71 72 return ( 73 <Table className="w-full"> 74 <TableHeader> 75 <TableRow> 76 <TableHead className="w-7"> 77 <span className="sr-only">Status</span> 78 </TableHead> 79 <TableHead>Message</TableHead> 80 <TableHead>Date</TableHead> 81 <TableHead className="w-[px]"> 82 <TooltipProvider> 83 <Tooltip> 84 <FormSheetStatusReportUpdate 85 onSubmit={async (values) => { 86 await createStatusReportUpdateMutation.mutateAsync({ 87 statusReportId: reportId, 88 message: values.message, 89 status: values.status, 90 date: values.date, 91 notifySubscribers: values.notifySubscribers, 92 }); 93 }} 94 > 95 <TooltipTrigger asChild> 96 <Button size="icon" className="ml-auto flex h-7 w-7 p-0"> 97 <Plus /> 98 <span className="sr-only">Create Report Update</span> 99 </Button> 100 </TooltipTrigger> 101 </FormSheetStatusReportUpdate> 102 <TooltipContent side="left" align="center"> 103 Create Report Update 104 </TooltipContent> 105 </Tooltip> 106 </TooltipProvider> 107 </TableHead> 108 </TableRow> 109 </TableHeader> 110 <TableBody> 111 {updates.map((update) => { 112 const Icon = icons.status[update.status]; 113 return ( 114 <TableRow key={update.id}> 115 <TableCell> 116 <div className="p-1"> 117 <Icon className={cn(colors[update.status])} size={20} /> 118 </div> 119 </TableCell> 120 <TableCell> 121 <div className="prose dark:prose-invert prose-sm line-clamp-3 text-wrap text-muted-foreground"> 122 <ProcessMessage value={update.message} /> 123 </div> 124 </TableCell> 125 <TableCell className="w-[170px] text-muted-foreground"> 126 <TableCellDate value={update.date} /> 127 </TableCell> 128 <TableCell className="w-8"> 129 <DataTableRowActions row={update} /> 130 </TableCell> 131 </TableRow> 132 ); 133 })} 134 </TableBody> 135 </Table> 136 ); 137}