From b6abfe8f038be51ade6d35328d4c2bec8a592adb Mon Sep 17 00:00:00 2001 From: William Mantly Date: Tue, 28 Jul 2026 13:27:12 -0400 Subject: [PATCH] Directory: tree view is now the only view; click a name for detail - Removed the list/tree view toggle -- tree (with indentation/parent arrows) is always used. Simplifies renderTable() back down to one code path instead of branching on a view mode nobody was toggling away from in practice. - Clicking a resource's name now opens the same modal the pencil/edit button does, rather than requiring the small icon click. The edit modal already surfaces full detail (parent, addresses, OAuth config, groups, edges) for every resource kind, so this reuses it rather than building a second, read-only view that would drift from the real one. Verified live: tree view renders correctly with no toggle present, and clicking a name (tested on the theta-proxy OAuth resource) opens the detail modal with the correct parent already selected -- also confirming the earlier "OAuth client has no parent" fix end-to-end. Co-Authored-By: Claude Sonnet 5 --- nodejs/views/directory.ejs | 84 ++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/nodejs/views/directory.ejs b/nodejs/views/directory.ejs index d7f5003..c1b17aa 100644 --- a/nodejs/views/directory.ejs +++ b/nodejs/views/directory.ejs @@ -15,12 +15,6 @@ -
- - - - -
@@ -49,7 +43,12 @@ {{{indentHtml}}} {{kind}}{{#metadata.subType}} ({{metadata.subType}}){{/metadata.subType}} - {{name}}
{{slug}} + + + {{name}} + +
{{slug}} + {{#metadata.isProduction}}Prod{{/metadata.isProduction}} {{^metadata.isProduction}}Dev{{/metadata.isProduction}} @@ -376,8 +375,7 @@ function renderTable() { const filter = $('#search-filter').val().toLowerCase(); const sort = $('#sort-by').val(); - const viewMode = $('input[name="viewMode"]:checked').val(); - + let filtered = rawResources.filter(r => { if (!filter) return true; return (r.name || '').toLowerCase().includes(filter) || @@ -402,42 +400,38 @@ let finalRenderList = []; - if (viewMode === 'tree') { - const map = {}; - const roots = []; - filtered.forEach(r => { map[r.id] = { ...r, children: [] }; }); - - filtered.forEach(r => { - const node = map[r.id]; - if (node.parentId && map[node.parentId]) { - map[node.parentId].children.push(node); - } else { - roots.push(node); - } - }); - - const flatten = (nodes, depth) => { - nodes.forEach(n => { - let indentHtml = ''; - for(let i = 0; i < depth; i++) { - indentHtml += ''; - } - if (depth > 0) { - indentHtml += ''; - } - n.indentHtml = indentHtml; - finalRenderList.push(n); - if (n.children.length > 0) { - flatten(n.children, depth + 1); - } - }); - }; - - flatten(roots, 0); - } else { - finalRenderList = filtered.map(r => ({ ...r, indentHtml: '' })); - } - + const map = {}; + const roots = []; + filtered.forEach(r => { map[r.id] = { ...r, children: [] }; }); + + filtered.forEach(r => { + const node = map[r.id]; + if (node.parentId && map[node.parentId]) { + map[node.parentId].children.push(node); + } else { + roots.push(node); + } + }); + + const flatten = (nodes, depth) => { + nodes.forEach(n => { + let indentHtml = ''; + for(let i = 0; i < depth; i++) { + indentHtml += ''; + } + if (depth > 0) { + indentHtml += ''; + } + n.indentHtml = indentHtml; + finalRenderList.push(n); + if (n.children.length > 0) { + flatten(n.children, depth + 1); + } + }); + }; + + flatten(roots, 0); + $.scope.resources.empty(); for (const r of finalRenderList) { $.scope.resources.push(r);