refactor: modernize frontend with hoover framework components and docs
- Add quick modal, table, service status, and confirmation dialog components - Refactor all pages (certs, dhcp, proxy, etc.) to use new component patterns - Introduce refactor load utility and render guard for consistent UX - Add hoover documentation and update AGENTS.md, architecture, overview
This commit is contained in:
@@ -16,9 +16,9 @@
|
||||
* });
|
||||
*/
|
||||
|
||||
import { reactive } from './reactivity.js';
|
||||
import { h } from './vdom.js';
|
||||
import { _compExpandedCache } from './render.js';
|
||||
import { reactive } from './reactivity.js?v=6';
|
||||
import { h } from './vdom.js?v=6';
|
||||
import { _compExpandedCache } from './render.js?v=6';
|
||||
|
||||
/** Registry of mounted components: key → { state, subscriptions, loadAbort, entry, isLoading } */
|
||||
const _mounted = new Map();
|
||||
@@ -32,6 +32,15 @@ export function isComponentStateMounted(state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Get the full mounted entry for a state object.
|
||||
* Used by websocket.js to abort in-flight loads before triggering a refresh. */
|
||||
export function getComponentEntry(state) {
|
||||
for (const entry of _mounted.values()) {
|
||||
if (entry.state === state) return entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** External subscribe function from websocket.js.
|
||||
* Set via setSubscribeFn() when the websocket module initializes.
|
||||
*/
|
||||
@@ -79,12 +88,11 @@ export function mountComponent(key, renderer) {
|
||||
let entry = _mounted.get(key);
|
||||
|
||||
if (entry) {
|
||||
// Re-mount of an already-mounted page: restart load with fresh AbortController
|
||||
if (entry.loadAbort) {
|
||||
entry.loadAbort.abort();
|
||||
}
|
||||
entry.requestId++;
|
||||
entry.loadAbort = null;
|
||||
// Re-mount: component already exists with its data and subscriptions.
|
||||
// Don't abort or restart loads — that re-render was triggered by a
|
||||
// state change (load completion, reactive update, etc). Let existing
|
||||
// in-flight loads complete naturally. WS handles auto-refresh.
|
||||
return;
|
||||
} else {
|
||||
// Fresh mount
|
||||
entry = {
|
||||
@@ -101,6 +109,7 @@ export function mountComponent(key, renderer) {
|
||||
|
||||
// Fire load with fresh AbortController
|
||||
if (pd.load) {
|
||||
if (entry.isLoading) return;
|
||||
const abortController = new AbortController();
|
||||
entry.loadAbort = abortController;
|
||||
entry.requestId++;
|
||||
|
||||
Reference in New Issue
Block a user