ui: amber pending-edit markers for unapplied config changes
Add hoover/dirty.js: line-matching helpers that flag UI rows/cards edited (saved to config) but not yet applied, consuming the pending state the daemon already streams — status.pending_diff for hash subsystems, firewall pending zone+type for firewalld. Visual language is amber (.config-dirty + PendingDot), distinct from the red .pending-delete; orphanInfo surfaces removed entries (e.g. WireGuard peers) on their container table. Wired into the backends, dhcp, interfaces, nat, proxy, rules, wireguard, and zones pages; Card and Table gain cls/title props. Covered by 27 node tests (tests/test-dirty.js).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { html, PageHeader, Badge, StatusDot, Card, Table, renderGuard, enc, $val, apiFetch, toast, definePage, getModel, ActionButton, DataTableSection, SectionTitle, ActionGroup, QuickModal, ConfirmDelete } from '/static/hoover/index.js';
|
||||
import { html, PageHeader, Badge, StatusDot, Card, Table, renderGuard, enc, $val, apiFetch, toast, definePage, getModel, ActionButton, DataTableSection, SectionTitle, ActionGroup, QuickModal, ConfirmDelete, PendingDot, fwDirty, fwInfo } from '/static/hoover/index.js';
|
||||
|
||||
const addFwd = QuickModal({
|
||||
title: 'Add Port Forward',
|
||||
@@ -33,6 +33,7 @@ export default definePage({
|
||||
const guard = renderGuard(state.firewall, 'NAT', 'Masquerade & port forwarding', state.firewall.data?.config);
|
||||
if (guard) return guard;
|
||||
|
||||
const fw = fwDirty(state.firewall.data?.pending);
|
||||
const cfg = state.firewall.data?.config || {};
|
||||
const zoneData = cfg.zones || {};
|
||||
|
||||
@@ -82,8 +83,9 @@ export default definePage({
|
||||
<td><span class="text-muted">${anyNonPublicMasq ? 'Propagated from other zones' : 'Not needed'}</span></td>
|
||||
</tr>`;
|
||||
}
|
||||
return html`<tr key=${'m-' + zone}>
|
||||
<td><strong>${zone}</strong></td>
|
||||
const info = fwInfo(fw, zone, 'masquerade');
|
||||
return html`<tr key=${'m-' + zone} class=${info.class || undefined} title=${info.title || undefined}>
|
||||
<td>${info.dirty ? PendingDot({}) : ''}<strong>${zone}</strong></td>
|
||||
<td><${Badge} text=${masq ? 'Enabled' : 'Disabled'} variant=${masq ? 'success' : 'info'} /></td>
|
||||
<td>
|
||||
<${ActionButton}
|
||||
@@ -102,8 +104,9 @@ export default definePage({
|
||||
forwards.forEach((fwd, i) => {
|
||||
const port = fwd.port;
|
||||
const proto = fwd['proxy-protocol'] || fwd.proto;
|
||||
fwRows.push(html`<tr key=${'f-' + zone + '-' + i}>
|
||||
<td><strong>${zone}</strong></td>
|
||||
const info = fwInfo(fw, zone, 'forward_ports');
|
||||
fwRows.push(html`<tr key=${'f-' + zone + '-' + i} class=${info.class || undefined} title=${info.title || undefined}>
|
||||
<td>${info.dirty ? PendingDot({}) : ''}<strong>${zone}</strong></td>
|
||||
<td><${Badge} text=${proto || 'tcp'} variant="info" /></td>
|
||||
<td>${port}</td>
|
||||
<td>${fwd['to-addr'] || fwd.toaddr || '-'}</td>
|
||||
|
||||
Reference in New Issue
Block a user