using Microsoft.EntityFrameworkCore; using ZB.MOM.WW.OtOpcUa.Configuration; namespace ZB.MOM.WW.OtOpcUa.AdminUI.ScriptList; /// One row of the /scripts list: everything the list renders, and nothing else. /// The script's logical id. /// The authored display name. /// The script language (e.g. CSharp). /// The source hash shown abbreviated on the row. public sealed record ScriptListRow(string ScriptId, string Name, string Language, string SourceHash); /// /// Queries behind the /scripts page. The list is a projection that leaves out /// SourceCode (R04 P8): loading every script's full source to render names and hashes made /// the page cost proportional to the total size of every script in the fleet. The source is fetched /// on demand, for one script, when its "Source" dialog opens. /// public static class ScriptListQueries { /// Loads the list rows, ordered by name, without any script's source. /// The config DB context. /// Cancellation token. /// The list rows. public static Task> LoadRowsAsync(OtOpcUaConfigDbContext db, CancellationToken ct = default) => db.Scripts.AsNoTracking() .OrderBy(s => s.Name) .Select(s => new ScriptListRow(s.ScriptId, s.Name, s.Language, s.SourceHash)) .ToListAsync(ct); /// Loads one script's source, or null when the script no longer exists. /// The config DB context. /// The script's logical id. /// Cancellation token. /// The source code, or null. public static Task LoadSourceAsync(OtOpcUaConfigDbContext db, string scriptId, CancellationToken ct = default) => db.Scripts.AsNoTracking() .Where(s => s.ScriptId == scriptId) .Select(s => (string?)s.SourceCode) .FirstOrDefaultAsync(ct); }