Merge pull request #118 from theta42/feat/directory-tree-only-and-click-detail
Directory: tree view is now the only view; click a name for detail
This commit is contained in:
+39
-45
@@ -15,12 +15,6 @@
|
|||||||
<option value="kind">Kind</option>
|
<option value="kind">Kind</option>
|
||||||
<option value="env">Environment</option>
|
<option value="env">Environment</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="btn-group btn-group-sm shadow-sm" role="group">
|
|
||||||
<input type="radio" class="btn-check" name="viewMode" id="view-list" value="list" autocomplete="off" checked onchange="renderTable()">
|
|
||||||
<label class="btn btn-outline-secondary" for="view-list"><i class="fa-solid fa-list"></i></label>
|
|
||||||
<input type="radio" class="btn-check" name="viewMode" id="view-tree" value="tree" autocomplete="off" onchange="renderTable()">
|
|
||||||
<label class="btn btn-outline-secondary" for="view-tree"><i class="fa-solid fa-folder-tree"></i></label>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-sm btn-primary ms-1 shadow-sm" onclick="openAddModal()">
|
<button class="btn btn-sm btn-primary ms-1 shadow-sm" onclick="openAddModal()">
|
||||||
<i class="fas fa-plus"></i> Add Resource
|
<i class="fas fa-plus"></i> Add Resource
|
||||||
</button>
|
</button>
|
||||||
@@ -49,7 +43,12 @@
|
|||||||
{{{indentHtml}}}
|
{{{indentHtml}}}
|
||||||
<span class="badge bg-secondary">{{kind}}{{#metadata.subType}} ({{metadata.subType}}){{/metadata.subType}}</span>
|
<span class="badge bg-secondary">{{kind}}{{#metadata.subType}} ({{metadata.subType}}){{/metadata.subType}}</span>
|
||||||
</td>
|
</td>
|
||||||
<td><strong>{{name}}</strong><br><small class="text-muted">{{slug}}</small></td>
|
<td>
|
||||||
|
<a href="#" class="text-reset text-decoration-none" onclick="openEditModal('{{id}}'); return false;" title="View details">
|
||||||
|
<strong>{{name}}</strong>
|
||||||
|
</a>
|
||||||
|
<br><small class="text-muted">{{slug}}</small>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{#metadata.isProduction}}<span class="badge bg-danger">Prod</span>{{/metadata.isProduction}}
|
{{#metadata.isProduction}}<span class="badge bg-danger">Prod</span>{{/metadata.isProduction}}
|
||||||
{{^metadata.isProduction}}<span class="badge bg-info">Dev</span>{{/metadata.isProduction}}
|
{{^metadata.isProduction}}<span class="badge bg-info">Dev</span>{{/metadata.isProduction}}
|
||||||
@@ -376,8 +375,7 @@
|
|||||||
function renderTable() {
|
function renderTable() {
|
||||||
const filter = $('#search-filter').val().toLowerCase();
|
const filter = $('#search-filter').val().toLowerCase();
|
||||||
const sort = $('#sort-by').val();
|
const sort = $('#sort-by').val();
|
||||||
const viewMode = $('input[name="viewMode"]:checked').val();
|
|
||||||
|
|
||||||
let filtered = rawResources.filter(r => {
|
let filtered = rawResources.filter(r => {
|
||||||
if (!filter) return true;
|
if (!filter) return true;
|
||||||
return (r.name || '').toLowerCase().includes(filter) ||
|
return (r.name || '').toLowerCase().includes(filter) ||
|
||||||
@@ -402,42 +400,38 @@
|
|||||||
|
|
||||||
let finalRenderList = [];
|
let finalRenderList = [];
|
||||||
|
|
||||||
if (viewMode === 'tree') {
|
const map = {};
|
||||||
const map = {};
|
const roots = [];
|
||||||
const roots = [];
|
filtered.forEach(r => { map[r.id] = { ...r, children: [] }; });
|
||||||
filtered.forEach(r => { map[r.id] = { ...r, children: [] }; });
|
|
||||||
|
filtered.forEach(r => {
|
||||||
filtered.forEach(r => {
|
const node = map[r.id];
|
||||||
const node = map[r.id];
|
if (node.parentId && map[node.parentId]) {
|
||||||
if (node.parentId && map[node.parentId]) {
|
map[node.parentId].children.push(node);
|
||||||
map[node.parentId].children.push(node);
|
} else {
|
||||||
} else {
|
roots.push(node);
|
||||||
roots.push(node);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
const flatten = (nodes, depth) => {
|
||||||
const flatten = (nodes, depth) => {
|
nodes.forEach(n => {
|
||||||
nodes.forEach(n => {
|
let indentHtml = '';
|
||||||
let indentHtml = '';
|
for(let i = 0; i < depth; i++) {
|
||||||
for(let i = 0; i < depth; i++) {
|
indentHtml += '<span style="display:inline-block; width: 1.5rem;"></span>';
|
||||||
indentHtml += '<span style="display:inline-block; width: 1.5rem;"></span>';
|
}
|
||||||
}
|
if (depth > 0) {
|
||||||
if (depth > 0) {
|
indentHtml += '<i class="fa-solid fa-turn-up fa-rotate-90 text-muted me-2"></i>';
|
||||||
indentHtml += '<i class="fa-solid fa-turn-up fa-rotate-90 text-muted me-2"></i>';
|
}
|
||||||
}
|
n.indentHtml = indentHtml;
|
||||||
n.indentHtml = indentHtml;
|
finalRenderList.push(n);
|
||||||
finalRenderList.push(n);
|
if (n.children.length > 0) {
|
||||||
if (n.children.length > 0) {
|
flatten(n.children, depth + 1);
|
||||||
flatten(n.children, depth + 1);
|
}
|
||||||
}
|
});
|
||||||
});
|
};
|
||||||
};
|
|
||||||
|
flatten(roots, 0);
|
||||||
flatten(roots, 0);
|
|
||||||
} else {
|
|
||||||
finalRenderList = filtered.map(r => ({ ...r, indentHtml: '' }));
|
|
||||||
}
|
|
||||||
|
|
||||||
$.scope.resources.empty();
|
$.scope.resources.empty();
|
||||||
for (const r of finalRenderList) {
|
for (const r of finalRenderList) {
|
||||||
$.scope.resources.push(r);
|
$.scope.resources.push(r);
|
||||||
|
|||||||
Reference in New Issue
Block a user