import { WriteHint } from "./freshness.tsx"; import { useEffect, useRef, useState } from "react"; import { Badge, Button, Tooltip } from "@cloudflare/kumo"; import { Warning } from "@phosphor-icons/react"; import type { Packet, ProjectState } from "./contracts.ts"; import { canArchive } from "./model.ts"; import { relativeTime } from "./time.ts"; import { ApiError } from "./transport.ts"; export function ArchivedBadge({ at }: { at: string }) { return ( } > Archived ); } /** One deliberate panel action. Reads after conflicts never retry the write. */ export function ArchiveControl({ packet, state, owner, busy, disabledReason, archive, unarchive, missing, }: { packet: Packet; state: ProjectState; owner: boolean; busy: boolean; disabledReason?: string; archive?: (id: string) => Promise; unarchive?: (id: string) => Promise; missing(message: string): void; }) { const [error, setError] = useState(); const button = useRef(null); const restoreFocus = useRef(false); const pending = useRef(false); useEffect(() => { if (restoreFocus.current && !busy) { button.current?.focus(); restoreFocus.current = false; } }, [packet.archived, busy]); const kind = packet.archived ? "unarchive" : "archive"; const label = packet.archived ? "Unarchive" : "Archive"; const write = packet.archived ? unarchive : archive; const offered = owner && write && (packet.archived || canArchive(state, packet.id)); return ( <> {offered && ( )} {error && (

)} ); }