chore: frontend cleanup — replaceChildren, missing source badge, http case
- Replace innerHTML = '' with replaceChildren() throughout tabs.js and app.js (12 + 7 sites). paintAtomic already used replaceChildren; now the direct-clear sites are consistent with it. - Add missing .rqe-source-startup_sweep CSS rule (startup_sweep is a valid QueueSource variant but had no badge style, falling through to the base muted appearance with no explicit intent). - Lowercase the one uppercase 'HTTP ' in the fetchAndRenderToolGroups error path to match every other fetch error in the file.
This commit is contained in:
parent
5c5ca38fe8
commit
2a62a561c4
3 changed files with 21 additions and 20 deletions
|
|
@ -549,7 +549,7 @@ window.marked = marked;
|
||||||
const slot = $('term-input');
|
const slot = $('term-input');
|
||||||
if (!slot) return;
|
if (!slot) return;
|
||||||
if (!termInputRendered) {
|
if (!termInputRendered) {
|
||||||
slot.innerHTML = '';
|
slot.replaceChildren();
|
||||||
const form = el('form', {
|
const form = el('form', {
|
||||||
action: 'send', method: 'POST',
|
action: 'send', method: 'POST',
|
||||||
class: 'sendform-term', 'data-async': '',
|
class: 'sendform-term', 'data-async': '',
|
||||||
|
|
@ -790,7 +790,7 @@ window.marked = marked;
|
||||||
if (slot._boundId) {
|
if (slot._boundId) {
|
||||||
const stillPending = pending.some((q) => q.id === slot._boundId);
|
const stillPending = pending.some((q) => q.id === slot._boundId);
|
||||||
if (!stillPending && !slot._resolvedShown) {
|
if (!stillPending && !slot._resolvedShown) {
|
||||||
slot.innerHTML = '';
|
slot.replaceChildren();
|
||||||
slot.appendChild(el('span', { class: 'ask-resolved-tag' }, '[resolved]'));
|
slot.appendChild(el('span', { class: 'ask-resolved-tag' }, '[resolved]'));
|
||||||
slot._resolvedShown = true;
|
slot._resolvedShown = true;
|
||||||
}
|
}
|
||||||
|
|
@ -800,7 +800,7 @@ window.marked = marked;
|
||||||
if (!q) continue;
|
if (!q) continue;
|
||||||
claimed.add(q.id);
|
claimed.add(q.id);
|
||||||
slot._boundId = q.id;
|
slot._boundId = q.id;
|
||||||
slot.innerHTML = '';
|
slot.replaceChildren();
|
||||||
slot.appendChild(buildAnswerForm(q.id));
|
slot.appendChild(buildAnswerForm(q.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1110,7 +1110,7 @@ window.marked = marked;
|
||||||
(s.status === 'needs_login_in_progress' && outLen !== lastOutputLen);
|
(s.status === 'needs_login_in_progress' && outLen !== lastOutputLen);
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
const root = $('status');
|
const root = $('status');
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
if (s.status === 'online') renderOnline(s.label, root);
|
if (s.status === 'online') renderOnline(s.label, root);
|
||||||
else if (s.status === 'needs_login_idle') renderNeedsLoginIdle(root);
|
else if (s.status === 'needs_login_idle') renderNeedsLoginIdle(root);
|
||||||
else if (s.status === 'needs_login_in_progress') renderLoginInProgress(s.session || {}, root);
|
else if (s.status === 'needs_login_in_progress') renderLoginInProgress(s.session || {}, root);
|
||||||
|
|
@ -1139,7 +1139,7 @@ window.marked = marked;
|
||||||
(function() {
|
(function() {
|
||||||
const log = $('live');
|
const log = $('live');
|
||||||
if (!log || !window.HiveTerminal) return;
|
if (!log || !window.HiveTerminal) return;
|
||||||
log.innerHTML = '';
|
log.replaceChildren();
|
||||||
|
|
||||||
function trim(s, n) { return s.length > n ? s.slice(0, n) + '…' : s; }
|
function trim(s, n) { return s.length > n ? s.slice(0, n) + '…' : s; }
|
||||||
// Render a message body as markdown into a new <div class="md">.
|
// Render a message body as markdown into a new <div class="md">.
|
||||||
|
|
@ -1543,7 +1543,7 @@ window.marked = marked;
|
||||||
// login UI; clear it so the operator sees a clean
|
// login UI; clear it so the operator sees a clean
|
||||||
// online state without a separate refetch.
|
// online state without a separate refetch.
|
||||||
const root = $('status');
|
const root = $('status');
|
||||||
if (root) root.innerHTML = '';
|
if (root) root.replaceChildren();
|
||||||
lastStatus = 'online';
|
lastStatus = 'online';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1566,7 +1566,7 @@ window.marked = marked;
|
||||||
// Expose the panel API for slash commands (`/help`, `/clear`).
|
// Expose the panel API for slash commands (`/help`, `/clear`).
|
||||||
termAPI = {
|
termAPI = {
|
||||||
row: (cls, text) => term.row(cls, text),
|
row: (cls, text) => term.row(cls, text),
|
||||||
clear: () => { log.innerHTML = ''; },
|
clear: () => { log.replaceChildren(); },
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1096,6 +1096,7 @@ code {
|
||||||
.rqe-source-manual { color: var(--cyan); border-color: var(--cyan); }
|
.rqe-source-manual { color: var(--cyan); border-color: var(--cyan); }
|
||||||
.rqe-source-meta_update { color: var(--purple); border-color: var(--purple); }
|
.rqe-source-meta_update { color: var(--purple); border-color: var(--purple); }
|
||||||
.rqe-source-auto_update { color: var(--muted); }
|
.rqe-source-auto_update { color: var(--muted); }
|
||||||
|
.rqe-source-startup_sweep { color: var(--muted); }
|
||||||
.rqe-source-crash_recover { color: var(--amber); border-color: var(--amber); }
|
.rqe-source-crash_recover { color: var(--amber); border-color: var(--amber); }
|
||||||
.rqe-source-approval { color: var(--green); border-color: var(--green); }
|
.rqe-source-approval { color: var(--green); border-color: var(--green); }
|
||||||
.rqe-when { color: var(--muted); font-size: 0.85em; }
|
.rqe-when { color: var(--muted); font-size: 0.85em; }
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@ window.marked = marked;
|
||||||
// no-op-when-target-absent convention the other renderers
|
// no-op-when-target-absent convention the other renderers
|
||||||
// (renderTombstones, etc.) follow.
|
// (renderTombstones, etc.) follow.
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
|
|
||||||
// Containers come from the derived map (event-driven) rather than
|
// Containers come from the derived map (event-driven) rather than
|
||||||
// `s.containers`; `s` still supplies hostname (for the web-ui
|
// `s.containers`; `s` still supplies hostname (for the web-ui
|
||||||
|
|
@ -883,7 +883,7 @@ window.marked = marked;
|
||||||
// Recompute action availability + tooltips per render. Each
|
// Recompute action availability + tooltips per render. Each
|
||||||
// action declares which agents it CAN'T run on; the bar disables
|
// action declares which agents it CAN'T run on; the bar disables
|
||||||
// the button and surfaces the offending names in the tooltip.
|
// the button and surfaces the offending names in the tooltip.
|
||||||
actions.innerHTML = '';
|
actions.replaceChildren();
|
||||||
const allRunning = selected.every((c) => c.running);
|
const allRunning = selected.every((c) => c.running);
|
||||||
const allStopped = selected.every((c) => !c.running);
|
const allStopped = selected.every((c) => !c.running);
|
||||||
const noManagers = selected.every((c) => !c.is_manager);
|
const noManagers = selected.every((c) => !c.is_manager);
|
||||||
|
|
@ -1114,7 +1114,7 @@ window.marked = marked;
|
||||||
// no-op on /flow.html and any other page that loads the shared
|
// no-op on /flow.html and any other page that loads the shared
|
||||||
// bundle without the dashboard's tab panes.
|
// bundle without the dashboard's tab panes.
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
if (!s.tombstones || !s.tombstones.length) {
|
if (!s.tombstones || !s.tombstones.length) {
|
||||||
root.append(el('p', { class: 'empty' }, 'no kept state — clean'));
|
root.append(el('p', { class: 'empty' }, 'no kept state — clean'));
|
||||||
return;
|
return;
|
||||||
|
|
@ -1181,21 +1181,21 @@ window.marked = marked;
|
||||||
async function fetchAndRenderToolGroups() {
|
async function fetchAndRenderToolGroups() {
|
||||||
const root = $('tool-groups-section');
|
const root = $('tool-groups-section');
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
root.append(el('p', { class: 'meta' }, 'loading…'));
|
root.append(el('p', { class: 'meta' }, 'loading…'));
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/tool-groups');
|
const resp = await fetch('/api/tool-groups');
|
||||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
if (!resp.ok) throw new Error('http ' + resp.status);
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
renderToolGroups(root, data);
|
renderToolGroups(root, data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
root.append(el('p', { class: 'meta' }, 'fetch failed: ' + err));
|
root.append(el('p', { class: 'meta' }, 'fetch failed: ' + err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderToolGroups(root, data) {
|
function renderToolGroups(root, data) {
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
const { groups, assignments } = data;
|
const { groups, assignments } = data;
|
||||||
if (!groups || !groups.length) {
|
if (!groups || !groups.length) {
|
||||||
root.append(el('p', { class: 'meta' }, '(no tool groups defined)'));
|
root.append(el('p', { class: 'meta' }, '(no tool groups defined)'));
|
||||||
|
|
@ -1380,7 +1380,7 @@ window.marked = marked;
|
||||||
// no-op when the section is missing. `question_added` /
|
// no-op when the section is missing. `question_added` /
|
||||||
// `question_resolved` SSE events route through here.
|
// `question_resolved` SSE events route through here.
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
const fmt = (n) => new Date(n * 1000).toISOString().replace('T', ' ').slice(0, 19);
|
const fmt = (n) => new Date(n * 1000).toISOString().replace('T', ' ').slice(0, 19);
|
||||||
const allPending = questionsState.pending;
|
const allPending = questionsState.pending;
|
||||||
const activeFilter = getQuestionsFilter();
|
const activeFilter = getQuestionsFilter();
|
||||||
|
|
@ -1712,7 +1712,7 @@ window.marked = marked;
|
||||||
function renderPeerHives(peers) {
|
function renderPeerHives(peers) {
|
||||||
const root = $('peers-section');
|
const root = $('peers-section');
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
if (!peers || !peers.length) {
|
if (!peers || !peers.length) {
|
||||||
root.append(el('p', { class: 'empty' }, 'no peer hives configured'));
|
root.append(el('p', { class: 'empty' }, 'no peer hives configured'));
|
||||||
return;
|
return;
|
||||||
|
|
@ -1743,7 +1743,7 @@ window.marked = marked;
|
||||||
// no-op elsewhere — `approval_added` / `approval_resolved` SSE
|
// no-op elsewhere — `approval_added` / `approval_resolved` SSE
|
||||||
// events route through here on every page that loads the bundle.
|
// events route through here on every page that loads the bundle.
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
|
|
||||||
// Spawn request form: submitting it queues a Spawn approval that
|
// Spawn request form: submitting it queues a Spawn approval that
|
||||||
// lands in this same list, so the form belongs here rather than on
|
// lands in this same list, so the form belongs here rather than on
|
||||||
|
|
@ -1933,7 +1933,7 @@ window.marked = marked;
|
||||||
function renderMetaInputs(s) {
|
function renderMetaInputs(s) {
|
||||||
const root = $('meta-inputs-section');
|
const root = $('meta-inputs-section');
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
const inputs = s.meta_inputs || [];
|
const inputs = s.meta_inputs || [];
|
||||||
if (!inputs.length) {
|
if (!inputs.length) {
|
||||||
root.append(el('p', { class: 'empty' }, 'meta repo not seeded yet'));
|
root.append(el('p', { class: 'empty' }, 'meta repo not seeded yet'));
|
||||||
|
|
@ -2054,7 +2054,7 @@ window.marked = marked;
|
||||||
function renderRebuildQueue(s) {
|
function renderRebuildQueue(s) {
|
||||||
const root = $('rebuild-queue-section');
|
const root = $('rebuild-queue-section');
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
root.innerHTML = '';
|
root.replaceChildren();
|
||||||
const queue = s.rebuild_queue || [];
|
const queue = s.rebuild_queue || [];
|
||||||
if (!queue.length) {
|
if (!queue.length) {
|
||||||
root.append(el('p', { class: 'empty' }, 'queue is empty — nothing pending or in flight.'));
|
root.append(el('p', { class: 'empty' }, 'queue is empty — nothing pending or in flight.'));
|
||||||
|
|
@ -3578,7 +3578,7 @@ window.marked = marked;
|
||||||
|
|
||||||
// Step 4: rebuild the dropdown from the two overflow sets.
|
// Step 4: rebuild the dropdown from the two overflow sets.
|
||||||
const overflowedTabs = [...dynamicOverflow, ...defaultOverflow];
|
const overflowedTabs = [...dynamicOverflow, ...defaultOverflow];
|
||||||
overflowDrop.innerHTML = '';
|
overflowDrop.replaceChildren();
|
||||||
for (const tab of overflowedTabs) {
|
for (const tab of overflowedTabs) {
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.setAttribute('role', 'presentation');
|
li.setAttribute('role', 'presentation');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue