graphvault-studio 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5
4
+
5
+ - Restore the Object Hierarchy view as an expandable lazy tree with persistent root context instead of a drilldown-only list.
6
+
3
7
  ## 0.1.4
4
8
 
5
9
  - Add production safety status and score to the summary API, Overview, KPI bar, and Operations view.
package/dist/admin-ui.js CHANGED
@@ -231,7 +231,11 @@ OFFSET 0</textarea>
231
231
  const authTokenInput = document.getElementById('authToken');
232
232
  const objectPageSize = 100;
233
233
  let objectPageOffset = 0;
234
- let hierarchyPath = [];
234
+ let hierarchyRootId = '';
235
+ let selectedHierarchyId = '';
236
+ const hierarchyExpanded = new Set();
237
+ const hierarchyRecords = new Map();
238
+ const hierarchyChildren = new Map();
235
239
  let gvqlEditorWired = false;
236
240
  const viewText = {
237
241
  hierarchy: ['Object Hierarchy', 'Root-first graph view with references you can follow.'],
@@ -336,7 +340,7 @@ OFFSET 0</textarea>
336
340
  async function showHierarchy() {
337
341
  setView('hierarchy');
338
342
  listTitle.textContent = 'Object hierarchy';
339
- listHint.textContent = 'Lazy loaded';
343
+ listHint.textContent = 'Expandable lazy tree';
340
344
  await refreshKpis();
341
345
  const root = await apiJson('/api/root');
342
346
  if (!root.rootObjectId) {
@@ -344,29 +348,75 @@ OFFSET 0</textarea>
344
348
  show(root);
345
349
  return;
346
350
  }
347
- await showObjectWithChildren(root.rootObjectId, 'root', []);
348
- show({ root: root.rootObjectId, note: 'Only the visible branch is loaded. Click a row to drill into its children.' });
351
+ hierarchyRootId = root.rootObjectId;
352
+ selectedHierarchyId = selectedHierarchyId || hierarchyRootId;
353
+ hierarchyExpanded.add(hierarchyRootId);
354
+ await ensureHierarchyNode(hierarchyRootId);
355
+ await renderHierarchyTree();
356
+ await selectHierarchyObject(selectedHierarchyId, 'root');
349
357
  }
350
- async function showObjectWithChildren(id, label, parentPath) {
358
+ async function ensureHierarchyNode(id) {
359
+ if (!hierarchyRecords.has(id)) {
360
+ hierarchyRecords.set(id, await apiJson('/api/objects/' + encodeURIComponent(id)));
361
+ }
362
+ if (!hierarchyChildren.has(id)) {
363
+ hierarchyChildren.set(id, await apiJson('/api/objects/' + encodeURIComponent(id) + '/children'));
364
+ }
365
+ return {
366
+ record: hierarchyRecords.get(id),
367
+ children: hierarchyChildren.get(id) || []
368
+ };
369
+ }
370
+ async function selectHierarchyObject(id, label) {
351
371
  document.getElementById('graphRoot').value = id;
352
- const record = await apiJson('/api/objects/' + encodeURIComponent(id));
353
- hierarchyPath = parentPath.concat([{ id, label, record }]);
372
+ selectedHierarchyId = id;
373
+ const data = await ensureHierarchyNode(id);
374
+ const record = data.record;
354
375
  renderEditableFields(record);
355
376
  document.getElementById('mid').value = id;
356
377
  document.getElementById('detailHint').textContent = 'Object #' + id;
357
378
  out.textContent = JSON.stringify(record, null, 2);
358
- const children = await apiJson('/api/objects/' + encodeURIComponent(id) + '/children');
359
- const rows = hierarchyPath.map((entry, index) => ({
360
- depth: index,
361
- columns: ['#' + entry.record.objectId, entry.record.node.type || entry.record.node.kind, entry.label + ' -> ' + summarizeRecord(entry.record), index === hierarchyPath.length - 1 ? 'current' : 'parent'],
362
- onclick: () => showObjectWithChildren(entry.id, entry.label, hierarchyPath.slice(0, index))
363
- })).concat(children.map(child => ({
364
- depth: hierarchyPath.length,
365
- columns: ['#' + child.to, child.type || child.kind, child.path + ' -> ' + child.preview, 'open'],
366
- onclick: () => showObjectWithChildren(child.to, child.path, hierarchyPath)
367
- })));
379
+ }
380
+ async function toggleHierarchyObject(id, label) {
381
+ const data = await ensureHierarchyNode(id);
382
+ if (data.children.length) {
383
+ if (hierarchyExpanded.has(id)) hierarchyExpanded.delete(id);
384
+ else hierarchyExpanded.add(id);
385
+ }
386
+ await selectHierarchyObject(id, label);
387
+ await renderHierarchyTree();
388
+ }
389
+ async function renderHierarchyTree() {
390
+ if (!hierarchyRootId) return;
391
+ const rows = [];
392
+ await appendHierarchyRows(rows, hierarchyRootId, 'root', 0, []);
368
393
  setRows(rows, 'No children');
369
394
  }
395
+ async function appendHierarchyRows(rows, id, label, depth, path) {
396
+ const data = await ensureHierarchyNode(id);
397
+ const record = data.record;
398
+ const children = data.children;
399
+ const isExpanded = hierarchyExpanded.has(id);
400
+ const marker = children.length ? (isExpanded ? '[-] ' : '[+] ') : ' ';
401
+ rows.push({
402
+ depth,
403
+ columns: [marker + '#' + record.objectId, record.node.type || record.node.kind, label + ' -> ' + summarizeRecord(record), id === selectedHierarchyId ? 'selected' : children.length + ' children'],
404
+ onclick: () => toggleHierarchyObject(id, label)
405
+ });
406
+ if (!isExpanded) return;
407
+ const nextPath = path.concat(id);
408
+ for (const child of children) {
409
+ if (nextPath.includes(child.to)) {
410
+ rows.push({
411
+ depth: depth + 1,
412
+ columns: ['[ref] #' + child.to, child.type || child.kind, child.path + ' -> cycle/shared reference', 'linked'],
413
+ onclick: () => selectHierarchyObject(child.to, child.path)
414
+ });
415
+ } else {
416
+ await appendHierarchyRows(rows, child.to, child.path, depth + 1, nextPath);
417
+ }
418
+ }
419
+ }
370
420
  async function showObjectInHierarchyPath(id) {
371
421
  document.getElementById('graphRoot').value = id;
372
422
  setView('hierarchy');
@@ -1 +1 @@
1
- {"version":3,"file":"admin-ui.js","sourceRoot":"","sources":["../src/admin-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAmOC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAgvBvD,CAAC"}
1
+ {"version":3,"file":"admin-ui.js","sourceRoot":"","sources":["../src/admin-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAmOC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkyBvD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphvault-studio",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Graphical admin client for GraphVault object graph stores.",
5
5
  "repository": {
6
6
  "type": "git",