diff --git a/frontend/src/components/ConfirmDialog.tsx b/frontend/src/components/ConfirmDialog.tsx new file mode 100644 index 0000000..13e7c92 --- /dev/null +++ b/frontend/src/components/ConfirmDialog.tsx @@ -0,0 +1,47 @@ +import { + Dialog, + DialogContent, + DialogTitle, + Stack, + Typography, +} from "@mui/material"; +import { DialogFooter } from "./DialogFooter"; + +export function ConfirmDialog({ + open, + title, + message, + confirmLabel = "Delete", + onCancel, + onConfirm, + busy, +}: { + open: boolean; + title: string; + message: string; + confirmLabel?: string; + onCancel: () => void; + onConfirm: () => void; + busy?: boolean; +}) { + return ( + + {title} + + + + {message} + + + + + + ); +} diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index d376377..3e6277d 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useMemo, useState } from "react"; import { Alert, Box, @@ -29,6 +29,7 @@ import { useMonitoringOverview, useSaveDashboardShortcut, } from "../hooks/useDashboard"; +import { useMonitoringSettings } from "../hooks/useSettings"; import type { DashboardShortcut, DashboardShortcutInput } from "../types"; import { NowPlaying } from "../components/NowPlaying"; import { MonitoringOverviewTable } from "../components/MonitoringOverviewTable"; @@ -310,7 +311,19 @@ function ShortcutCard({ export function Dashboard() { const navigate = useNavigate(); - const { data: activity } = useActivity(); + const { data: machines = [] } = useMonitoringSettings(); + const jellyfinMachines = useMemo( + () => + machines.filter( + (machine) => machine.enabled && machine.services.includes("jellyfin"), + ), + [machines], + ); + const [activeJellyfinMachineId, setActiveJellyfinMachineId] = + useState(""); + const selectedJellyfinId = + activeJellyfinMachineId || jellyfinMachines[0]?.id || ""; + const { data: activity } = useActivity(selectedJellyfinId || undefined); const { data: monitoringOverview } = useMonitoringOverview(); const { data: shortcuts = [] } = useDashboardShortcuts(); const saveShortcut = useSaveDashboardShortcut(); @@ -319,6 +332,7 @@ export function Dashboard() { const [shortcutDraft, setShortcutDraft] = useState( emptyShortcut(), ); + const [deleteShortcutId, setDeleteShortcutId] = useState(null); const openCreateShortcut = () => { setShortcutDraft(emptyShortcut()); @@ -373,7 +387,7 @@ export function Dashboard() { } }} onEdit={() => openEditShortcut(shortcut)} - onDelete={() => deleteShortcut.mutate(shortcut.id)} + onDelete={() => setDeleteShortcutId(shortcut.id)} /> ))} @@ -389,6 +403,29 @@ export function Dashboard() { 1 ? ( + + + + ) : jellyfinMachines.length === 1 ? ( + + ) : null + } > {activity ? ( setShortcutDialogOpen(false)} onSave={saveShortcutDraft} /> + setDeleteShortcutId(null)} + fullWidth + maxWidth="xs" + > + Delete shortcut? + + + This cannot be undone. The shortcut will be removed from the + dashboard. + + + setDeleteShortcutId(null)} + onConfirm={() => { + if (deleteShortcutId) { + deleteShortcut.mutate(deleteShortcutId); + } + setDeleteShortcutId(null); + }} + confirmLabel="Delete" + confirmColor="error" + /> + ); } diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index 2cd0b62..ff944ce 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -36,6 +36,7 @@ import { HoverEditButton } from "../components/HoverEditButton"; import { SectionCard } from "../components/SectionCard"; import { SelectionRailCard } from "../components/SelectionRailCard"; import { TabbedCard } from "../components/TabbedCard"; +import { ConfirmDialog } from "../components/ConfirmDialog"; const SERVICE_OPTIONS = [ { value: "monitoring", label: "Monitoring" }, { value: "files", label: "Files" }, @@ -996,6 +997,7 @@ export function Settings() { const deleteMachine = useDeleteMonitoringMachine(); const testMachineSSH = useTestMonitoringMachineSSH(); const [tab, setTab] = useState("machines"); + const [deleteMachineId, setDeleteMachineId] = useState(null); const [sshValidationMessage, setSSHValidationMessage] = useState(""); const [sshValidationError, setSSHValidationError] = useState(""); const [sshValidationStatus, setSSHValidationStatus] = useState(""); @@ -1384,7 +1386,7 @@ export function Settings() { variant="outlined" color="error" onClick={() => - deleteMachine.mutate(selectedMachine.id) + setDeleteMachineId(selectedMachine.id) } > Delete @@ -1448,8 +1450,8 @@ export function Settings() { variant="outlined" color="error" onClick={() => { - deleteMachine.mutate(machineDraft.id as string); - closeMachineDialog(); + setDeleteMachineId(machineDraft.id as string); + }} > Delete @@ -1457,6 +1459,20 @@ export function Settings() { ) : undefined } /> + + setDeleteMachineId(null)} + onConfirm={() => { + if (deleteMachineId) { + deleteMachine.mutate(deleteMachineId); + closeMachineDialog(); + } + setDeleteMachineId(null); + }} + /> );