Update status checks and add optgroup support to form modals
- modal.js: add optgroup support for select options in formModal - dhcp.js: use zone-based interface selector for DHCP ranges - dashboard.js, wireguard.js: use status.up for state checks - proxy.js: use inner.querySelector for modal field lookup
This commit is contained in:
+40
-25
@@ -1,26 +1,40 @@
|
||||
import { html, PageHeader, Badge, ConfirmDelete, Tabs, Table, ServiceStatus, renderGuard, esc, enc, $val, apiFetch, toast, definePage, getModel, modelFetch, ActionButton, ActionGroup, QuickModal } from '/static/hoover/index.js?v=7';
|
||||
import { html, PageHeader, ConfirmDelete, Tabs, Table, ServiceStatus, renderGuardMulti, esc, enc, $val, apiFetch, toast, definePage, getModel, ActionButton, ActionGroup, QuickModal } from '/static/hoover/index.js?v=7';
|
||||
|
||||
const addRange = QuickModal({
|
||||
title: 'Add DHCP Range',
|
||||
fields: [
|
||||
{ label: 'Interface (optional)', id: 'r-iface', placeholder: 'Leave empty for global' },
|
||||
{ label: 'Start IP', id: 'r-start', placeholder: '192.168.1.100' },
|
||||
{ label: 'End IP', id: 'r-end', placeholder: '192.168.1.200' },
|
||||
{ label: 'Lease Time', id: 'r-lease', placeholder: '12h' },
|
||||
],
|
||||
submit: {
|
||||
url: '/api/dhcp/ranges',
|
||||
body: () => ({
|
||||
interface: ($val('r-iface') || '').trim() || undefined,
|
||||
start: ($val('r-start') || '').trim(),
|
||||
end: ($val('r-end') || '').trim(),
|
||||
lease_time: ($val('r-lease') || '').trim() || '12h',
|
||||
}),
|
||||
validate: (b) => !b.start || !b.end ? 'Start and end are required' : null,
|
||||
successMsg: 'Range added',
|
||||
},
|
||||
refresh: 'dnsmasq',
|
||||
});
|
||||
function makeAddRange(activeZones) {
|
||||
const opts = [
|
||||
['', '(global)'],
|
||||
...Object.entries(activeZones || {})
|
||||
.filter(([, ifaces]) => Array.isArray(ifaces) && ifaces.length > 0)
|
||||
.flatMap(([zone, ifaces]) => {
|
||||
const label = zone + ' \u2192 ';
|
||||
if (ifaces.length === 1)
|
||||
return [[ifaces[0], label + ifaces[0]]];
|
||||
return [{ group: zone, options: ifaces.map(i => [i, label + i]) }];
|
||||
}),
|
||||
];
|
||||
|
||||
return QuickModal({
|
||||
title: 'Add DHCP Range',
|
||||
fields: [
|
||||
{ label: 'Interface (optional)', id: 'r-iface', tag: 'select', options: opts },
|
||||
{ label: 'Start IP', id: 'r-start', placeholder: '192.168.1.100' },
|
||||
{ label: 'End IP', id: 'r-end', placeholder: '192.168.1.200' },
|
||||
{ label: 'Lease Time', id: 'r-lease', placeholder: '12h' },
|
||||
],
|
||||
submit: {
|
||||
url: '/api/dhcp/ranges',
|
||||
body: () => ({
|
||||
interface: ($val('r-iface') || '').trim() || undefined,
|
||||
start: ($val('r-start') || '').trim(),
|
||||
end: ($val('r-end') || '').trim(),
|
||||
lease_time: ($val('r-lease') || '').trim() || '12h',
|
||||
}),
|
||||
validate: (b) => !b.start || !b.end ? 'Start and end are required' : null,
|
||||
successMsg: 'Range added',
|
||||
},
|
||||
refresh: 'dnsmasq',
|
||||
});
|
||||
}
|
||||
|
||||
const addLease = QuickModal({
|
||||
title: 'Add Static Lease',
|
||||
@@ -61,11 +75,12 @@ export default definePage({
|
||||
init() {
|
||||
return {
|
||||
dnsmasq: getModel('dnsmasq'),
|
||||
firewall: getModel('firewall'),
|
||||
activeTab: 'ranges',
|
||||
};
|
||||
},
|
||||
render(state) {
|
||||
const guard = renderGuard(state.dnsmasq, 'DHCP & DNS', 'Dnsmasq management', state.dnsmasq.data);
|
||||
const guard = renderGuardMulti('DHCP & DNS', 'Dnsmasq management', state.dnsmasq, state.firewall);
|
||||
if (guard) return guard;
|
||||
|
||||
const cfg = state.dnsmasq.data?.config || {};
|
||||
@@ -116,7 +131,7 @@ export default definePage({
|
||||
|
||||
const tabNames = ['ranges', 'leases', 'dns', 'active'];
|
||||
const actions = ActionGroup(
|
||||
html`<button class="btn btn-primary" onClick=${() => addRange(state)}>Add Range</button>`,
|
||||
html`<button class="btn btn-primary" onClick=${() => makeAddRange(state.firewall.data?.zones?.active)(state)}>Add Range</button>`,
|
||||
html`<button class="btn btn-outline" onClick=${() => addLease(state)}>Static Lease</button>`,
|
||||
html`<button class="btn btn-outline" onClick=${() => addDns(state)}>DNS Record</button>`,
|
||||
ActionButton({
|
||||
@@ -141,7 +156,7 @@ export default definePage({
|
||||
|
||||
return [
|
||||
PageHeader({ title: 'DHCP & DNS', subtitle: 'Dnsmasq management', actions }),
|
||||
ServiceStatus({ state: status.state || 'down', label: 'Dnsmasq' }),
|
||||
ServiceStatus({ state: status.service_active ? 'up' : 'down', label: 'Dnsmasq' }),
|
||||
Tabs({ state, tabs: tabNames }),
|
||||
state.activeTab === 'ranges'
|
||||
? Table({ columns: ['Interface', 'Start', 'End', 'Lease', 'Action'], rows: rangesRows, emptyText: 'No DHCP ranges' }) : null,
|
||||
|
||||
Reference in New Issue
Block a user