Model page: Diagrams and Registry as collapsible panels, one header per folder
- <details> panels for Diagrams (open) and Registry (closed by default) - each folder inside Diagrams is its own collapsible header with a count, above its diagram cards; diagrams next to main.archify list directly - open/closed state is kept in the webview state, so re-renders and restores keep it
This commit is contained in:
+50
-9
@@ -183,6 +183,25 @@ function bridgeScript(options: PageOptions): string {
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Collapsible panels of the model page; open/closed is kept in the webview state.
|
||||
function panelStates() { return (vscode.getState() || {}).modelPanels || {}; }
|
||||
function panel(key, className, title, count, defaultOpen) {
|
||||
var details = el('details', 'archify-model-panel ' + className);
|
||||
var saved = panelStates()[key];
|
||||
details.open = saved === undefined ? defaultOpen : saved;
|
||||
var summary = el('summary', 'archify-model-summary');
|
||||
summary.appendChild(el('span', 'archify-model-chevron'));
|
||||
summary.appendChild(el('span', 'archify-model-summary-title', title));
|
||||
if (count !== undefined) summary.appendChild(el('span', 'archify-model-count', String(count)));
|
||||
details.appendChild(summary);
|
||||
details.addEventListener('toggle', function () {
|
||||
var states = panelStates();
|
||||
states[key] = details.open;
|
||||
vscode.setState(Object.assign({}, vscode.getState() || {}, { modelPanels: states }));
|
||||
});
|
||||
return details;
|
||||
}
|
||||
|
||||
var DOT_BY_TYPE = { frontend: 'cyan', backend: 'emerald', database: 'violet', cloud: 'amber', security: 'rose', messagebus: 'orange', external: 'slate' };
|
||||
function dotForType(type) { return DOT_BY_TYPE[type || ''] || 'slate'; }
|
||||
|
||||
@@ -208,10 +227,16 @@ function bridgeScript(options: PageOptions): string {
|
||||
|
||||
var body = el('section', 'archify-model archify-model-body');
|
||||
var count = model.groups.reduce(function (n, g) { return n + g.diagrams.length; }, 0);
|
||||
body.appendChild(el('h2', 'archify-model-title', 'Diagrams' + (count ? ' · ' + count : '')));
|
||||
if (!count) body.appendChild(el('p', 'archify-model-empty', 'No diagrams yet. Add .archify files next to main.archify or in subfolders.'));
|
||||
var diagramsPanel = panel('diagrams', 'archify-model-diagrams', 'Diagrams', count, true);
|
||||
body.appendChild(diagramsPanel);
|
||||
if (!count) diagramsPanel.appendChild(el('p', 'archify-model-empty', 'No diagrams yet. Add .archify files next to main.archify or in subfolders.'));
|
||||
model.groups.forEach(function (group) {
|
||||
if (group.group) body.appendChild(el('h3', 'archify-model-group', group.group));
|
||||
// Each folder is its own collapsible header; diagrams next to main.archify are listed directly.
|
||||
var holder = diagramsPanel;
|
||||
if (group.group) {
|
||||
holder = panel('folder:' + group.group, 'archify-model-folder', group.group, group.diagrams.length, true);
|
||||
diagramsPanel.appendChild(holder);
|
||||
}
|
||||
var list = el('ul', 'archify-model-list');
|
||||
group.diagrams.forEach(function (diagram) {
|
||||
var item = el('li', 'archify-model-item' + (diagram.parseError ? ' is-broken' : ''));
|
||||
@@ -224,11 +249,12 @@ function bridgeScript(options: PageOptions): string {
|
||||
item.appendChild(button);
|
||||
list.appendChild(item);
|
||||
});
|
||||
body.appendChild(list);
|
||||
holder.appendChild(list);
|
||||
});
|
||||
// Registry elements as Archify info cards: the same cards a diagram shows below itself.
|
||||
if (model.registry.length) {
|
||||
body.appendChild(el('h2', 'archify-model-title', 'Registry · ' + model.registry.length));
|
||||
var registryPanel = panel('registry', 'archify-model-registry', 'Registry', model.registry.length, false);
|
||||
body.appendChild(registryPanel);
|
||||
var cards = el('div', 'cards archify-model-cards');
|
||||
model.registry.forEach(function (element) {
|
||||
var card = el('div', 'card archify-model-card');
|
||||
@@ -253,7 +279,7 @@ function bridgeScript(options: PageOptions): string {
|
||||
card.appendChild(list);
|
||||
cards.appendChild(card);
|
||||
});
|
||||
body.appendChild(cards);
|
||||
registryPanel.appendChild(cards);
|
||||
}
|
||||
if (anchor && anchor.parentNode) anchor.parentNode.insertBefore(body, anchor.nextSibling); else document.body.appendChild(body);
|
||||
}
|
||||
@@ -287,8 +313,23 @@ const MODEL_STYLE = `
|
||||
.archify-model-name { margin: 0.25rem 0 0.5rem; font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; }
|
||||
.archify-model-description { margin: 0; max-width: 72ch; font-size: 0.9375rem; line-height: 1.55; color: var(--m-muted); white-space: pre-line; }
|
||||
.archify-model-problem { margin: 0.75rem 0 0; padding: 0.5rem 0.75rem; border-radius: 0.5rem; border: 1px solid var(--vscode-inputValidation-errorBorder, #be1100); color: var(--m-text); font-size: 0.8125rem; }
|
||||
.archify-model-title { margin: 1.5rem 0 0.75rem; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; }
|
||||
.archify-model-group { margin: 1rem 0 0.25rem; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--m-muted); font-family: ui-monospace, Menlo, monospace; }
|
||||
/* Collapsible panels: Diagrams and Registry, and one per folder inside Diagrams. */
|
||||
.archify-model-panel { margin: 1rem 0 0; border: 1px solid var(--m-border); border-radius: 0.75rem; background: var(--m-panel); }
|
||||
.archify-model-panel[open] { padding-bottom: 0.85rem; }
|
||||
.archify-model-summary { display: flex; align-items: center; gap: 0.6rem; padding: 0.75rem 0.9rem; cursor: pointer; list-style: none; user-select: none; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; color: var(--m-text); }
|
||||
.archify-model-summary::-webkit-details-marker { display: none; }
|
||||
.archify-model-summary:hover { color: var(--m-accent); }
|
||||
.archify-model-summary:focus-visible { outline: 2px solid var(--m-accent); outline-offset: -2px; border-radius: 0.75rem; }
|
||||
.archify-model-chevron { flex: none; width: 0.5rem; height: 0.5rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform 0.15s; opacity: 0.7; margin-left: 0.1rem; }
|
||||
.archify-model-panel[open] > .archify-model-summary > .archify-model-chevron { transform: rotate(45deg); }
|
||||
.archify-model-count { margin-left: auto; font-size: 0.75rem; font-weight: 500; color: var(--m-muted); font-family: ui-monospace, Menlo, monospace; padding: 0.05rem 0.5rem; border: 1px solid var(--m-border); border-radius: 999px; }
|
||||
.archify-model-panel > .archify-model-list, .archify-model-panel > .archify-model-cards, .archify-model-panel > .archify-model-empty { margin: 0 0.9rem; }
|
||||
.archify-model-folder { margin: 0.35rem 0.9rem 0; background: transparent; border-radius: 0.6rem; }
|
||||
.archify-model-folder[open] { padding-bottom: 0.7rem; }
|
||||
.archify-model-folder > .archify-model-summary { padding: 0.55rem 0.75rem; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--m-muted); font-family: ui-monospace, Menlo, monospace; }
|
||||
.archify-model-folder > .archify-model-summary:hover { color: var(--m-accent); }
|
||||
.archify-model-folder > .archify-model-list { margin: 0 0.75rem; }
|
||||
.archify-model-diagrams > .archify-model-list { margin-top: 0.25rem; }
|
||||
.archify-model-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.5rem; }
|
||||
.archify-model-open { display: flex; flex-direction: column; gap: 0.2rem; width: 100%; padding: 0.7rem 0.85rem; text-align: left; cursor: pointer; font: inherit; color: var(--m-text); background: var(--m-panel); border: 1px solid var(--m-border); border-radius: 0.6rem; transition: border-color 0.15s, transform 0.15s; }
|
||||
.archify-model-open:hover { border-color: var(--m-accent); transform: translateY(-1px); }
|
||||
@@ -299,7 +340,7 @@ const MODEL_STYLE = `
|
||||
.archify-model-empty { color: var(--m-muted); }
|
||||
/* Registry cards: Archify's own .card look, with fallbacks for the page without a diagram. */
|
||||
.archify-model { --m-frontend: var(--frontend-stroke, #22d3ee); --m-backend: var(--backend-stroke, #34d399); --m-database: var(--database-stroke, #a78bfa); --m-cloud: var(--cloud-stroke, #fbbf24); --m-security: var(--security-stroke, #fb7185); --m-messagebus: var(--messagebus-stroke, #fb923c); --m-external: var(--external-stroke, #94a3b8); }
|
||||
.archify-model-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: 1rem; margin-top: 0.75rem; }
|
||||
.archify-model-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: 1rem; margin-top: 0.25rem; }
|
||||
.archify-model-card { background: var(--m-panel); border: 1px solid var(--m-border); border-radius: 0.75rem; padding: 1.125rem 1.25rem; }
|
||||
.archify-model-card .card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.6rem; }
|
||||
.archify-model-card .card-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; }
|
||||
|
||||
Reference in New Issue
Block a user