From dc1b6aac01057b17c655752a1c8d213a95f8ea76 Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Tue, 9 Jun 2026 08:36:20 -0400 Subject: [PATCH] Trees list: inline visibility selector (private/unlisted/public) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tree visibility was set to private with no UI to change it — the trees list only displayed the value as text. Add a private/unlisted/public dropdown on each tree card that PATCHes visibility immediately (optimistic), pulled out of the card's navigation Link so it doesn't trigger a page change. Honors the "everything configurable / full CRUD in the UI" invariants. Living people stay protected by the privacy engine regardless of tree visibility. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Justin Paul --- frontend/app/trees/page.tsx | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/frontend/app/trees/page.tsx b/frontend/app/trees/page.tsx index 7316737..bcdf3f5 100644 --- a/frontend/app/trees/page.tsx +++ b/frontend/app/trees/page.tsx @@ -53,6 +53,15 @@ export default function TreesPage() { await api.POST("/api/v1/trees/{tree_id}/restore", { params: { path: { tree_id: id } } }); load(); } + // Optimistic visibility change so the dropdown reflects the pick immediately. + async function setVisibility(id: string, visibility: NonNullable) { + setTrees((cur) => cur.map((t) => (t.id === id ? { ...t, visibility } : t))); + await api.PATCH("/api/v1/trees/{tree_id}", { + params: { path: { tree_id: id } }, + body: { visibility }, + }); + load(); + } if (!ready) return

Loading…

; @@ -76,16 +85,26 @@ export default function TreesPage() { {trees.map((tree) => (
  • - +
    {tree.name}
    -
    - {tree.visibility} -
    +