From fd67bb03af4efdfa6c24b6aad4541602a97c16c0 Mon Sep 17 00:00:00 2001 From: Paul Trowbridge Date: Wed, 15 Apr 2026 21:11:28 -0400 Subject: [PATCH] Records: fix override panel not opening Open panel immediately on row click (panelOpen state), then load full record async. Previously the panel condition depended on selectedRecord or panelLoading both of which are set after async work, so if id was missing or the API call failed the panel never appeared. Also shows a message if id is missing (view needs regeneration). Co-Authored-By: Claude Sonnet 4.6 --- ui/src/pages/Records.jsx | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/ui/src/pages/Records.jsx b/ui/src/pages/Records.jsx index d8a96fa..0125018 100644 --- a/ui/src/pages/Records.jsx +++ b/ui/src/pages/Records.jsx @@ -32,7 +32,9 @@ export default function Records({ source }) { const LIMIT = 100 // Override panel - const [selectedRecord, setSelectedRecord] = useState(null) // full record from API + const [panelOpen, setPanelOpen] = useState(false) + const [selectedRow, setSelectedRow] = useState(null) // raw view row (has id) + const [selectedRecord, setSelectedRecord] = useState(null) // full record from API const [overrideDraft, setOverrideDraft] = useState({}) // { field: newValue } const [panelLoading, setPanelLoading] = useState(false) const [panelSaving, setPanelSaving] = useState(false) @@ -45,6 +47,8 @@ export default function Records({ source }) { setFilters([]) setViewError(null) setSelectedRecord(null) + setSelectedRow(null) + setPanelOpen(false) load(0, null, 'asc', []) }, [source]) @@ -100,12 +104,20 @@ export default function Records({ source }) { function next() { const o = offset + LIMIT; setOffset(o); load(o, sort.col, sort.dir, filters) } async function openPanel(row) { - const id = row.id - if (!id) return - setPanelLoading(true) - setPanelMsg(null) + // Open panel immediately, then load full record async + setPanelOpen(true) + setSelectedRow(row) setSelectedRecord(null) setOverrideDraft({}) + setPanelMsg(null) + + const id = row.id + if (!id) { + setPanelMsg({ text: 'No record ID — regenerate the view in Sources.', ok: false }) + return + } + + setPanelLoading(true) try { const rec = await api.getRecord(id) setSelectedRecord(rec) @@ -118,6 +130,8 @@ export default function Records({ source }) { } function closePanel() { + setPanelOpen(false) + setSelectedRow(null) setSelectedRecord(null) setOverrideDraft({}) setPanelMsg(null) @@ -267,7 +281,7 @@ export default function Records({ source }) { {rows.map((row, i) => { const isOverridden = row._overridden - const isSelected = selectedRecord?.id === row.id + const isSelected = selectedRow?.id != null && selectedRow.id === row.id return ( {/* Override panel */} - {(selectedRecord || panelLoading) && ( + {panelOpen && (
Override