import { html, PageHeader, Empty, Card, ConfirmDelete, Table, renderGuard, esc, enc, $val, apiFetch, toast, definePage, getModel, MonoText, QuickModal } from '/static/hoover/index.js'; const addRule = QuickModal({ title: 'Add Rich Rule', fields: (d) => [ { label: 'Zone', id: 'rule-zone', tag: 'select', options: d.zones }, { label: 'Rule (XML)', id: 'rule-text', tag: 'textarea', placeholder: 'rule family="ipv4" source address="192.168.1.0/24" accept' }, ], submit: { url: '/api/firewall/rich-rules', body: () => ({ zone: $val('rule-zone'), rule: ($val('rule-text') || '').trim() }), validate: (b) => !b.zone || !b.rule ? 'Zone and rule are required' : null, successMsg: 'Rule added', }, }); export default definePage({ init() { return { firewall: getModel('firewall'), }; }, render(state) { const guard = renderGuard(state.firewall, 'Rules', 'Firewall rich rules', state.firewall.data?.config); if (guard) return guard; const cfg = state.firewall.data?.config || {}; const zones = Object.keys(state.firewall.data?.zones || {}); const zoneData = cfg.zones || {}; const zoneRules = {}; Object.entries(zoneData).forEach(([zname, zcfg]) => { const rr = zcfg.rich_rules || []; if (rr.length) zoneRules[zname] = rr; }); const cards = Object.entries(zoneRules).map(([zone, 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); return html`