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, Empty, Card, ConfirmDelete, Table, renderGuard, esc, enc, $val, apiFetch, toast, definePage, getModel, MonoText, QuickModal } from '/static/hoover/index.js';
|
||||
import { h, html, PageHeader, Empty, Card, ConfirmDelete, Table, renderGuard, esc, enc, $val, apiFetch, toast, definePage, getModel, MonoText, QuickModal, PendingDot, fwDirty, fwInfo } from '/static/hoover/index.js';
|
||||
|
||||
const addRule = QuickModal({
|
||||
title: 'Add Rich Rule',
|
||||
@@ -24,6 +24,7 @@ export default definePage({
|
||||
const guard = renderGuard(state.firewall, 'Rules', 'Firewall rich rules', state.firewall.data?.config);
|
||||
if (guard) return guard;
|
||||
|
||||
const fw = fwDirty(state.firewall.data?.pending);
|
||||
const cfg = state.firewall.data?.config || {};
|
||||
const zones = Object.keys(state.firewall.data?.zones || {});
|
||||
const zoneData = cfg.zones || {};
|
||||
@@ -34,6 +35,7 @@ export default definePage({
|
||||
});
|
||||
|
||||
const cards = Object.entries(zoneRules).map(([zone, rules]) => {
|
||||
const info = fwInfo(fw, zone, 'rich_rules');
|
||||
const ruleRows = (Array.isArray(rules) ? rules : []).map((entry, i) => {
|
||||
const ruleId = typeof entry === 'object' ? entry.id : null;
|
||||
const ruleText = typeof entry === 'object' ? (entry.rule || '') : String(entry);
|
||||
@@ -50,8 +52,12 @@ export default definePage({
|
||||
</tr>`;
|
||||
});
|
||||
return Card({
|
||||
header: 'Zone: ' + esc(zone),
|
||||
header: info.dirty
|
||||
? h('span', {}, [PendingDot({}), 'Zone: ' + esc(zone)])
|
||||
: 'Zone: ' + esc(zone),
|
||||
key: zone,
|
||||
cls: info.class || undefined,
|
||||
title: info.title || undefined,
|
||||
children: [Table({
|
||||
columns: ['#', 'Rule', 'Action'],
|
||||
rows: ruleRows,
|
||||
|
||||
Reference in New Issue
Block a user