Drop generated cards; registry descriptions become Elements tooltips
- resolveRefs no longer adds cards to a diagram; it returns node id → description, which the page sets as the tooltip of the matching row in Archify's Elements panel - hand-written cards pass through unchanged; docs and changelog
This commit is contained in:
+7
-48
@@ -55,42 +55,6 @@ export interface Registry {
|
||||
problems: ModelProblem[];
|
||||
}
|
||||
|
||||
/** Archify card dot colour for a component type (the colours Archify gives the nodes). */
|
||||
const DOT_BY_TYPE: Record<string, string> = {
|
||||
frontend: 'cyan',
|
||||
backend: 'emerald',
|
||||
database: 'violet',
|
||||
cloud: 'amber',
|
||||
security: 'rose',
|
||||
messagebus: 'orange',
|
||||
external: 'slate',
|
||||
};
|
||||
|
||||
export function dotForType(type?: string): string {
|
||||
return DOT_BY_TYPE[type ?? ''] ?? 'slate';
|
||||
}
|
||||
|
||||
export interface Card {
|
||||
dot: string;
|
||||
title: string;
|
||||
items: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Archify info cards for registry elements: one per element that has a
|
||||
* description, titled by its label. What a diagram gets below itself when
|
||||
* it draws shared elements and defines no cards of its own.
|
||||
*/
|
||||
export function cardsFromElements(elements: Iterable<RegistryElement>): Card[] {
|
||||
const cards: Card[] = [];
|
||||
for (const element of elements) {
|
||||
if (!element.description) continue;
|
||||
const items = [element.description.trim()];
|
||||
cards.push({ dot: dotForType(element.type), title: element.label ?? element.id, items });
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
|
||||
export function isMainFile(fileName: string): boolean {
|
||||
return (fileName.split(/[\\/]/).pop() ?? '') === MAIN_FILE;
|
||||
}
|
||||
@@ -196,6 +160,8 @@ export interface ResolvedDiagram {
|
||||
links: Map<string, string>;
|
||||
/** Registry element ids used by this diagram. */
|
||||
used: Set<string>;
|
||||
/** Node id → registry description, for the Elements panel. */
|
||||
descriptions: Map<string, string>;
|
||||
}
|
||||
|
||||
export interface ResolveOptions {
|
||||
@@ -208,20 +174,19 @@ export interface ResolveOptions {
|
||||
* Expands `ref` components from the registry and strips what Archify does
|
||||
* not know. Component order and indexes are kept, so Archify's diagnostics
|
||||
* (JSON pointers) still point at the right component in the source file.
|
||||
* A diagram without `cards` of its own gets cards from the descriptions of
|
||||
* the shared elements it draws, so the registry text shows under the diagram.
|
||||
*/
|
||||
export function resolveRefs(doc: unknown, options: ResolveOptions): ResolvedDiagram {
|
||||
const problems: ModelProblem[] = [];
|
||||
const refs = new Map<number, RegistryElement>();
|
||||
const links = new Map<string, string>();
|
||||
const used = new Set<string>();
|
||||
if (!isObj(doc)) return { diagram: {}, problems, refs, links, used };
|
||||
const descriptions = new Map<string, string>();
|
||||
if (!isObj(doc)) return { diagram: {}, problems, refs, links, used, descriptions };
|
||||
const diagram: Obj = { ...doc };
|
||||
delete diagram.model;
|
||||
const { registry } = options;
|
||||
const components = Array.isArray(doc.components) ? doc.components : undefined;
|
||||
if (!components) return { diagram, problems, refs, links, used };
|
||||
if (!components) return { diagram, problems, refs, links, used, descriptions };
|
||||
|
||||
diagram.components = components.map((raw, index) => {
|
||||
if (!isObj(raw)) return raw;
|
||||
@@ -248,6 +213,7 @@ export function resolveRefs(doc: unknown, options: ResolveOptions): ResolvedDiag
|
||||
}
|
||||
used.add(ref);
|
||||
refs.set(index, element);
|
||||
if (element.description) descriptions.set(id, element.description.trim());
|
||||
for (const key of Object.keys(own)) {
|
||||
if ((COPIED_FIELDS as readonly string[]).includes(key) && !(OVERRIDABLE_FIELDS as readonly string[]).includes(key)) {
|
||||
problems.push({
|
||||
@@ -267,14 +233,7 @@ export function resolveRefs(doc: unknown, options: ResolveOptions): ResolvedDiag
|
||||
if (link) links.set(id, link);
|
||||
return merged;
|
||||
});
|
||||
if (diagram.cards === undefined && refs.size) {
|
||||
const seen = new Set<string>();
|
||||
const elements: RegistryElement[] = [];
|
||||
for (const element of refs.values()) if (!seen.has(element.id)) { seen.add(element.id); elements.push(element); }
|
||||
const cards = cardsFromElements(elements);
|
||||
if (cards.length) diagram.cards = cards;
|
||||
}
|
||||
return { diagram, problems, refs, links, used };
|
||||
return { diagram, problems, refs, links, used, descriptions };
|
||||
}
|
||||
|
||||
/** Group of a diagram inside a model: '' for the root folder, else the folder path with '/' separators. */
|
||||
|
||||
@@ -16,6 +16,8 @@ export interface PreparedDiagram {
|
||||
problems: ModelProblem[];
|
||||
/** Node id → diagram path relative to the model root. */
|
||||
links: Map<string, string>;
|
||||
/** Node id → registry description. */
|
||||
descriptions: Map<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,5 +35,5 @@ export async function prepareDiagram(models: ModelService, uri: vscode.Uri, text
|
||||
const prepared: DiagramSource = changed
|
||||
? { ...source, diagram: resolved.diagram, json: JSON.stringify(resolved.diagram, null, 2) }
|
||||
: source;
|
||||
return { source: prepared, root: found?.root, registry: found?.registry, problems: resolved.problems, links: resolved.links };
|
||||
return { source: prepared, root: found?.root, registry: found?.registry, problems: resolved.problems, links: resolved.links, descriptions: resolved.descriptions };
|
||||
}
|
||||
|
||||
@@ -199,10 +199,11 @@ class DiagramPreview implements vscode.Disposable {
|
||||
notice: result.evidenceNotice ? { kind: 'warning', text: result.evidenceNotice } : undefined,
|
||||
viewer3d: viewer3dOption(this.panel.webview, this.context.extensionUri),
|
||||
links: Object.fromEntries(prepared.links),
|
||||
descriptions: Object.fromEntries(prepared.descriptions),
|
||||
model,
|
||||
});
|
||||
// Nonces differ per render, so compare the renderer output instead.
|
||||
const fingerprint = `${viewerTheme()}\u0000${result.evidenceNotice ?? ''}\u0000${JSON.stringify([model ?? null, [...prepared.links]])}\u0000${result.html}`;
|
||||
const fingerprint = `${viewerTheme()}\u0000${result.evidenceNotice ?? ''}\u0000${JSON.stringify([model ?? null, [...prepared.links], [...prepared.descriptions]])}\u0000${result.html}`;
|
||||
if (!force && this.rendered && fingerprint === this.lastHtml) {
|
||||
void this.panel.webview.postMessage({ type: 'notice', notice: undefined });
|
||||
return;
|
||||
|
||||
@@ -18,6 +18,8 @@ export interface PageOptions {
|
||||
links?: Record<string, string>;
|
||||
/** The model page: metadata above the diagram, the diagram list and registry below. */
|
||||
model?: ModelPanel;
|
||||
/** Node id → registry description, shown as tooltips in the Elements panel. */
|
||||
descriptions?: Record<string, string>;
|
||||
/** Registry page: the elements of one .archify-registry file. */
|
||||
registry?: RegistryPanel;
|
||||
}
|
||||
@@ -77,6 +79,7 @@ function bridgeScript(options: PageOptions): string {
|
||||
links: options.links ?? {},
|
||||
model: options.model,
|
||||
registry: options.registry,
|
||||
descriptions: options.descriptions || {},
|
||||
};
|
||||
return `(function () {
|
||||
var config = ${scriptJson(config)};
|
||||
@@ -322,6 +325,15 @@ function bridgeScript(options: PageOptions): string {
|
||||
document.body.appendChild(body);
|
||||
}
|
||||
|
||||
// Elements: registry descriptions as tooltips on Archify's node index rows.
|
||||
function describeElements() {
|
||||
var items = document.querySelectorAll('#node-outline .node-outline-item[data-outline-node]');
|
||||
Array.prototype.forEach.call(items, function (item) {
|
||||
var text = config.descriptions[item.getAttribute('data-outline-node')];
|
||||
if (text) item.title = text;
|
||||
});
|
||||
}
|
||||
|
||||
// Connectors: a rail panel next to Archify's Elements index, read from the
|
||||
// SVG's edges. Hover highlights the connector, click keeps it highlighted.
|
||||
function renderConnectors() {
|
||||
@@ -486,6 +498,7 @@ function bridgeScript(options: PageOptions): string {
|
||||
if (config.model) onReady(function () { renderModel(config.model); });
|
||||
if (config.registry) onReady(function () { renderRegistry(config.registry); });
|
||||
onReady(renderConnectors);
|
||||
onReady(describeElements);
|
||||
if (config.notice) {
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', function () { showNotice(config.notice); });
|
||||
|
||||
Reference in New Issue
Block a user