diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor index 24cea2d7..78a8e78a 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor +++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor @@ -14,6 +14,7 @@ @inject ICentralUiRepository CentralUiRepository @inject TemplateService TemplateService @inject ZB.MOM.WW.ScadaBridge.CentralUI.ScriptAnalysis.ScriptAnalysisService AnalysisService +@inject ZB.MOM.WW.ScadaBridge.CentralUI.Services.ITemplateInheritanceQueryService InheritanceQuery @inject AuthenticationStateProvider AuthStateProvider @inject NavigationManager NavigationManager @inject IDialogService Dialog @@ -62,6 +63,12 @@ private Template? _ownerTemplate; private TemplateComposition? _ownerComposition; + // M9-T26b: the FULL transitively-resolved inherited member set (multi-level + // chain + post-creation base additions) + staleness, fetched read-only via + // GetResolvedTemplateMembersCommand. Populated only for derived templates; + // null when the read failed (editor falls back to the stored-row view). + private Commons.Messages.Management.ResolvedTemplateMembers? _resolved; + private bool _loading = true; private string? _loadError; private string _activeTab = "attributes"; @@ -195,6 +202,7 @@ _baseTemplate = null; _ownerTemplate = null; _ownerComposition = null; + _resolved = null; if (_selectedTemplate.IsDerived && _selectedTemplate.ParentTemplateId.HasValue) { _baseTemplate = await TemplateEngineRepository.GetTemplateByIdAsync(_selectedTemplate.ParentTemplateId.Value); @@ -218,6 +226,14 @@ } } } + + // M9-T26b: resolve the FULL inherited member set (whole chain + + // post-creation base additions) read-only. The stored-row tables + // above only carry the IMMEDIATE base; this surfaces the rest with + // origin annotation + a base-changed staleness banner. Read-only: + // a failed read leaves _resolved null and the editor degrades to + // the stored-row view. + _resolved = await InheritanceQuery.ResolveAsync(Id); } // Editor metadata: child compositions + every parent that @@ -270,6 +286,32 @@ } + + @* M9-T26b: read-only base-changed banner. Informational only — surfaced + when the freshly-resolved inherited set differs from this template's + stored copy (a multi-level inherited member, or a base member added + after this template was created). No action button: a deploy already + resolves fresh, so this is purely an authoring heads-up. *@ + @if (_resolved?.Staleness.IsStale == true) + { +
No resolved members.
+ } +| Name | +Effective value | + @if (showTrigger) + { +Trigger config (effective) | + } +Source | +Lock | +
|---|---|---|---|---|
| @m.Name | +@(m.EffectiveValue ?? "—") | + @if (showTrigger) + { ++ @(string.IsNullOrEmpty(m.EffectiveTriggerConfiguration) ? "—" : m.EffectiveTriggerConfiguration) + | + } ++ @if (m.IsInherited) + { + + Inherited from @m.OriginTemplateName + + } + else + { + Local + } + | ++ @if (m.IsBaseLocked) + { + 🔒 Base-locked + } + else if (m.IsLocked) + { + Locked + } + else + { + Unlocked + } + | +