import { useEffect, useState } from "preact/hooks"; import { t } from "../../i18n"; import { api, apiErrorText } from "../../features/customize/api"; import { custTab } from "../../features/customize/actions"; import { confirmAction, hint } from "../../features/customize/host"; import { currentId } from "../../stores/session"; import { useAlive } from "./use-timer-lease"; import { markCustomizeFailed, markCustomizeLoaded } from "../../features/customize/load"; import { Hdr, IconGhost, Note } from "./ui"; type ScopeMeta = { scope: string; scope_id: string; label: string }; type Rule = { rule_id: string; tool: string; pattern: string; decision: string }; function DecSelect({ value, onChange, }: { value: string; onChange: (v: string) => void; }) { return ( ); } function ResetRow() { return (
{t("cust.perm.resetName")}
{t("cust.perm.resetDesc")}
); } function AddRow({ g }: { g: ScopeMeta }) { const [tool, setTool] = useState(""); const [pat, setPat] = useState("*"); const [dec, setDec] = useState("ask"); return (
setTool((e.target as HTMLInputElement).value)} /> setPat((e.target as HTMLInputElement).value)} />
); } export function PermissionsTab() { const alive = useAlive(); const [note, setNote] = useState(null); const [data, setData] = useState | null>(null); useEffect(() => { if (!currentId.value) { setNote(t("cust.perm.noSessionNote")); markCustomizeLoaded(); return; } void (async () => { try { const next = await api(`/frames/${currentId.value}/permissions`); if (!alive()) return; setData(next); markCustomizeLoaded(); } catch (e) { if (!alive()) return; const message = t("versions.load.err", (e as Error).message); setNote(message); markCustomizeFailed(message); } })(); }, [alive]); const meta: Record | null = data ? { global: { scope: "global", scope_id: "", label: t("cust.perm.scope.global") }, project: { scope: "project", scope_id: String(data.project_id || ""), label: t("cust.perm.scope.project"), }, conversation: { scope: "conversation", scope_id: String(data.root_frame_id || ""), label: t("cust.perm.scope.conversation"), }, } : null; return (
{note ? {note} : null} {meta ? (["conversation", "project", "global"] as const).map((k) => { const g = meta[k]!; const rules = ((data!.rules as Record | undefined) || {})[ k ] || []; return (
{g.label}
{!rules.length ? {t("cust.perm.noRules")} : null} {rules.map((r) => (
{r.tool} {r.pattern} { try { await api("/permissions", { method: "POST", body: JSON.stringify({ scope: g.scope, scope_id: g.scope_id, tool: r.tool, pattern: r.pattern, decision: v, }), }); hint(t("toast.perm.ruleUpdated")); } catch (e) { hint(t("toast.perm.updateFailed", apiErrorText(e)), true); } }} /> { try { await api(`/permissions/${r.rule_id}`, { method: "DELETE" }); custTab("permissions"); } catch (e) { hint(t("toast.deleteFailed", apiErrorText(e)), true); } }} />
))}
); }) : null}
); }