feat(templates/ui): phase 9 — single-parent editor context
Derive-on-compose guarantees at most one slot owner per template, so the Parent.* context in the Monaco editor resolves directly via OwnerCompositionId without a picker. Base templates suppress Parent.* assistance entirely (empty context). Removed the multi-parent <select> dropdown from the Add Script form and the now-redundant _selectedParentIndex / OnParentContextChanged plumbing. ActiveEditorParent collapses to _editorParents.FirstOrDefault().
This commit is contained in:
@@ -103,20 +103,15 @@
|
|||||||
= Array.Empty<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>();
|
= Array.Empty<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// One entry per template that composes this one (in the design-time
|
/// Editor's Parent.* context. Empty for base templates (no owner exists);
|
||||||
/// graph). Populated by <see cref="LoadEditorParentsAsync"/>; the user
|
/// exactly one entry for derived templates — the slot-owner resolved from
|
||||||
/// picks one via <see cref="_selectedParentIndex"/> when multiple exist.
|
/// the template's OwnerCompositionId.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext> _editorParents
|
private List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext> _editorParents
|
||||||
= new();
|
= new();
|
||||||
|
|
||||||
/// <summary>Index into <see cref="_editorParents"/>; -1 when none.</summary>
|
|
||||||
private int _selectedParentIndex = -1;
|
|
||||||
|
|
||||||
private ScadaLink.CentralUI.ScriptAnalysis.CompositionContext? ActiveEditorParent =>
|
private ScadaLink.CentralUI.ScriptAnalysis.CompositionContext? ActiveEditorParent =>
|
||||||
_selectedParentIndex >= 0 && _selectedParentIndex < _editorParents.Count
|
_editorParents.FirstOrDefault();
|
||||||
? _editorParents[_selectedParentIndex]
|
|
||||||
: null;
|
|
||||||
|
|
||||||
private bool _showCompForm;
|
private bool _showCompForm;
|
||||||
private int _compComposedTemplateId;
|
private int _compComposedTemplateId;
|
||||||
@@ -190,7 +185,6 @@
|
|||||||
// editor.
|
// editor.
|
||||||
_editorChildren = await BuildChildContextsAsync(_compositions);
|
_editorChildren = await BuildChildContextsAsync(_compositions);
|
||||||
_editorParents = await BuildParentContextsAsync(Id);
|
_editorParents = await BuildParentContextsAsync(Id);
|
||||||
_selectedParentIndex = _editorParents.Count > 0 ? 0 : -1;
|
|
||||||
|
|
||||||
_validationResult = null;
|
_validationResult = null;
|
||||||
}
|
}
|
||||||
@@ -865,21 +859,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label class="form-label">Code</label>
|
<label class="form-label">Code</label>
|
||||||
@if (_editorParents.Count > 1)
|
|
||||||
{
|
|
||||||
<div class="small text-muted mb-2">
|
|
||||||
Parent context for editor:
|
|
||||||
<select class="form-select form-select-sm d-inline-block w-auto ms-1"
|
|
||||||
value="@_selectedParentIndex"
|
|
||||||
@onchange="OnParentContextChanged">
|
|
||||||
@foreach (var (parent, idx) in _editorParents.Select((p, i) => (p, i)))
|
|
||||||
{
|
|
||||||
<option value="@idx">@parent.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
<span class="ms-2">(this template is composed by @_editorParents.Count parents; pick one for <code>Parent.*</code> assistance)</span>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<MonacoEditor @ref="_scriptEditor" Value="@_scriptCode" ValueChanged="@(v => _scriptCode = v)"
|
<MonacoEditor @ref="_scriptEditor" Value="@_scriptCode" ValueChanged="@(v => _scriptCode = v)"
|
||||||
Language="csharp" Height="320px"
|
Language="csharp" Height="320px"
|
||||||
DeclaredParameters="@ScriptParameterNames.Parse(_scriptParameters)"
|
DeclaredParameters="@ScriptParameterNames.Parse(_scriptParameters)"
|
||||||
@@ -1311,10 +1290,21 @@
|
|||||||
|
|
||||||
private async Task<List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>> BuildParentContextsAsync(int templateId)
|
private async Task<List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>> BuildParentContextsAsync(int templateId)
|
||||||
{
|
{
|
||||||
var parents = await TemplateEngineRepository.GetTemplatesComposingAsync(templateId);
|
// Post derive-on-compose: only derived templates have a parent context,
|
||||||
return parents
|
// and exactly one — the template that owns their composition slot.
|
||||||
.Select(p => BuildCompositionContext(p.Name, p))
|
// Base templates suppress Parent.* assistance.
|
||||||
.ToList();
|
if (_selectedTemplate?.IsDerived != true || _ownerTemplate == null)
|
||||||
|
return new List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>();
|
||||||
|
|
||||||
|
// Resolve the owner with eager-loaded members so the context has shapes.
|
||||||
|
var owner = await TemplateEngineRepository.GetTemplateByIdAsync(_ownerTemplate.Id);
|
||||||
|
if (owner == null)
|
||||||
|
return new List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>();
|
||||||
|
|
||||||
|
return new List<ScadaLink.CentralUI.ScriptAnalysis.CompositionContext>
|
||||||
|
{
|
||||||
|
BuildCompositionContext(owner.Name, owner)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ScadaLink.CentralUI.ScriptAnalysis.CompositionContext BuildCompositionContext(
|
private static ScadaLink.CentralUI.ScriptAnalysis.CompositionContext BuildCompositionContext(
|
||||||
@@ -1331,12 +1321,6 @@
|
|||||||
return new ScadaLink.CentralUI.ScriptAnalysis.CompositionContext(label, attrs, scripts);
|
return new ScadaLink.CentralUI.ScriptAnalysis.CompositionContext(label, attrs, scripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnParentContextChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
if (int.TryParse(e.Value?.ToString(), out var idx) && idx >= 0 && idx < _editorParents.Count)
|
|
||||||
_selectedParentIndex = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string MapDataType(ScadaLink.Commons.Types.Enums.DataType dt) => dt switch
|
private static string MapDataType(ScadaLink.Commons.Types.Enums.DataType dt) => dt switch
|
||||||
{
|
{
|
||||||
ScadaLink.Commons.Types.Enums.DataType.Boolean => "Boolean",
|
ScadaLink.Commons.Types.Enums.DataType.Boolean => "Boolean",
|
||||||
|
|||||||
Reference in New Issue
Block a user