fix(admin-ui): render published gen read-only on the 6 cluster-detail content tabs
The Equipment, UNS Structure, Namespaces, Drivers, Tags, and ACLs tabs all rendered only an "Open a draft to edit" placeholder when no draft was open — even when the cluster had a fully populated published generation. docs/v2/admin-ui.md \xa7Cluster Detail describes these as "read-only views of the published generation" with an "Edit in draft" affordance; that view was never wired. The earlier code path also correctly rendered nothing when the cluster had no published gen yet, which was indistinguishable from the broken state. Collapse the six per-tab conditions into one shared branch that threads the published gen ID into the existing tab components when no draft exists, wrapped in <fieldset disabled> so any Add/Edit button click in the read-only state cannot silently mutate published rows even though the tab components themselves don't yet honor an IsReadOnly flag. Banner above the content explains the state. Surgical: zero changes to the ~1500 LoC across the six tab components. Verified live on cluster-dev gen 1: Drivers tab now shows the cluster-dev-galaxy-main GalaxyMxGateway row read-only; Namespaces tab shows cluster-dev-galaxy-ns SystemPlatform row; both with the read-only banner and visibly disabled affordances. Follow-up worth doing later: refactor each tab component to accept an IsReadOnly parameter so the disabled-affordance UX is per-tab rather than a blanket fieldset opacity wash. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,29 +101,44 @@ else
|
||||
{
|
||||
<Generations ClusterId="@ClusterId"/>
|
||||
}
|
||||
else if (_tab == "equipment" && _currentDraft is not null)
|
||||
else if (_tab is "equipment" or "uns" or "namespaces" or "drivers" or "tags" or "acls")
|
||||
{
|
||||
<EquipmentTab GenerationId="@_currentDraft.GenerationId"/>
|
||||
@* Bug #10 fix — these six tabs are scoped to a generation. Per docs/v2/admin-ui.md the
|
||||
design intent is a read-only view of the published generation when no draft is open
|
||||
("Edit in draft" affordance), and the editable view of the draft when one is open.
|
||||
The earlier implementation rendered nothing in the no-draft case, leaving operators
|
||||
with just the "Open a draft to edit" placeholder. We now route both states through
|
||||
the same tab components, gating edits via <fieldset disabled> so a button click in
|
||||
the read-only state cannot silently mutate the published rows even though the tab
|
||||
components themselves haven't been refactored to honor an IsReadOnly flag yet. *@
|
||||
var genId = _currentDraft?.GenerationId ?? _currentPublished?.GenerationId;
|
||||
var isReadOnly = _currentDraft is null;
|
||||
if (genId is null)
|
||||
{
|
||||
<section class="panel notice rise" style="animation-delay:.02s">
|
||||
No published generation yet. Click <strong>New draft</strong> above to author this cluster's first generation.
|
||||
</section>
|
||||
}
|
||||
else if (_tab == "uns" && _currentDraft is not null)
|
||||
else
|
||||
{
|
||||
<UnsTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
|
||||
if (isReadOnly)
|
||||
{
|
||||
<section class="panel notice rise mb-3" style="animation-delay:.02s">
|
||||
<strong>Read-only view</strong> of published generation @genId. Click <strong>New draft</strong> above to make changes.
|
||||
</section>
|
||||
}
|
||||
else if (_tab == "namespaces" && _currentDraft is not null)
|
||||
<fieldset disabled="@isReadOnly" style="border:0;padding:0;margin:0;min-width:0;">
|
||||
@switch (_tab)
|
||||
{
|
||||
<NamespacesTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
|
||||
case "equipment": <EquipmentTab GenerationId="@genId.Value"/> break;
|
||||
case "uns": <UnsTab GenerationId="@genId.Value" ClusterId="@ClusterId"/> break;
|
||||
case "namespaces": <NamespacesTab GenerationId="@genId.Value" ClusterId="@ClusterId"/> break;
|
||||
case "drivers": <DriversTab GenerationId="@genId.Value" ClusterId="@ClusterId"/> break;
|
||||
case "tags": <TagsTab GenerationId="@genId.Value" ClusterId="@ClusterId"/> break;
|
||||
case "acls": <AclsTab GenerationId="@genId.Value" ClusterId="@ClusterId"/> break;
|
||||
}
|
||||
else if (_tab == "drivers" && _currentDraft is not null)
|
||||
{
|
||||
<DriversTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
|
||||
</fieldset>
|
||||
}
|
||||
else if (_tab == "tags" && _currentDraft is not null)
|
||||
{
|
||||
<TagsTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
|
||||
}
|
||||
else if (_tab == "acls" && _currentDraft is not null)
|
||||
{
|
||||
<AclsTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
|
||||
}
|
||||
else if (_tab == "redundancy")
|
||||
{
|
||||
@@ -133,10 +148,6 @@ else
|
||||
{
|
||||
<AuditTab ClusterId="@ClusterId"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<section class="panel notice rise" style="animation-delay:.02s">Open a draft to edit this cluster's content.</section>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
Reference in New Issue
Block a user