| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| export function formatTime(isoString) { |
| try { |
| const d = new Date(isoString); |
| return d.toLocaleTimeString("en-US", { |
| hour12: false, |
| hour: "2-digit", |
| minute: "2-digit", |
| second: "2-digit", |
| }); |
| } catch { |
| return "-"; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| export function formatDuration(ms) { |
| if (!ms) return "-"; |
| if (ms < 1000) return `${ms}ms`; |
| return `${(ms / 1000).toFixed(1)}s`; |
| } |
|
|
| |
| |
| |
| |
| |
| export function formatDateTime(iso) { |
| try { |
| const d = new Date(iso); |
| return d.toLocaleDateString("pt-BR") + ", " + d.toLocaleTimeString("en-US", { hour12: false }); |
| } catch { |
| return iso; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function maskSegment(value, start = 2, end = 2) { |
| if (!value) return ""; |
| if (value.length <= start + end) return `${value.slice(0, 1)}***`; |
| return `${value.slice(0, start)}***${value.slice(-end)}`; |
| } |
|
|
| |
| |
| |
| |
| |
| export function maskAccount(account) { |
| if (!account || account === "-") return "-"; |
| const atIdx = account.indexOf("@"); |
| if (atIdx > 3) { |
| return account.slice(0, 3) + "***" + account.slice(atIdx); |
| } |
| if (account.length > 8) { |
| return account.slice(0, 5) + "***"; |
| } |
| return account; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function formatApiKeyLabel(apiKeyName, apiKeyId) { |
| if (!apiKeyName && !apiKeyId) return "—"; |
| const maskedName = apiKeyName ? maskSegment(apiKeyName, 2, 1) : "key"; |
| if (!apiKeyId) return maskedName; |
| return `${maskedName} (${maskSegment(apiKeyId, 4, 4)})`; |
| } |
|
|
| |
| |
| |
| |
| |
| export function maskKey(key) { |
| if (!key || key.length < 8) return "***"; |
| return `${key.slice(0, 4)}...${key.slice(-4)}`; |
| } |
|
|
| |
| |
| |
| |
| |
| export function fmtCompact(n) { |
| if (n >= 1_000_000_000) return `${(n / 1_000_000_000).toFixed(1)}B`; |
| if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`; |
| if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`; |
| return new Intl.NumberFormat().format(n || 0); |
| } |
|
|
| |
| |
| |
| |
| |
| export function fmtFull(n) { |
| return new Intl.NumberFormat().format(n || 0); |
| } |
|
|
| |
| |
| |
| |
| |
| export function fmtCost(n) { |
| return `$${(n || 0).toFixed(2)}`; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function truncateUrl(url, max = 50) { |
| if (!url) return "-"; |
| try { |
| const parsed = new URL(url); |
| const display = parsed.hostname + parsed.pathname; |
| return display.length > max ? display.slice(0, max) + "…" : display; |
| } catch { |
| return url.length > max ? url.slice(0, max) + "…" : url; |
| } |
| } |
|
|