diff --git a/public/css/aurora.css b/public/css/aurora.css index 8aa9c6b2..841cd4ee 100644 --- a/public/css/aurora.css +++ b/public/css/aurora.css @@ -301,6 +301,10 @@ a{color:inherit} /* "Collapse all" toolbar toggle */ #aurora-collapse-all{color:var(--muted)} #aurora-collapse-all:hover{color:var(--text)} +/* Batch-select checkbox column (shown only in batch mode) */ +.data-table .td-batch{width:34px; text-align:center; padding-right:0} +.data-table .batch-checkbox{width:16px; height:16px; accent-color:var(--teal); cursor:pointer; vertical-align:middle} +.data-table.batch-mode tbody tr[data-route-id]{cursor:pointer} /* Grouped member rows — nested under their group header via indent + a left rail, so they're clearly set off from standalone routes (which sit flush). */ .data-table tr.aurora-route-sub td.cell-name{position:relative; padding-left:34px; color:var(--muted)} diff --git a/public/js/routes.js b/public/js/routes.js index b31a48d9..60b581d5 100644 --- a/public/js/routes.js +++ b/public/js/routes.js @@ -479,8 +479,13 @@ var delDomain = r.domain ? escapeHtml(r.domain) : ((r.l4_protocol === 'udp' ? 'UDP' : 'TCP') + ' :' + (r.l4_listen_port || '')); + // Batch-select checkbox (first column) — only while batch mode is active. + var batchCell = batchMode + ? '' + : ''; var rowCls = opts.grouped ? ' class="aurora-route-sub"' : ''; return '' + + batchCell + '' + domainTxt + '' + '' + typeTag + '' + '' + escapeHtml(targetTxt) + '' @@ -515,7 +520,7 @@ ? '' + escapeHtml(t['service_bundle.badge'] || 'SERVICE') + '' : ''; var countTxt = (t['routes.group_count'] || '{{count}} routes').replace('{{count}}', g.routes.length); - return '' + return '' + AURORA_GROUP_CHEVRON + '' + '' + label + '' @@ -532,9 +537,9 @@ var t = GC.t; var rows = ''; auroraGroupKeys = []; - // Aurora: group-headed table (no batch column). Multi-route groups get a - // collapsible header row + indented sub-rows; collapsed groups hide their - // members. Standalone routes render bare. + // Aurora: group-headed table. Multi-route groups get a collapsible header + // row + indented sub-rows; collapsed groups hide their members. Standalone + // routes render bare. A batch-select checkbox column is prepended in batch mode. for (var gi = 0; gi < groups.length; gi++) { var g = groups[gi]; var grouped = !g.single && g.routes.length > 1; @@ -552,7 +557,8 @@ return '
' + escapeHtml(t['routes.no_routes'] || 'No routes configured') + '
'; } - return '' + return '
' + + (batchMode ? '' : '') + '' + '' + '' diff --git a/templates/aurora/layout.njk b/templates/aurora/layout.njk index ae9ba825..0412bbeb 100644 --- a/templates/aurora/layout.njk +++ b/templates/aurora/layout.njk @@ -66,6 +66,12 @@ 'routes.group_no_domain': {{ t('routes.group_no_domain') | dump | safe }}, 'routes.group_count': {{ t('routes.group_count') | dump | safe }}, 'routes.no_match': {{ t('routes.no_match') | dump | safe }}, + 'batch.selected': {{ t('batch.selected') | dump | safe }}, + 'batch.none_selected': {{ t('batch.none_selected') | dump | safe }}, + 'batch.enable': {{ t('batch.enable') | dump | safe }}, + 'batch.disable': {{ t('batch.disable') | dump | safe }}, + 'batch.delete': {{ t('batch.delete') | dump | safe }}, + 'batch.confirm_delete_routes': {{ t('batch.confirm_delete_routes') | dump | safe }}, 'routes.table_domain': {{ t('routes.table_domain') | dump | safe }}, 'routes.table_type': {{ t('routes.table_type') | dump | safe }}, 'routes.table_target': {{ t('routes.table_target') | dump | safe }}, diff --git a/templates/aurora/pages/routes.njk b/templates/aurora/pages/routes.njk index 36e105e3..8ba7691f 100644 --- a/templates/aurora/pages/routes.njk +++ b/templates/aurora/pages/routes.njk @@ -12,6 +12,10 @@ {# routes-count: hidden but present for JS contract (JS writes textContent) #}
+
' + escapeHtml(t['routes.table_domain'] || 'Domain') + '' + escapeHtml(t['routes.table_type'] || 'Type') + '' + escapeHtml(t['routes.table_target'] || 'Target') + '