mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
webui: surface confd inference in the advanced tree editor
confd infers Infix-suggested values (DHCP option lists, related leaves, normalised values) into the candidate when a change is written, but the tree editor's write handlers only wrote — SaveLeaf echoed the typed value back, SaveGroup returned 204 — so the inferred values never appeared until a manual page reload. After a save (cfgSaved) re-fetch the current tree page from the now up-to-date candidate and re-render it, so inference surfaces wherever it landed on the page. SaveLeaf now emits cfgSaved + 204 like SaveGroup (its form uses hx-swap="none") instead of echoing the raw input. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -1227,17 +1227,17 @@ func (h *TreeHandler) SaveLeaf(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
body := map[string]any{qualName: coerceLeafValue(rawValue, node)}
|
||||
data := &nodeDetailData{Node: node}
|
||||
|
||||
// Emit cfgSaved/cfgError like SaveGroup and let the client re-fetch the
|
||||
// whole current page from the fresh candidate (so confd inference and
|
||||
// normalisation surface) — don't echo the raw input back, which hid it.
|
||||
if putErr := h.RC.Put(r.Context(), candidateDS+path, body); putErr != nil {
|
||||
data.Error = putErr.Error()
|
||||
data.CurrentValue = rawValue
|
||||
} else {
|
||||
data.SavedOK = true
|
||||
data.CurrentValue = rawValue
|
||||
w.Header().Set("HX-Trigger", `{"cfgError":"`+node.Name+": "+putErr.Error()+`"}`)
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
h.FragTmpl.ExecuteTemplate(w, "yang-node-detail", data)
|
||||
w.Header().Set("HX-Trigger", `{"cfgSaved":"Saved `+node.Name+` to candidate"}`)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DeleteLeaf serves DELETE /configure/tree/node?path=...
|
||||
|
||||
@@ -2121,6 +2121,22 @@ function renderCfgLog() {
|
||||
span.classList.remove('saved');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Re-render the whole current tree page from the (now fresh) candidate.
|
||||
// The save handlers only WRITE — they don't echo back what confd
|
||||
// inferred from the change (DHCP option lists, related leaves,
|
||||
// normalised values), and inference can land outside the edited node.
|
||||
// Re-fetching the page the user is on surfaces all of it. Guarded on
|
||||
// #yang-detail so curated pages that also emit cfgSaved are unaffected.
|
||||
var detail = document.getElementById('yang-detail');
|
||||
if (detail && window.htmx) {
|
||||
var node = (history.state && history.state.yangDetailPath) ||
|
||||
new URLSearchParams(window.location.search).get('node');
|
||||
if (node) {
|
||||
htmx.ajax('GET', '/configure/tree/node?path=' + encodeURIComponent(node),
|
||||
{ target: '#yang-detail', swap: 'innerHTML' });
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
|
||||
{{/* ── Edit form — only for writable leaves in non-ReadOnly mode ── */}}
|
||||
{{if and (not .ReadOnly) .Config (or (eq .Kind "leaf") (eq .Kind "leaf-list"))}}
|
||||
{{/* hx-swap="none": SaveLeaf returns 204 + a cfgSaved trigger, and the
|
||||
cfgSaved handler re-fetches the whole current tree page from the
|
||||
fresh candidate so confd-inferred values surface. */}}
|
||||
<form class="yt-edit-form"
|
||||
hx-put="/configure/tree/node?path={{.Path | urlquery}}"
|
||||
hx-target="#yang-detail"
|
||||
hx-swap="innerHTML">
|
||||
hx-swap="none">
|
||||
<div class="cfg-card-footer">
|
||||
<label class="yt-value-label">
|
||||
{{if .UsingDefault -}}
|
||||
|
||||
Reference in New Issue
Block a user