feat(uns): equipment modal wired into the tree
This commit is contained in:
@@ -22,6 +22,33 @@ public sealed record AreaEditDto(string UnsAreaId, string Name, string? Notes, s
|
||||
/// <param name="RowVersion">The optimistic-concurrency token last read.</param>
|
||||
public sealed record LineEditDto(string UnsLineId, string UnsAreaId, string Name, string? Notes, byte[] RowVersion);
|
||||
|
||||
/// <summary>
|
||||
/// An equipment projected for editing: its system-generated id, the operator-editable identity and
|
||||
/// OPC 40010 identification fields, plus the concurrency token the edit modal must echo back on save.
|
||||
/// </summary>
|
||||
/// <param name="EquipmentId">The system-generated stable id (read-only — never operator-edited, decision #125).</param>
|
||||
/// <param name="Name">UNS level-5 segment name.</param>
|
||||
/// <param name="MachineCode">Operator colloquial id; unique fleet-wide.</param>
|
||||
/// <param name="UnsLineId">The owning line id (the UNS-line selection).</param>
|
||||
/// <param name="DriverInstanceId">Optional driver binding; <c>null</c> when driver-less.</param>
|
||||
/// <param name="ZTag">Optional ERP equipment id.</param>
|
||||
/// <param name="SAPID">Optional SAP PM equipment id.</param>
|
||||
/// <param name="Manufacturer">Optional OPC 40010 manufacturer name.</param>
|
||||
/// <param name="Model">Optional OPC 40010 model designation.</param>
|
||||
/// <param name="SerialNumber">Optional OPC 40010 serial number.</param>
|
||||
/// <param name="HardwareRevision">Optional OPC 40010 hardware revision.</param>
|
||||
/// <param name="SoftwareRevision">Optional OPC 40010 software revision.</param>
|
||||
/// <param name="YearOfConstruction">Optional OPC 40010 year of construction.</param>
|
||||
/// <param name="AssetLocation">Optional OPC 40010 asset location.</param>
|
||||
/// <param name="ManufacturerUri">Optional OPC 40010 manufacturer URI.</param>
|
||||
/// <param name="DeviceManualUri">Optional OPC 40010 device-manual URI.</param>
|
||||
/// <param name="Enabled">Whether the equipment is surfaced in deployments.</param>
|
||||
/// <param name="RowVersion">The optimistic-concurrency token last read.</param>
|
||||
public sealed record EquipmentEditDto(string EquipmentId, string Name, string MachineCode, string UnsLineId,
|
||||
string? DriverInstanceId, string? ZTag, string? SAPID, string? Manufacturer, string? Model, string? SerialNumber,
|
||||
string? HardwareRevision, string? SoftwareRevision, short? YearOfConstruction, string? AssetLocation,
|
||||
string? ManufacturerUri, string? DeviceManualUri, bool Enabled, byte[] RowVersion);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the structural portion of the unified-namespace (UNS) browse tree —
|
||||
/// Enterprise → Cluster → Area → Line → Equipment — from the config database.
|
||||
@@ -67,6 +94,26 @@ public interface IUnsTreeService
|
||||
/// <returns>The line's edit projection, or <c>null</c> when missing.</returns>
|
||||
Task<LineEditDto?> LoadLineAsync(string unsLineId, CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// Loads a single equipment projected for editing, or <c>null</c> if it no longer exists.
|
||||
/// Reads untracked and captures the current concurrency token for last-write-wins saves.
|
||||
/// </summary>
|
||||
/// <param name="equipmentId">The equipment to load.</param>
|
||||
/// <param name="ct">A token to cancel the load.</param>
|
||||
/// <returns>The equipment's edit projection, or <c>null</c> when missing.</returns>
|
||||
Task<EquipmentEditDto?> LoadEquipmentAsync(string equipmentId, CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// Loads every driver instance in a cluster (regardless of namespace kind) so the equipment modal
|
||||
/// can offer the full cluster driver list for binding. Ordered by <c>DriverInstanceId</c>. Each is
|
||||
/// projected to a <c>(DriverInstanceId, Display)</c> pair where <c>Display</c> is
|
||||
/// <c>"{DriverInstanceId} — {Name} ({DriverType})"</c>.
|
||||
/// </summary>
|
||||
/// <param name="clusterId">The cluster whose drivers to load.</param>
|
||||
/// <param name="ct">A token to cancel the load.</param>
|
||||
/// <returns>The cluster's drivers projected to <c>(DriverInstanceId, Display)</c> pairs.</returns>
|
||||
Task<IReadOnlyList<(string DriverInstanceId, string Display)>> LoadDriversForClusterAsync(string clusterId, CancellationToken ct = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new UNS area under a cluster. Fails if an area with the same id already exists.
|
||||
/// Whitespace-only notes are stored as <c>null</c>.
|
||||
|
||||
@@ -148,6 +148,55 @@ public sealed class UnsTreeService(IDbContextFactory<OtOpcUaConfigDbContext> dbF
|
||||
.FirstOrDefaultAsync(ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<EquipmentEditDto?> LoadEquipmentAsync(string equipmentId, CancellationToken ct = default)
|
||||
{
|
||||
await using var db = await dbFactory.CreateDbContextAsync(ct);
|
||||
|
||||
return await db.Equipment
|
||||
.AsNoTracking()
|
||||
.Where(e => e.EquipmentId == equipmentId)
|
||||
.Select(e => new EquipmentEditDto(
|
||||
e.EquipmentId,
|
||||
e.Name,
|
||||
e.MachineCode,
|
||||
e.UnsLineId,
|
||||
e.DriverInstanceId,
|
||||
e.ZTag,
|
||||
e.SAPID,
|
||||
e.Manufacturer,
|
||||
e.Model,
|
||||
e.SerialNumber,
|
||||
e.HardwareRevision,
|
||||
e.SoftwareRevision,
|
||||
e.YearOfConstruction,
|
||||
e.AssetLocation,
|
||||
e.ManufacturerUri,
|
||||
e.DeviceManualUri,
|
||||
e.Enabled,
|
||||
e.RowVersion))
|
||||
.FirstOrDefaultAsync(ct);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<(string DriverInstanceId, string Display)>> LoadDriversForClusterAsync(
|
||||
string clusterId,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
await using var db = await dbFactory.CreateDbContextAsync(ct);
|
||||
|
||||
var drivers = await db.DriverInstances
|
||||
.AsNoTracking()
|
||||
.Where(d => d.ClusterId == clusterId)
|
||||
.OrderBy(d => d.DriverInstanceId)
|
||||
.Select(d => new { d.DriverInstanceId, d.Name, d.DriverType })
|
||||
.ToListAsync(ct);
|
||||
|
||||
return drivers
|
||||
.Select(d => (d.DriverInstanceId, Display: $"{d.DriverInstanceId} — {d.Name} ({d.DriverType})"))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<UnsMutationResult> CreateAreaAsync(
|
||||
string clusterId,
|
||||
|
||||
Reference in New Issue
Block a user