feat(adminui): ScriptEdit uses MonacoEditor; drop CDN loader

This commit is contained in:
Joseph Doherty
2026-06-09 15:11:13 -04:00
parent 071bed5f94
commit 088fc50ef2
2 changed files with 2 additions and 87 deletions
@@ -13,7 +13,6 @@
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
@inject IDbContextFactory<OtOpcUaConfigDbContext> DbFactory
@inject NavigationManager Nav
@inject IJSRuntime JS
<div class="d-flex justify-content-between align-items-center mb-3">
<h4 class="mb-0">@(IsNew ? "New script" : "Edit script")</h4>
@@ -57,15 +56,8 @@ else
<section class="panel rise mt-3">
<div class="panel-head">Source</div>
<div style="padding:1rem">
@* The textarea stays in the DOM and remains Blazor's source of truth. Monaco
mounts a <div> beside it (textarea hides), and the loader's onDidChangeModelContent
handler mirrors edits back into the textarea + fires the input event so @bind
picks them up. Falls back to the textarea gracefully if Monaco's CDN is
unreachable (air-gapped deployments — see monaco-loader.js). *@
<InputTextArea id="script-source" @bind-Value="_form.SourceCode"
class="form-control form-control-sm mono" rows="20"
placeholder="// C# expression body" />
<div class="form-text">SHA-256 hash is computed automatically on save. Monaco editor attaches over the textarea on render.</div>
<MonacoEditor @bind-Value="_form.SourceCode" Height="420px" />
<div class="form-text">SHA-256 hash is computed automatically on save.</div>
</div>
</section>
@@ -110,24 +102,6 @@ else
_loaded = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender || !_loaded) return;
// Inject loader once, then attach over the textarea. Failures are silent — the page
// is fully usable via the underlying textarea if Monaco's CDN is unreachable.
try
{
await JS.InvokeVoidAsync("eval", "if (!document.querySelector('script[data-otopcua=monaco-loader]')) { var s=document.createElement('script'); s.src='/_content/ZB.MOM.WW.OtOpcUa.AdminUI/js/monaco-loader.js'; s.dataset.otopcua='monaco-loader'; document.head.appendChild(s); }");
// Wait a tick for the loader IIFE to register window.otOpcUaScriptEditor, then attach.
await Task.Delay(50);
await JS.InvokeVoidAsync("otOpcUaScriptEditor.attach", "script-source");
}
catch
{
// Textarea remains the editor — no-op.
}
}
private async Task SubmitAsync()
{
_busy = true; _error = null;