feat(desktop): add typed inspector panels

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Senior Frontend Engineer
2026-03-28 11:16:39 +00:00
parent a9524dfbf6
commit 7c1abf2fd1
7 changed files with 397 additions and 11 deletions

View File

@@ -45,6 +45,10 @@ import {
toBackendErrorNotice,
type OperatorNotice,
} from "./lib/operator-notices";
import {
buildStructuredInspectorSections,
type StructuredInspectorSection,
} from "./lib/structured-inspector";
import { cn } from "./lib/utils";
declare const __APP_VERSION__: string;
@@ -439,6 +443,14 @@ function App() {
const inspectorText = tauriAvailable
? formatInspectorValue(selectedValueRecord, selectedKey, isInspectorLoading)
: (selectedKey?.value ?? "");
const structuredInspectorSections = tauriAvailable
? buildStructuredInspectorSections(selectedValueRecord)
: [];
const showStructuredInspector =
selectedKey !== null &&
!isInspectorLoading &&
structuredInspectorSections.length > 0 &&
!isEditable;
const supportNote = tauriAvailable
? buildLiveSupportNote(selectedValueRecord, selectedKey)
@@ -1662,15 +1674,20 @@ function App() {
</div>
{selectedKey ? (
<Textarea
value={isEditable ? draftValue : inspectorText}
onChange={(event) => setDraftValue(event.target.value)}
readOnly={!isEditable}
className={cn(
"mt-3 h-64 resize-none font-mono",
!isEditable && "border-[var(--line-soft)] bg-[var(--surface-muted)] text-[var(--ink-soft)]",
)}
/>
showStructuredInspector ? (
<StructuredInspectorPanels sections={structuredInspectorSections} />
) : (
<Textarea
value={isEditable ? draftValue : inspectorText}
onChange={(event) => setDraftValue(event.target.value)}
readOnly={!isEditable}
className={cn(
"mt-3 h-64 resize-none font-mono",
!isEditable &&
"border-[var(--line-soft)] bg-[var(--surface-muted)] text-[var(--ink-soft)]",
)}
/>
)
) : (
<div className="mt-3 flex h-64 items-center justify-center rounded-[22px] border border-dashed border-[var(--line-strong)] bg-[var(--surface-muted)] px-6 text-center text-sm text-[var(--ink-soft)]">
No key matches the current pattern in {activeDb}. Clear or adjust the search to restore an inspector target.
@@ -1944,6 +1961,85 @@ function InfoCard({
);
}
function StructuredInspectorPanels({
sections,
}: {
sections: StructuredInspectorSection[];
}) {
return (
<div className="mt-3 h-64 space-y-3 overflow-auto pr-1">
{sections.map((section) => (
<section
key={section.id}
className="rounded-[22px] border border-[var(--line-soft)] bg-[var(--surface-muted)] p-4"
>
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<p className="text-sm font-medium text-[var(--ink-0)]">{section.title}</p>
<p className="mt-1 text-sm text-[var(--ink-soft)]">{section.summary}</p>
</div>
<Badge variant="neutral">{section.rows.length} rows</Badge>
</div>
<div className="mt-4 hidden grid-cols-[minmax(0,0.38fr)_minmax(0,0.62fr)] gap-3 px-1 sm:grid">
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)]">
{section.primaryLabel}
</p>
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)]">
{section.secondaryLabel}
</p>
</div>
<div className="mt-3 space-y-2">
{section.rows.map((row) => (
<div
key={row.id}
className="grid gap-3 rounded-[18px] border border-[var(--line-soft)] bg-[var(--surface-base)] p-3 sm:grid-cols-[minmax(0,0.38fr)_minmax(0,0.62fr)]"
>
<div>
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)] sm:hidden">
{section.primaryLabel}
</p>
<p className="mt-1 break-all font-mono text-sm text-[var(--ink-0)] sm:mt-0">
{row.primary}
</p>
</div>
<div>
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)] sm:hidden">
{section.secondaryLabel}
</p>
<p className="mt-1 break-all font-mono text-sm text-[var(--ink-0)] sm:mt-0">
{row.secondary}
</p>
</div>
{row.detailLines && row.detailLines.length > 0 ? (
<div className="sm:col-span-2">
<p className="font-mono text-[11px] uppercase tracking-[0.18em] text-[var(--ink-muted)]">
Payload
</p>
<div className="mt-2 space-y-2">
{row.detailLines.map((detail) => (
<div
key={`${row.id}-${detail}`}
className="rounded-2xl border border-[var(--line-soft)] bg-[var(--surface-muted)] px-3 py-2 font-mono text-xs text-[var(--ink-soft)]"
>
{detail}
</div>
))}
</div>
</div>
) : null}
</div>
))}
</div>
</section>
))}
</div>
);
}
function isTauriRuntimeAvailable() {
return typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
}
@@ -2281,7 +2377,7 @@ function buildLiveSupportNote(record: RedisValueRecord | null, selectedKey: KeyR
case "set":
case "sorted_set":
case "stream":
return `${formatRedisKeyTypeLabel(record.metadata.key_type)} values are loaded live and remain explicitly read only in the current desktop contract.`;
return `${formatRedisKeyTypeLabel(record.metadata.key_type)} values are loaded live into structured read-only panels in the current desktop contract.`;
default:
return "The current key is available for live inspection through the desktop backend contract.";
}