Commit Graph

6 Commits

Author SHA1 Message Date
Joseph Doherty cf9548e9ed feat(ui/scripts): Roslyn-backed C# completions + diagnostics for Monaco
Adds Microsoft.CodeAnalysis.CSharp.Scripting (4.13.0). Scripts are
compiled as C# script fragments against a ScriptHost globals type
that mirrors what the runtime exposes (Parameters bag, CallShared,
CallScript) — Roslyn reads the signatures so those identifiers are
in scope for analysis without executing anything.

ScriptAnalysisService:
  - Diagnose(code): Compilation.GetDiagnostics() projected to
    Monaco-shaped DiagnosticMarker records (severity 8/4/2/1).
  - Complete(code, line, col): dot-member lookup via SemanticModel
    when the token at position is part of a MemberAccessExpression;
    falls back to LookupSymbols at position for the general case.

Two endpoints exposed by the existing CentralUI endpoint pipeline,
both behind RequireDesign policy:
  POST /api/script-analysis/diagnostics
  POST /api/script-analysis/completions

monaco-init.js registers a csharp CompletionItemProvider with dot/
paren/quote trigger chars, plus a 500 ms debounced diagnostics pass
on every keystroke that pushes markers via setModelMarkers. Initial
pass fires on editor create so existing scripts surface errors right
away. Auth uses the existing cookie via credentials: same-origin.

Smoke-verified:
  - Typing `DateTimeOffset.UtcNow` (no semicolon) shows the missing
    semicolon squiggle in real time.
  - Ctrl-Space at file scope returns the full type universe
    (AccessViolationException, Action, Akka, AppDomain, ...).

Wave 2 of three. SCADA-specific extensions (declared param keys,
shared/sibling script names, forbidden-API diagnostic) follow.
2026-05-12 04:40:07 -04:00
Joseph Doherty 7f01c5547a feat(ui/design): Monaco editor for script code fields
Vendors Monaco 0.55.1 min/vs/ (~15 MB) at
wwwroot/lib/monaco/vs/. No CDN dependency; works on air-gapped
deployments. Loaded lazily on first script-edit via the AMD loader.

wwwroot/js/monaco-init.js exposes window.MonacoBlazor with
createEditor / setValue / getValue / setMarkers / dispose. Handles
loader bootstrap, DotNet round-trip on content change, and marker
sets for later diagnostic wiring.

Components/Shared/MonacoEditor.razor is a Blazor wrapper with
Value / ValueChanged / Language / Height / ReadOnly parameters and
IAsyncDisposable teardown. Bidirectional binding tracks
_lastSentValue to avoid push/pull loops.

Replaces the plain textareas in SharedScriptForm, TemplateEdit's
Add-Script form, and ApiMethodForm. Default height 320px ≈ the
previous rows=10. Build / tests / dialog flow unaffected.

Wave 1 of three. Roslyn-backed completions and SCADA-specific
extensions follow in subsequent commits.
2026-05-12 04:34:41 -04:00
Joseph Doherty eb1d6872ef refactor(ui/shared): migrate sidebar CSS to Bootstrap variables
Replaces hardcoded sidebar / nav-link hex colors with Bootstrap CSS
custom properties (var(--bs-dark), var(--bs-primary), var(--bs-gray-*),
var(--bs-white)). Visual parity preserved; rebrand/dark-mode work
later can override the variables without touching this file.

Only the reconnect overlay rgba(0,0,0,0.5) is left as a literal —
Bootstrap doesn't ship a backdrop-overlay token.
2026-05-12 03:57:45 -04:00
Joseph Doherty f7b10f2ff7 refactor(ui/shared): scroll-lock, escape, aria-live, responsive sidebar
ConfirmDialog locks body scroll via IJSRuntime + Bootstrap's
modal-open class on show, restores on hide. Escape key now closes
the dialog; default ConfirmButtonClass flipped from btn-danger to
btn-primary so non-destructive confirms aren't red. Destructive
callsites (Delete, Discard) get explicit ConfirmButtonClass="btn-danger".

ToastNotification adds aria-live="polite" + aria-atomic="true" on the
container and an optional autoDismissMs parameter on every Show* method.

LoadingSpinner text-muted -> text-secondary for contrast.

DataTable gains a clear (x) button on the search input and applies
disabled / aria-disabled directly to the pagination buttons.

NewFolderDialog splits backdrop and modal markup to match ConfirmDialog.

NavMenu wraps the nav list in an overflow-y scroll container so the
username/sign-out footer stays anchored, and section headers convert
from <li> to <div role="presentation">.

MainLayout adds a hamburger toggle for <lg viewports; sidebar collapses
via Bootstrap collapse data attributes.

App.razor extracts inline <style> block to a shared site.css; adds a
left-border accent on the active nav link; switches the reconnect
modal to modal-dialog-centered.

Login uses d-flex / min-vh-100 centering. NotAuthorizedView gets the
same centered layout plus the ScadaLink brand heading.

Sites.razor: only the new ConfirmButtonClass="btn-danger" follow-up.
2026-05-12 03:32:07 -04:00
Joseph Doherty addbb6ffeb fix(ui): move treeview-storage.js to Host wwwroot where static files are served 2026-03-24 16:19:39 -04:00
Joseph Doherty d3a6ed5f68 feat(ui): add sessionStorage persistence for TreeView expansion state (R11) 2026-03-24 16:19:39 -04:00