feat(ui): agent-outdated banner on the NAS settings page (capability gate, Part 3)
- networkStoragePageData threads NetAddSupport (yes/no/unknown) via the short-budget netAddSupport probe (2 s ctx + cache — a down agent cannot stall the page) - storage_network.html: support=no replaces the add form with the Hungarian alert-warning banner; share list + remove render in every state; yes/unknown render the form unchanged; load-time JS guarded for the formless render - T5 render test (banner/no-form on 'no', form on yes/unknown); red-proof RP5 run (conditional dropped → banner assertions fail) and reverted - template_id_gate + emoji_gate green Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1048,6 +1048,9 @@ func (s *Server) storagePageData() map[string]interface{} {
|
|||||||
func (s *Server) networkStoragePageData() map[string]interface{} {
|
func (s *Server) networkStoragePageData() map[string]interface{} {
|
||||||
data := s.settingsBaseData("storage-network", "Hálózati tárhely")
|
data := s.settingsBaseData("storage-network", "Hálózati tárhely")
|
||||||
data["NetworkStoragePaths"] = s.networkStorageItems(context.Background())
|
data["NetworkStoragePaths"] = s.networkStorageItems(context.Background())
|
||||||
|
// Capability banner: "no" swaps the add form for the agent-outdated notice (yes/unknown render
|
||||||
|
// the form — flaky states belong to the add-time gate). Short-budget probe, cache-backed.
|
||||||
|
data["NetAddSupport"] = s.netAddSupport()
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func TestStorageNetworkTemplate_CanonicalClasses(t *testing.T) {
|
|||||||
s.loadTemplates()
|
s.loadTemplates()
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"Page": "storage-network", "Title": "Hálózati tárhely",
|
"Page": "storage-network", "Title": "Hálózati tárhely",
|
||||||
|
"NetAddSupport": "yes",
|
||||||
"NetworkStoragePaths": []networkStorageItem{
|
"NetworkStoragePaths": []networkStorageItem{
|
||||||
{Name: "media", Label: "NAS media", Protocol: "nfs", Server: "10.0.0.5", Export: "/srv/media", Path: "/mnt/felhom-drives/media", Health: "ok"},
|
{Name: "media", Label: "NAS media", Protocol: "nfs", Server: "10.0.0.5", Export: "/srv/media", Path: "/mnt/felhom-drives/media", Health: "ok"},
|
||||||
{Name: "ghost", Label: "Árva megosztás: ghost", Protocol: "nfs", Server: "10.0.0.5", Export: "/srv/ghost", Path: "/mnt/felhom-drives/ghost", Health: "idle", Orphan: true},
|
{Name: "ghost", Label: "Árva megosztás: ghost", Protocol: "nfs", Server: "10.0.0.5", Export: "/srv/ghost", Path: "/mnt/felhom-drives/ghost", Health: "idle", Orphan: true},
|
||||||
@@ -54,3 +55,52 @@ func TestStorageNetworkTemplate_CanonicalClasses(t *testing.T) {
|
|||||||
t.Error("remove action missing")
|
t.Error("remove action missing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- T5 (Scenario D): capability banner replaces the add form on an old agent -------------------
|
||||||
|
// Companion red-proof: drop the {{if eq .NetAddSupport "no"}} wrapper (always render the form) →
|
||||||
|
// the banner-present + form-absent assertions on "no" fail.
|
||||||
|
func TestStorageNetworkTemplate_AgentOutdatedBanner(t *testing.T) {
|
||||||
|
s := testServer(t)
|
||||||
|
s.loadTemplates()
|
||||||
|
render := func(support string) string {
|
||||||
|
t.Helper()
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := s.tmpl.ExecuteTemplate(&buf, "storage_network", map[string]interface{}{
|
||||||
|
"Page": "storage-network", "Title": "Hálózati tárhely",
|
||||||
|
"NetAddSupport": support,
|
||||||
|
"NetworkStoragePaths": []networkStorageItem{
|
||||||
|
{Name: "media", Label: "NAS media", Protocol: "nfs", Server: "10.0.0.5", Export: "/srv/media", Path: "/mnt/felhom-drives/media", Health: "ok"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("render (support=%s): %v", support, err)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
const banner = "A rendszer háttérszolgáltatása (ügynök) régebbi verziójú"
|
||||||
|
t.Run("no → banner instead of form; list + remove intact", func(t *testing.T) {
|
||||||
|
html := render("no")
|
||||||
|
if !strings.Contains(html, banner) {
|
||||||
|
t.Error("the §Part-3 banner is missing on an old agent")
|
||||||
|
}
|
||||||
|
if strings.Contains(html, `id="ns-add-form"`) {
|
||||||
|
t.Error("the add form must NOT render on an old agent")
|
||||||
|
}
|
||||||
|
// The share list + remove action stay fully usable in every state.
|
||||||
|
if !strings.Contains(html, "NAS media") || !strings.Contains(html, "Eltávolítás") {
|
||||||
|
t.Error("share list/remove must still render under the banner")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for _, support := range []string{"yes", "unknown"} {
|
||||||
|
t.Run(support+" → form as today", func(t *testing.T) {
|
||||||
|
html := render(support)
|
||||||
|
if !strings.Contains(html, `id="ns-add-form"`) {
|
||||||
|
t.Errorf("the add form must render on support=%s", support)
|
||||||
|
}
|
||||||
|
if strings.Contains(html, banner) {
|
||||||
|
t.Errorf("the banner must NOT render on support=%s", support)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,6 +48,13 @@
|
|||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Hálózati tárhely hozzáadása</h3>
|
<h3>Hálózati tárhely hozzáadása</h3>
|
||||||
|
{{if eq .NetAddSupport "no"}}
|
||||||
|
<!-- Capability gate (agent predates the verify-before-commit add semantics): the add form is
|
||||||
|
withheld; the share list + remove above stay fully usable. -->
|
||||||
|
<div class="alert alert-warning">A rendszer háttérszolgáltatása (ügynök) régebbi verziójú, ezért új
|
||||||
|
hálózati tárhely most nem csatlakoztatható. A frissítés megérkezése után a funkció automatikusan
|
||||||
|
elérhetővé válik — a meglévő megosztások addig is működnek.</div>
|
||||||
|
{{else}}
|
||||||
<p class="settings-card-desc">A csatlakoztatás előtt a rendszer ellenőrzi a megosztást: valóban
|
<p class="settings-card-desc">A csatlakoztatás előtt a rendszer ellenőrzi a megosztást: valóban
|
||||||
csatolható-e, és tudnak-e írni rá az alkalmazások. Hiba esetén semmi nem marad félkészen beállítva.</p>
|
csatolható-e, és tudnak-e írni rá az alkalmazások. Hiba esetén semmi nem marad félkészen beállítva.</p>
|
||||||
<form id="ns-add-form" onsubmit="return netStorageAdd(event)">
|
<form id="ns-add-form" onsubmit="return netStorageAdd(event)">
|
||||||
@@ -93,6 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="ns-add-result" style="margin-top:1rem"></div>
|
<div id="ns-add-result" style="margin-top:1rem"></div>
|
||||||
</form>
|
</form>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
@@ -206,8 +214,7 @@ function netStorageRemove(name,label){
|
|||||||
}).catch(function(e){ alert('Hiba: '+e); });
|
}).catch(function(e){ alert('Hiba: '+e); });
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
nsToggleSmb();
|
if(document.getElementById('ns-add-form')){ nsToggleSmb(); nsUpdateHostID(); } // form absent on the capability banner
|
||||||
nsUpdateHostID();
|
|
||||||
</script>
|
</script>
|
||||||
<div id="dialog-root"></div>
|
<div id="dialog-root"></div>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
Reference in New Issue
Block a user