namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns;
///
/// The kind of node within the v3 Raw project tree (/raw). Determines how the
/// renderer styles the row, which context-menu it shows, and which entity (if any) it
/// links to. The Raw tree is cluster-rooted and mirrors the RawPath hierarchy:
/// Enterprise → Cluster → Folder(s) → Driver → Device → TagGroup(s) → Tag.
///
public enum RawNodeKind
{
/// Top-level grouping label (a string on cluster rows, not a DB entity).
Enterprise,
/// A server cluster — the root of a Raw project tree.
Cluster,
/// A driver-organizing RawFolder (nestable under a cluster or another folder).
Folder,
/// A DriverInstance.
Driver,
/// A Device under a driver (universal in v3 — every driver has ≥1).
Device,
/// A tag-organizing TagGroup (nestable under a device or another group).
TagGroup,
/// A raw Tag (signal) — a leaf.
Tag,
}
///
/// View-model for a single node in the Raw project tree. Carries the stable identity,
/// display text, per-kind ids, and lazy-load metadata the renderer needs, plus transient UI
/// state (expansion/loading) that is never persisted. Detached from EF — safe to hold and
/// mutate UI state on after the loading context is disposed. This is the shared contract
/// between (which produces nodes) and the RawTree
/// component (which renders + lazily expands them).
///
public sealed class RawNode
{
/// The kind of node — drives styling, context-menu, and entity linking.
public required RawNodeKind Kind { get; init; }
/// Stable per-node key, unique within the tree (e.g. drv:{driverInstanceId}).
public required string Key { get; init; }
/// Human-readable label shown in the tree (the node's Name, or Enterprise/Cluster label).
public required string DisplayName { get; init; }
/// Owning cluster id for every node under a cluster (and the cluster itself); null for Enterprise.
public string? ClusterId { get; init; }
///
/// This node's own logical entity id (RawFolderId/DriverInstanceId/DeviceId/
/// TagGroupId/TagId, or the ClusterId for a cluster); null for Enterprise. The
/// child loader keys off + this id to fetch the next level.
///
public string? EntityId { get; init; }
///
/// The bound DriverType for (and propagated to Device/TagGroup/Tag
/// nodes beneath it, so tag editors and the browse-enable gate can dispatch without another query);
/// null for folders/clusters/enterprise. Use the DriverTypeNames constants when matching.
///
public string? DriverType { get; init; }
/// Whether a Driver/Device node is enabled (drives the enable/disable menu label + styling); true otherwise.
public bool Enabled { get; init; } = true;
/// Direct child count (for the badge) — for a device, its root tag-groups + root tags (direct children only, not the whole subtree).
public int ChildCount { get; set; }
///
/// Whether this node's children load lazily on expand. True for every container kind in the Raw tree
/// (Cluster/Folder/Driver/Device/TagGroup) — unlike the UNS tree, /raw actually exercises the
/// lazy plumbing (per-device tag counts can be large). Tags are leaves (false).
///
public bool HasLazyChildren { get; init; }
/// Lazily-materialised children — empty until flips on expand.
public List Children { get; } = new();
/// Optimistic-concurrency token for this node's backing row (empty for Enterprise); echoed on mutations.
public byte[] RowVersion { get; init; } = Array.Empty();
// --- Runtime UI state (not persisted) ---
/// Whether the node is currently expanded in the UI.
public bool Expanded { get; set; }
/// Whether the node's lazy children have been loaded.
public bool Loaded { get; set; }
/// Whether a lazy-load is currently in flight for this node.
public bool Loading { get; set; }
/// Last load error message, if any.
public string? Error { get; set; }
}