namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared;
///
/// Rendering helpers for operator-facing text that comes out of the database.
///
///
///
/// Why this exists (#504). Several pages abbreviated a hash / thumbprint with the range
/// operator — @s.SourceHash[..12]… — which throws
/// the moment the value is shorter than the slice.
/// In Blazor that escapes BuildRenderTree unhandled and takes the whole page to an
/// HTTP 500, not just the offending row. Nothing enforces a minimum length at the schema, the
/// entity, or the render layer, so any hand-written / seeded / migrated row is a live page-kill.
/// The docker-dev seed proved it: its placeholder SourceHash values (h1,
/// h-abs-hr200) made /scripts a hard 500 on every stock bring-up.
///
///
/// Use for every such prefix. It never throws, and it appends the
/// ellipsis only when it actually truncated — a 2-character hash renders as h1, not
/// h1…, so the display never implies more text than exists.
///
///
public static class DisplayText
{
/// Placeholder rendered for a null / blank value. Matches the em-dash convention the
/// Admin UI already uses for "nothing to show" cells.
public const string Empty = "—";
///
/// The first characters of , followed by an
/// ellipsis when (and only when) characters were dropped.
///
/// The value to abbreviate. May be null, blank, or shorter than
/// — none of which throw.
/// Maximum number of characters to keep. Values below 1 are treated as 1,
/// so a caller cannot turn a display bug into a crash.
/// for a null/blank value; the value verbatim when it already fits;
/// otherwise the truncated prefix plus an ellipsis.
public static string Abbreviate(string? value, int maxLength)
{
if (string.IsNullOrWhiteSpace(value)) return Empty;
if (maxLength < 1) maxLength = 1;
return value.Length <= maxLength ? value : string.Concat(value.AsSpan(0, maxLength), "…");
}
}