Registry view with element dialog; Elements and Connectors panels under diagrams
- .archify-registry opens in a new read-only custom editor (archify.registry, default): the file's elements as cards; click one for a dialog with its description, the defining line (opens the YAML) and the diagrams that use it (open on click); Show Source and Open Model work from the view - the same dialog opens from the registry cards on the model page - Archify's node index is titled Elements; a Connectors panel built from the SVG edges lists from → to with the label, highlights on hover and keeps the highlight on click; side by side in the bottom rail - integration test for the registry view; docs and changelog
This commit is contained in:
+85
-4
@@ -1,20 +1,76 @@
|
||||
import { DiagramSummary, RegistryElement } from './format';
|
||||
import { ModelIndex } from './service';
|
||||
|
||||
/** A diagram an element is used in, as the pages show it. */
|
||||
export interface UsedIn {
|
||||
path: string;
|
||||
title?: string;
|
||||
kind?: string;
|
||||
}
|
||||
|
||||
/** A registry element as the model page and the registry page show it. */
|
||||
export interface ElementCard {
|
||||
id: string;
|
||||
label?: string;
|
||||
sublabel?: string;
|
||||
type?: string;
|
||||
brand?: string;
|
||||
description?: string;
|
||||
/** Diagram that explains the element, relative to the model root. */
|
||||
diagram?: string;
|
||||
/** Registry file (relative to the model root) and 0-based line of the element. */
|
||||
file: string;
|
||||
line: number;
|
||||
usedIn: UsedIn[];
|
||||
}
|
||||
|
||||
/** What the model page shows; serialised into the webview. */
|
||||
export interface ModelPanel {
|
||||
meta: { id?: string; name?: string; description?: string };
|
||||
/** True when main.archify also carries a diagram, shown between metadata and the list. */
|
||||
hasDiagram: boolean;
|
||||
groups: { group: string; diagrams: { path: string; title?: string; kind?: string; parseError?: string }[] }[];
|
||||
registry: { id: string; label?: string; type?: string; description?: string; file: string; usedIn: string[] }[];
|
||||
registry: ElementCard[];
|
||||
problems: string[];
|
||||
nested: string[];
|
||||
}
|
||||
|
||||
/** What the registry page (one .archify-registry file) shows. */
|
||||
export interface RegistryPanel {
|
||||
/** The registry file, relative to the model root (or its base name outside a model). */
|
||||
file: string;
|
||||
inModel: boolean;
|
||||
model?: { id?: string; name?: string };
|
||||
elements: ElementCard[];
|
||||
problems: string[];
|
||||
}
|
||||
|
||||
function usedIn(id: string, usage: Map<string, string[]>, diagrams: DiagramSummary[]): UsedIn[] {
|
||||
return (usage.get(id) ?? []).map((path) => {
|
||||
const summary = diagrams.find((d) => d.relativePath === path);
|
||||
return { path, title: summary?.title, kind: summary?.kind };
|
||||
});
|
||||
}
|
||||
|
||||
export function elementCard(e: RegistryElement, usage: Map<string, string[]>, diagrams: DiagramSummary[]): ElementCard {
|
||||
return {
|
||||
id: e.id,
|
||||
label: e.label,
|
||||
sublabel: e.sublabel,
|
||||
type: e.type,
|
||||
brand: e.brand,
|
||||
description: e.description,
|
||||
diagram: e.diagram,
|
||||
file: e.file,
|
||||
line: e.line,
|
||||
usedIn: usedIn(e.id, usage, diagrams),
|
||||
};
|
||||
}
|
||||
|
||||
const byId = (a: { id: string }, b: { id: string }) => a.id.localeCompare(b.id);
|
||||
|
||||
export function panelFromIndex(index: ModelIndex): ModelPanel {
|
||||
const registry = [...index.registry.elements.values()]
|
||||
.sort((a, b) => a.id.localeCompare(b.id))
|
||||
.map((e) => ({ id: e.id, label: e.label, type: e.type, description: e.description, file: e.file, usedIn: index.usage.get(e.id) ?? [] }));
|
||||
const registry = [...index.registry.elements.values()].sort(byId).map((e) => elementCard(e, index.usage, index.diagrams));
|
||||
return {
|
||||
meta: index.meta,
|
||||
hasDiagram: index.mainHasDiagram,
|
||||
@@ -27,3 +83,28 @@ export function panelFromIndex(index: ModelIndex): ModelPanel {
|
||||
nested: index.nested,
|
||||
};
|
||||
}
|
||||
|
||||
/** The registry page of one file inside a model: its elements, in file order, with usage. */
|
||||
export function registryPanelFromIndex(index: ModelIndex, file: string): RegistryPanel {
|
||||
const elements = [...index.registry.elements.values()]
|
||||
.filter((e) => e.file === file)
|
||||
.sort((a, b) => a.line - b.line)
|
||||
.map((e) => elementCard(e, index.usage, index.diagrams));
|
||||
return {
|
||||
file,
|
||||
inModel: true,
|
||||
model: { id: index.meta.id, name: index.meta.name },
|
||||
elements,
|
||||
problems: index.registry.problems.filter((p) => p.file === file).map((p) => p.message),
|
||||
};
|
||||
}
|
||||
|
||||
/** The registry page of a file outside a model: elements only, nothing is used anywhere. */
|
||||
export function registryPanelStandalone(file: string, parsed: { elements: RegistryElement[]; problems: { message: string }[] }): RegistryPanel {
|
||||
return {
|
||||
file,
|
||||
inModel: false,
|
||||
elements: parsed.elements.map((e) => elementCard(e, new Map(), [])),
|
||||
problems: parsed.problems.map((p) => p.message),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user