Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions public/css/aurora.css
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,18 @@ a{color:inherit}
.data-table .mono{font-family:var(--font-mono); font-size:12.5px; color:var(--muted)}
.data-table .cell-name{font-weight:600}
/* Routes table — service/domain group header rows (related routes read as a unit) */
.data-table tr.aurora-group-row{cursor:pointer; user-select:none}
.data-table tr.aurora-group-row td{background:var(--surface-2); padding:9px 14px; border-bottom:1px solid var(--line)}
.data-table tr.aurora-group-row:hover td{background:var(--surface-2)}
.data-table tr.aurora-group-row:hover td{background:var(--surface-3)}
.data-table tr.aurora-group-row .group-status-dot{display:inline-block; vertical-align:middle}
.aurora-group-label{font-weight:700; font-size:12.5px; color:var(--text); margin-left:9px; vertical-align:middle}
.aurora-group-chevron{vertical-align:middle; margin-right:5px; color:var(--muted); transition:transform .2s ease}
.data-table tr.aurora-group-row.collapsed .aurora-group-chevron{transform:rotate(-90deg)}
.aurora-group-label{font-weight:700; font-size:12.5px; color:var(--text); margin-left:5px; vertical-align:middle}
.aurora-group-count{margin-left:10px; font-size:11px; color:var(--faint); font-family:var(--font-mono); vertical-align:middle}
.aurora-group-badge{margin-left:8px; vertical-align:middle; font-size:10.5px; padding:1px 7px}
/* "Collapse all" toolbar toggle */
#aurora-collapse-all{color:var(--muted)}
#aurora-collapse-all:hover{color:var(--text)}
.row-actions{display:flex; gap:6px; justify-content:flex-end}
.icon-action{width:30px;height:30px;border-radius:8px;border:1px solid var(--line);background:var(--chip);color:var(--muted);
display:grid;place-items:center;cursor:pointer;transition:.15s}
Expand Down
61 changes: 57 additions & 4 deletions public/js/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,39 +495,58 @@
+ '</div></td></tr>';
}

// Chevron for collapsible Aurora group headers (rotates via CSS .collapsed).
var AURORA_GROUP_CHEVRON = '<svg class="aurora-group-chevron" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>';

// Aurora group-header row: shown for every multi-route group (service
// bundle or shared domain) so related routes read as a unit, not just a
// hinted-at indent. Mirrors the default theme's .routes-table-group row.
// hinted-at indent. Collapsible — clicking the row toggles its members via
// the shared [data-gtoggle] handler + collapsedGroups set (same persisted
// localStorage state the default/pro card view uses). Mirrors the default
// theme's .routes-table-group row.
function auroraRenderGroupHead(g) {
var t = GC.t;
var collapsed = collapsedGroups.has(g.key);
var label = g.label != null
? escapeHtml(g.label)
: escapeHtml(t['routes.group_no_domain'] || 'Without domain');
var bundleTag = g.isBundle
? '<span class="tag tag-blue aurora-group-badge">' + escapeHtml(t['service_bundle.badge'] || 'SERVICE') + '</span>'
: '';
var countTxt = (t['routes.group_count'] || '{{count}} routes').replace('{{count}}', g.routes.length);
return '<tr class="aurora-group-row" data-gkey="' + escapeHtml(g.key) + '"><td colspan="6">'
return '<tr class="aurora-group-row' + (collapsed ? ' collapsed' : '') + '" data-gtoggle="' + escapeHtml(g.key) + '" aria-expanded="' + (collapsed ? 'false' : 'true') + '"><td colspan="6">'
+ AURORA_GROUP_CHEVRON
+ '<span class="group-status-dot ' + statusDotClass(g.status) + '"></span>'
+ '<span class="aurora-group-label">' + label + '</span>'
+ bundleTag
+ '<span class="aurora-group-count">' + escapeHtml(countTxt) + '</span>'
+ '</td></tr>';
}

// Keys of the multi-route groups in the last Aurora render — drives the
// toolbar "collapse/expand all" toggle. Updated by auroraRenderTable().
var auroraGroupKeys = [];

