2026-01-21 19:01:25 +00:00

151 lines
6.3 KiB
TypeScript

import React from "react"
import { AlertTriangle, Trash2 } from "lucide-react"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
import { Button } from "@/components/ui/button"
import { Separator } from "@/components/ui/separator"
import type { JobStatus } from "@shared/types"
import { ALL_JOB_STATUSES, STATUS_DESCRIPTIONS } from "@client/pages/settings/constants"
type DangerZoneSectionProps = {
statusesToClear: JobStatus[]
toggleStatusToClear: (status: JobStatus) => void
handleClearByStatuses: () => void
handleClearDatabase: () => void
isLoading: boolean
isSaving: boolean
}
export const DangerZoneSection: React.FC<DangerZoneSectionProps> = ({
statusesToClear,
toggleStatusToClear,
handleClearByStatuses,
handleClearDatabase,
isLoading,
isSaving,
}) => {
return (
<AccordionItem value="danger-zone" className="border rounded-lg px-4 border-destructive/30 mt-4">
<AccordionTrigger className="hover:no-underline py-4">
<div className="flex items-center gap-2 text-destructive">
<AlertTriangle className="h-4 w-4" />
<span className="text-base font-semibold tracking-wider">Danger Zone</span>
</div>
</AccordionTrigger>
<AccordionContent className="pb-4">
<div className="space-y-4 pt-2">
<div className="p-3 rounded-md space-y-4">
<div className="space-y-0.5">
<div className="text-sm font-semibold text-destructive">Clear Jobs by Status</div>
<div className="text-xs text-muted-foreground">
Select which job statuses you want to clear.
</div>
</div>
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
{ALL_JOB_STATUSES.map((status) => {
const isSelected = statusesToClear.includes(status)
return (
<button
key={status}
type="button"
onClick={() => toggleStatusToClear(status)}
disabled={isLoading || isSaving}
className={`flex items-start gap-3 rounded-lg border p-3 text-left transition-colors hover:bg-destructive/20 disabled:cursor-not-allowed disabled:opacity-50 ${
isSelected ? 'border-destructive bg-destructive/10' : 'border-border'
}`}
>
<div className={`mt-0.5 h-4 w-4 rounded-full border-2 flex items-center justify-center ${
isSelected ? 'border-destructive' : 'border-muted-foreground'
}`}>
{isSelected && <div className="h-2 w-2 rounded-full bg-destructive" />}
</div>
<div className="grid gap-0.5">
<span className="text-sm font-medium capitalize">{status}</span>
<span className="text-xs text-muted-foreground">
{STATUS_DESCRIPTIONS[status]}
</span>
</div>
</button>
)
})}
</div>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
variant="destructive"
size="sm"
disabled={isLoading || isSaving || statusesToClear.length === 0}
>
<Trash2 className="mr-2 h-4 w-4" />
Clear Selected ({statusesToClear.length})
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Clear jobs by status?</AlertDialogTitle>
<AlertDialogDescription>
This will delete all jobs with the following statuses: {statusesToClear.join(', ')}.
This action cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleClearByStatuses} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
Clear {statusesToClear.length} status{statusesToClear.length !== 1 ? 'es' : ''}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
<Separator />
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between p-3 rounded-md">
<div className="space-y-0.5">
<div className="text-sm font-semibold text-destructive">Clear Entire Database</div>
<div className="text-xs text-muted-foreground">
Delete all jobs and pipeline runs from the database.
</div>
</div>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" size="sm" disabled={isLoading || isSaving}>
<Trash2 className="mr-2 h-4 w-4" />
Clear Database
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Clear all jobs?</AlertDialogTitle>
<AlertDialogDescription>
This deletes all jobs and pipeline runs from the database. This action cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleClearDatabase} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
Clear database
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</div>
</AccordionContent>
</AccordionItem>
)
}