From 52ceec34d51d39df4d4006087f815efff077ad0f Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Tue, 11 Aug 2026 22:29:33 +0530 Subject: [PATCH 1/3] Fix: Updated DoctorPanle with aria, layout and button handling --- .../src/features/doctor/DoctorPanel.tsx | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/apps/desktop/src/features/doctor/DoctorPanel.tsx b/apps/desktop/src/features/doctor/DoctorPanel.tsx index 7aa062d..85ad5fe 100644 --- a/apps/desktop/src/features/doctor/DoctorPanel.tsx +++ b/apps/desktop/src/features/doctor/DoctorPanel.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from "react"; import type { DoctorReport } from "@trachyte/core"; import { runDoctor } from "../../ipc/doctor"; @@ -14,6 +14,8 @@ export default function DoctorPanel({ path, onClose, onRebuild }: DoctorPanelPro const [loading, setLoading] = useState(true); const [rebuilding, setRebuilding] = useState(false); const [rebuildResult, setRebuildResult] = useState(null); + const closeRef = useRef(null); + const rebuildRef = useRef(null); async function handleRebuild() { setRebuilding(true); @@ -28,6 +30,20 @@ export default function DoctorPanel({ path, onClose, onRebuild }: DoctorPanelPro } } + function handleCloseKeyDown(e: ReactKeyboardEvent) { + if (e.shiftKey && e.key === "Tab") { + e.preventDefault(); + rebuildRef.current?.focus(); + } + } + + function handleRebuildKeyDown(e: ReactKeyboardEvent) { + if (e.key === "Tab" && !e.shiftKey) { + e.preventDefault(); + closeRef.current?.focus(); + } + } + useEffect(() => { let cancelled = false; void runDoctor(path) @@ -45,36 +61,60 @@ export default function DoctorPanel({ path, onClose, onRebuild }: DoctorPanelPro }; }, [path]); + useEffect(() => { + closeRef.current?.focus(); + }, []); + + useEffect(() => { + function onKeyDown(e: KeyboardEvent) { + if (e.key === "Escape") onClose(); + } + window.addEventListener("keydown", onKeyDown); + return () => window.removeEventListener("keydown", onKeyDown); + }, [onClose]); + return (
-

Trachyte Doctor

- +

+ Trachyte Doctor +

- {rebuildResult !== null && ( -

- {rebuildResult} -

- )}
+ + {rebuildResult !== null && ( +

+ {rebuildResult} +

+ )} + {loading &&

Checking vault health…

} {!loading && error !== null &&

Error: {error}

} From 8472f6d3c43924c300049fe42000e2df0f26d62e Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Tue, 11 Aug 2026 22:33:18 +0530 Subject: [PATCH 2/3] Fix: Updated rebuild index to a better less fragile async method --- apps/desktop/src/routes/Home.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/routes/Home.tsx b/apps/desktop/src/routes/Home.tsx index 82c4640..6e0c0be 100644 --- a/apps/desktop/src/routes/Home.tsx +++ b/apps/desktop/src/routes/Home.tsx @@ -187,7 +187,9 @@ export default function Home() { key={openedVault} path={openedVault} onClose={() => setDoctorOpen(false)} - onRebuild={() => indexer!.rebuild()} + onRebuild={async () => { + if (indexer !== null) await indexer.rebuild(); + }} /> )} {paletteOpen && openedVault !== null && ( From dd143933f5d53e8929d7c0c67a991243c76c5323 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Tue, 11 Aug 2026 22:35:09 +0530 Subject: [PATCH 3/3] Updated Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b74fbf..adc1fbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,5 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Vault creation no longer lands inside the app's working tree (`apps/desktop/src-tauri/…`), which caused `tauri dev` rebuilds to restart the window and wipe the open vault/note state - External-change reloader no longer unsubscribes itself under React StrictMode (idempotent `start()` / `dispose()` lifecycle) +- Doctor panel layout: "Rebuild index" button and its result no longer render inside the header row (was breaking the `flex` header layout) +- Doctor panel modal a11y: focus trap (Tab wraps close ⇄ rebuild), `Escape` to close, auto-focus on open, accessible name via `aria-labelledby` +- `Home.tsx`: index rebuild no longer uses the `indexer!` non-null assertion ### Removed