function auroraRenderTable(groups) {
var t = GC.t;
var rows = '';
auroraGroupKeys = [];
// Aurora: group-headed table (no batch column). Multi-route groups get a
// header row + indented sub-rows; standalone routes render bare.
// collapsible header row + indented sub-rows; collapsed groups hide their
// members. Standalone routes render bare.
for (var gi = 0; gi < groups.length; gi++) {
var g = groups[gi];
var grouped = !g.single && g.routes.length > 1;
if (grouped) rows += auroraRenderGroupHead(g);
if (grouped) {
auroraGroupKeys.push(g.key);
rows += auroraRenderGroupHead(g);
if (collapsedGroups.has(g.key)) continue; // collapsed → members hidden
}
for (var ri = 0; ri < g.routes.length; ri++) {
rows += auroraRenderTableRow(g.routes[ri], { subRow: grouped && ri > 0 });
}
}
auroraUpdateCollapseAll();
if (!rows) {
return '<div style="font-size:13px;color:var(--faint);padding:20px 0;text-align:center">'
+ escapeHtml(t['routes.no_routes'] || 'No routes configured') + '</div>';
Expand Down Expand Up @@ -556,6 +575,39 @@
});
}

// Reflects the "collapse all / expand all" toolbar button: hidden when no
// multi-route groups exist, otherwise labelled by what the click will do.
function auroraUpdateCollapseAll() {
var btn = document.getElementById('aurora-collapse-all');
if (!btn) return;
if (!auroraGroupKeys.length) { btn.style.display = 'none'; return; }
btn.style.display = '';
var allCollapsed = auroraGroupKeys.every(function (k) { return collapsedGroups.has(k); });
var lbl = btn.querySelector('.aurora-collapse-all-lbl');
if (lbl) {
lbl.textContent = allCollapsed
? (GC.t['routes.expand_all'] || 'Expand all')
: (GC.t['routes.collapse_all'] || 'Collapse all');
}
btn.classList.toggle('all-collapsed', allCollapsed);
}

function auroraInitCollapseAll() {
var btn = document.getElementById('aurora-collapse-all');
if (!btn) return;
btn.addEventListener('click', function () {
var allCollapsed = auroraGroupKeys.length > 0
&& auroraGroupKeys.every(function (k) { return collapsedGroups.has(k); });
// All collapsed → expand all; otherwise collapse all.
auroraGroupKeys.forEach(function (k) {
if (allCollapsed) collapsedGroups.delete(k);
else collapsedGroups.add(k);
});
lsSetSet('gc_routes_groups_collapsed_v1', collapsedGroups);
render();
});
}

function renderTableRow(r, opts) {
if (isAurora()) return auroraRenderTableRow(r, opts);
opts = opts || {};
Expand Down Expand Up @@ -4028,6 +4080,7 @@

// Aurora-only: wire the type toggle-group in the Aurora toolbar
if (isAurora()) auroraInitTypeToggle();
if (isAurora()) auroraInitCollapseAll();

// ─── Init ────────────────────────────────────────────────
loadRoutes();
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@
"routes.view_table": "Tabellenansicht",
"routes.group_no_domain": "Ohne Domain",
"routes.group_count": "{{count}} Routen",
"routes.collapse_all": "Alle einklappen",
"routes.expand_all": "Alle ausklappen",
"routes.no_match": "Keine Routen entsprechen dem Filter",
"routes.table_domain": "Domain",
"routes.table_type": "Typ",
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@
"routes.view_table": "Table view",
"routes.group_no_domain": "Without domain",
"routes.group_count": "{{count}} routes",
"routes.collapse_all": "Collapse all",
"routes.expand_all": "Expand all",
"routes.no_match": "No routes match the filter",
"routes.table_domain": "Domain",
"routes.table_type": "Type",
Expand Down
5 changes: 5 additions & 0 deletions templates/aurora/pages/routes.njk
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<button type="button" class="toggle-btn" data-value="l4">{{ t('routes.type_l4') }}</button>
<button type="button" class="toggle-btn" data-nav="/rdp">{{ t('nav.rdp') }}</button>
</span>
{# Collapse/expand all route groups — JS shows it only when multi-route groups exist #}
<button type="button" class="btn btn-ghost btn-sm" id="aurora-collapse-all" style="margin-left:auto;display:none">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" width="14" height="14"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" y1="10" x2="21" y2="3"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
<span class="aurora-collapse-all-lbl">{{ t('routes.collapse_all') }}</span>
</button>
</div>

<!-- Routes list card: full-width Aurora .data-table shell, populated by auroraRenderTable() -->
Expand Down
Loading