Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
5.7 kB ยท 168 lines
TSX
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169"use client";
import { Button } from "@openstatus/ui/components/ui/button";import { Label } from "@openstatus/ui/components/ui/label";import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from "@openstatus/ui/components/ui/select";import { Separator } from "@openstatus/ui/components/ui/separator";import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";import { useState } from "react";
import { EmptyStateContainer, EmptyStateTitle,} from "@/components/content/empty-state";import { FormCard, FormCardGroup } from "@/components/forms/form-card";import { FormSheetContent, FormSheetDescription, FormSheetFooter, FormSheetHeader, FormSheetTitle, FormSheetTrigger, FormSheetWithDirtyProtection,} from "@/components/forms/form-sheet";import { FormMaintenance } from "@/components/forms/maintenance/form";import { toCheckboxTreeItems } from "@/components/ui/checkbox-tree";import { useTRPC } from "@/lib/trpc/client";
/** * Create-maintenance sheet with a status page selector โ for surfaces that * are not scoped to a single page (e.g. /overview). `children` is the trigger. */export function FormSheetMaintenanceCreate({ children, open: controlledOpen, onOpenChange, defaultPageId,}: { children?: React.ReactNode; open?: boolean; onOpenChange?: (open: boolean) => void; /** Pre-scopes the sheet to a page and hides the selector. */ defaultPageId?: number;}) { const [internalOpen, setInternalOpen] = useState(false); const open = controlledOpen ?? internalOpen; const setOpen = onOpenChange ?? setInternalOpen; const [selectedPageId, setSelectedPageId] = useState<number | null>(null); const trpc = useTRPC(); const queryClient = useQueryClient(); const { data: pages } = useQuery(trpc.page.list.queryOptions());
const pageId = defaultPageId ?? (pages?.length === 1 ? pages[0].id : (selectedPageId ?? undefined));
const { data: page } = useQuery( trpc.page.get.queryOptions( { id: pageId ?? 0 }, { enabled: pageId !== undefined }, ), );
const sendMaintenanceUpdateMutation = useMutation( trpc.subscriberNotification.maintenance.mutationOptions(), ); const createMaintenanceMutation = useMutation( trpc.maintenance.new.mutationOptions({ onSuccess: (maintenance) => { if (maintenance.notifySubscribers) { sendMaintenanceUpdateMutation.mutate({ id: maintenance.id }); } // no-input prefix key โ matches every maintenance.list query queryClient.invalidateQueries({ queryKey: trpc.maintenance.list.queryKey(), }); }, }), );
return ( <FormSheetWithDirtyProtection open={open} onOpenChange={setOpen}> {children ? ( <FormSheetTrigger asChild>{children}</FormSheetTrigger> ) : null} <FormSheetContent className="sm:max-w-lg"> <FormSheetHeader> <FormSheetTitle>Maintenance</FormSheetTitle> <FormSheetDescription> Configure and update the maintenance. </FormSheetDescription> </FormSheetHeader> {defaultPageId === undefined && pages && pages.length > 1 ? ( <> <div className="grid gap-1.5 px-4 py-4"> <Label htmlFor="maintenance-page-select">Status Page</Label> <Select value={pageId !== undefined ? String(pageId) : undefined} onValueChange={(value) => setSelectedPageId(Number(value))} > <SelectTrigger id="maintenance-page-select" size="sm"> <SelectValue placeholder="Select a status page" /> </SelectTrigger> <SelectContent> {pages.map((p) => ( <SelectItem key={p.id} value={String(p.id)}> {p.title} </SelectItem> ))} </SelectContent> </Select> </div> <Separator /> </> ) : null} {pageId !== undefined ? ( <FormCardGroup className="overflow-y-auto"> <FormCard className="overflow-auto rounded-none border-none"> <FormMaintenance key={pageId} id="maintenance-form" className="my-4" items={toCheckboxTreeItems( page?.pageComponents ?? [], page?.pageComponentGroups ?? [], )} onSubmit={async (values) => { await createMaintenanceMutation.mutateAsync({ pageId, title: values.title, message: values.message, startDate: values.startDate, endDate: values.endDate, pageComponents: values.pageComponents, notifySubscribers: values.notifySubscribers, }); setOpen(false); }} /> </FormCard> </FormCardGroup> ) : ( <EmptyStateContainer className="m-4"> <EmptyStateTitle> {pages?.length === 0 ? "No status pages found" : "Select a status page"} </EmptyStateTitle> </EmptyStateContainer> )} <FormSheetFooter> <Button type="submit" form="maintenance-form" disabled={pageId === undefined} > Submit </Button> </FormSheetFooter> </FormSheetContent> </FormSheetWithDirtyProtection> );}