diff --git a/DomainDetective.Toolbox/Components/Shared/ResultTable.razor b/DomainDetective.Toolbox/Components/Shared/ResultTable.razor index 92cf7c490..0de1a2b84 100644 --- a/DomainDetective.Toolbox/Components/Shared/ResultTable.razor +++ b/DomainDetective.Toolbox/Components/Shared/ResultTable.razor @@ -1,15 +1,17 @@ - - - - @foreach (var col in Columns) { - - } - - - - @ChildContent - -
@col
+
+ + + + @foreach (var col in Columns) { + + } + + + + @ChildContent + +
@col
+
@code { [Parameter] public string[] Columns { get; set; } = Array.Empty(); diff --git a/DomainDetective.Toolbox/Components/Tools/Dns/DnsPropagationTool.razor b/DomainDetective.Toolbox/Components/Tools/Dns/DnsPropagationTool.razor index 68d6db861..365f87382 100644 --- a/DomainDetective.Toolbox/Components/Tools/Dns/DnsPropagationTool.razor +++ b/DomainDetective.Toolbox/Components/Tools/Dns/DnsPropagationTool.razor @@ -78,7 +78,16 @@ - Majority answer set@FormatAnswerSet(item.MajorityAnswerSet) + + Majority answer set + +
+ @foreach (var value in GetAnswerSetEntries(item.MajorityAnswerSet)) { + @value + } +
+ + Average response time@FormatDuration(item.AvgDuration) Fastest response@FormatDuration(item.MinDuration) Slowest response@FormatDuration(item.MaxDuration) @@ -89,7 +98,13 @@ @foreach (var answerSet in answerSets) { - @answerSet.Label + +
+ @foreach (var value in GetAnswerSetEntries(answerSet.Key)) { + @value + } +
+ @answerSet.Count @(answerSet.IsMajority ? "Majority" : "Observed") @@ -98,7 +113,7 @@ }
- +
@@ -120,7 +135,13 @@ @(result.Success ? "Seen" : "Unavailable") - + } @@ -214,7 +235,7 @@ .GroupBy(static result => NormalizeAnswerSet(result.Records), StringComparer.OrdinalIgnoreCase) .Select(group => new DnsPropagationAnswerSetInfo { Key = group.Key, - Label = FormatAnswerSet(group.Key), + Label = string.Join(" | ", GetAnswerSetEntries(group.Key)), Count = group.Count(), IsMajority = string.Equals(group.Key, item.MajorityAnswerSet ?? string.Empty, StringComparison.OrdinalIgnoreCase) }) @@ -246,9 +267,9 @@ return values.Length > 0 ? string.Join(", ", values) : "(no answer)"; } - private static string FormatAnswerSet(string? value) { + private static IReadOnlyList GetAnswerSetEntries(string? value) { if (string.IsNullOrWhiteSpace(value) || string.Equals(value, "(no answer)", StringComparison.OrdinalIgnoreCase)) { - return "No majority answer set"; + return new[] { "No majority answer set" }; } var entries = value @@ -257,7 +278,7 @@ .Where(static item => item.Length > 0) .ToArray(); - return entries.Length > 0 ? string.Join(", ", entries) : "No majority answer set"; + return entries.Length > 0 ? entries : new[] { "No majority answer set" }; } private static string FormatBool(bool value) { @@ -309,9 +330,9 @@ return !string.IsNullOrWhiteSpace(result.Asn) ? result.Asn : "Unknown"; } - private static string FormatRecords(IEnumerable records) { + private static IReadOnlyList GetRecordEntries(IEnumerable records) { var values = records?.Where(static value => !string.IsNullOrWhiteSpace(value)).ToArray() ?? Array.Empty(); - return values.Length > 0 ? string.Join(", ", values) : "No answer"; + return values.Length > 0 ? values : new[] { "No answer" }; } private static string FormatResolver(DnsPropagationResultInfo result) { diff --git a/DomainDetective.Toolbox/Components/Tools/TlsCert/DaneTool.razor b/DomainDetective.Toolbox/Components/Tools/TlsCert/DaneTool.razor index f0d3025c6..5c3ed9f47 100644 --- a/DomainDetective.Toolbox/Components/Tools/TlsCert/DaneTool.razor +++ b/DomainDetective.Toolbox/Components/Tools/TlsCert/DaneTool.razor @@ -100,7 +100,7 @@ @if (records.Count > 0) {
-
Resolver @FormatRecords(result.Records) +
+ @foreach (var value in GetRecordEntries(result.Records)) { + @value + } +
+
@FormatDuration(result.Duration)
+
diff --git a/DomainDetective.Website/wwwroot/css/app.css b/DomainDetective.Website/wwwroot/css/app.css index 95f3e01ab..07294c3c8 100644 --- a/DomainDetective.Website/wwwroot/css/app.css +++ b/DomainDetective.Website/wwwroot/css/app.css @@ -1224,19 +1224,36 @@ a:hover { color: var(--dd-accent-light); } /* ── Result Tables ──────────────────────────────────────────────── */ +.result-table-wrap, +.tool-data-table-wrap { + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + .result-table { width: 100%; + min-width: 0; border-collapse: collapse; + table-layout: fixed; position: relative; } .result-table th, .result-table td { padding: 0.625rem 0.75rem; text-align: left; + vertical-align: top; border-bottom: 1px solid var(--dd-border); font-size: 0.9rem; + white-space: normal; + word-break: break-word; + overflow-wrap: anywhere; transition: background 0.15s ease; } +.result-table th:first-child, +.result-table td:first-child { + width: 32%; +} .result-table th { color: var(--dd-accent); font-weight: 600; @@ -1271,6 +1288,146 @@ a:hover { color: var(--dd-accent-light); } background: rgba(15, 143, 176, 0.055); } +.tool-data-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; +} + +.tool-data-table th, +.tool-data-table td { + padding: 0.75rem 1rem; + text-align: left; + vertical-align: top; + border-bottom: 1px solid var(--dd-border); + white-space: normal; + word-break: break-word; + overflow-wrap: anywhere; +} + +.tool-data-table th { + color: var(--dd-accent); + font-size: 0.8rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + background: linear-gradient(135deg, rgba(0, 217, 255, 0.08), rgba(139, 92, 246, 0.05)); + border-bottom: 1px solid rgba(0, 217, 255, 0.15); +} + +.tool-data-table td { + color: var(--dd-ink); + font-size: 0.95rem; +} + +.tool-value-stack { + display: grid; + gap: 0.35rem; +} + +.tool-value-stack code { + display: block; + width: fit-content; + max-width: 100%; + padding: 0.2rem 0.45rem; + border-radius: 0.5rem; + background: rgba(15, 23, 42, 0.45); + color: var(--dd-ink-strong); + font-family: var(--dd-font-mono); + font-size: 0.85rem; + white-space: normal; + word-break: break-word; + overflow-wrap: anywhere; +} + +.tool-data-table tbody tr:nth-child(even) td { + background: linear-gradient(90deg, rgba(13, 21, 48, 0.3), rgba(13, 21, 48, 0.15)); +} + +.tool-data-table tbody tr:hover td { + background: rgba(0, 217, 255, 0.05); +} + +.tool-data-table tr:last-child td { + border-bottom: none; +} + +.tool-data-table-dns { + min-width: 56rem; +} + +.tool-data-table-dns th:nth-child(1), +.tool-data-table-dns td:nth-child(1) { + width: 20%; +} + +.tool-data-table-dns th:nth-child(2), +.tool-data-table-dns td:nth-child(2) { + width: 14%; +} + +.tool-data-table-dns th:nth-child(3), +.tool-data-table-dns td:nth-child(3) { + width: 12%; +} + +.tool-data-table-dns th:nth-child(4), +.tool-data-table-dns td:nth-child(4) { + width: 10%; +} + +.tool-data-table-dns th:nth-child(5), +.tool-data-table-dns td:nth-child(5) { + width: 34%; +} + +.tool-data-table-dns th:nth-child(6), +.tool-data-table-dns td:nth-child(6) { + width: 10%; +} + +.tool-data-table-dane { + min-width: 60rem; +} + +.tool-data-table-dane th:nth-child(1), +.tool-data-table-dane td:nth-child(1) { + width: 18rem; +} + +.tool-data-table-dane th:nth-child(2), +.tool-data-table-dane td:nth-child(2), +.tool-data-table-dane th:nth-child(3), +.tool-data-table-dane td:nth-child(3), +.tool-data-table-dane th:nth-child(4), +.tool-data-table-dane td:nth-child(4), +.tool-data-table-dane th:nth-child(5), +.tool-data-table-dane td:nth-child(5) { + width: 6rem; +} + +.tool-data-table-dane th:nth-child(7), +.tool-data-table-dane td:nth-child(7) { + width: 8rem; +} + +[data-theme="light"] .tool-data-table th { + background: linear-gradient(135deg, rgba(15, 143, 176, 0.1), rgba(59, 130, 246, 0.08)); + border-bottom-color: rgba(15, 143, 176, 0.16); +} + +[data-theme="light"] .tool-data-table tbody tr:nth-child(even) td { + background: linear-gradient(90deg, rgba(15, 23, 42, 0.025), rgba(59, 130, 246, 0.03)); +} + +[data-theme="light"] .tool-data-table tbody tr:hover td { + background: rgba(15, 143, 176, 0.055); +} + +[data-theme="light"] .tool-value-stack code { + background: rgba(226, 232, 240, 0.65); +} + .result-record { background: var(--dd-code-bg); border: 1px solid var(--dd-border); @@ -2560,6 +2717,12 @@ a:hover { color: var(--dd-accent-light); } } .tool-breadcrumb { font-size: 0.8rem; padding: 0.375rem 0.5rem; } .result-card { padding: 1rem; } + .result-table th, + .result-table td, + .tool-data-table th, + .tool-data-table td { + padding: 0.625rem 0.75rem; + } .category-card:hover { transform: translateY(-2px); } }
Name