import { useEffect, useRef, useState } from "react"; import { useLocation, useNavigate, useParams, useSearchParams } from "react-router-dom"; import { LuPencil, LuPlus, LuTrash2 } from "react-icons/lu"; import { errorMessage } from "../api/client.js"; import { useDeleteSecret, useOwners, useSecrets } from "../api/hooks.js"; import { ConfirmDialog } from "../components/ConfirmDialog.jsx"; import { FormSelect } from "../components/FormControls.jsx"; import { SecretEditorModal } from "../components/SecretEditorModal.jsx"; import { useRouteDrivenModal } from "../hooks/useRouteDrivenModal.js"; import { formatTime } from "../lib/format.jsx"; export function SecretsPage() { const navigate = useNavigate(); const location = useLocation(); const { owner: routeOwner, name: routeName } = useParams(); const [params] = useSearchParams(); const isNewRoute = /\/secrets\/new\/?$/.test(location.pathname); const isEditRoute = Boolean(routeOwner && routeName); const { data: owners = [] } = useOwners(); const [ownerFilter, setOwnerFilter] = useState( () => routeOwner || params.get("owner") || "", ); const { data: secrets = [], isLoading } = useSecrets(ownerFilter || undefined); const del = useDeleteSecret(); const [confirmDelete, setConfirmDelete] = useState(null); const [highlightName, setHighlightName] = useState(() => routeName || ""); const highlightRef = useRef(null); const listPath = ownerFilter ? `/secrets?owner=${encodeURIComponent(ownerFilter)}` : "/secrets"; const { editor, closeEditor } = useRouteDrivenModal({ isNewRoute, isEditRoute, listPath, newRouteKey: () => `new:${params.get("owner") || ""}:${params.get("name") || ""}`, canOpenNew: () => Boolean(params.get("owner") || ownerFilter || owners.length > 0), onBeforeOpenNew: () => { if (params.get("owner")) setOwnerFilter(params.get("owner")); }, buildNewEditor: () => { const owner = params.get("owner") || ownerFilter || owners[0] || "default"; return { mode: "add", initial: { owner, name: params.get("name") || "" }, }; }, editRouteKey: () => `edit:${routeOwner}/${routeName}`, canOpenEdit: () => { if (ownerFilter !== routeOwner) { setOwnerFilter(routeOwner); return false; } return true; }, onOpenEdit: () => setHighlightName(routeName), buildEditEditor: () => ({ mode: "replace", initial: { owner: routeOwner, name: routeName }, }), newDeps: [params, owners, ownerFilter], editDeps: [routeOwner, routeName, ownerFilter], }); useEffect(() => { if (!highlightName || isLoading) return; highlightRef.current?.scrollIntoView({ block: "nearest", behavior: "smooth" }); }, [highlightName, isLoading, secrets]); return (
No secrets yet.
) : (| Owner | Name | Updated | |
|---|---|---|---|
| {s.owner} | {s.name} | {formatTime(s.updated_at)} |