");
+
+ foreach (var entry in updates)
+ {
+ var path = entry.Path;
+ var pathEnc = System.Web.HttpUtility.HtmlEncode(path);
+ var displayEnc = System.Web.HttpUtility.HtmlEncode(Shorten(path, shortenPrefix));
+ var op = entry.Operation ?? "";
+
+ sb.Append("
");
+
+ // Column 1: path (truncates on narrow layouts)
+ sb.Append(
+ $"
{displayEnc}");
+
+ // Column 2: old version chip or "new" marker
+ if (entry.VersionBefore is { } vb)
+ sb.Append(
+ $"
v{vb}");
+ else if (op.Equals("Created", StringComparison.OrdinalIgnoreCase))
+ sb.Append("
new");
+ else
+ sb.Append("
");
+
+ // Column 3: arrow
+ sb.Append("
→");
+
+ // Column 4: new version chip or "deleted" marker
+ if (entry.VersionAfter is { } va)
+ sb.Append(
+ $"
v{va}");
+ else if (op.Equals("Deleted", StringComparison.OrdinalIgnoreCase))
+ sb.Append("
deleted");
+ else
+ sb.Append("
");
+
+ // Column 5: Diff (old ↔ new) — points to VersionDiff with from/to params.
+ if (entry.VersionBefore.HasValue && entry.VersionAfter.HasValue)
+ sb.Append(
+ $"
Diff");
+ else
+ sb.Append("
");
+
+ // Column 6: Restore to old — opens VersionDiff (which has the Restore button).
+ if (entry.VersionBefore.HasValue)
+ sb.Append(
+ $"
Restore v{entry.VersionBefore.Value}");
+ else
+ sb.Append("
");
+
+ // Column 7: Restore to new — opens VersionDiff (which has the Restore button).
+ if (entry.VersionAfter.HasValue)
+ sb.Append(
+ $"
Restore v{entry.VersionAfter.Value}");
+ else
+ sb.Append("
");
+
+ sb.Append("