From 249241dfd4d1330ff0c6ca7565eb6ea2ce5237f8 Mon Sep 17 00:00:00 2001 From: Nawaz Dhandala Date: Wed, 1 Apr 2026 15:07:20 +0100 Subject: [PATCH] feat: enhance UptimeBarTooltip with improved layout, color adjustments, and incident display; optimize status breakdown and tooltip styles --- .../UI/Components/Graphs/UptimeBarTooltip.tsx | 266 +++++++++--------- 1 file changed, 129 insertions(+), 137 deletions(-) diff --git a/Common/UI/Components/Graphs/UptimeBarTooltip.tsx b/Common/UI/Components/Graphs/UptimeBarTooltip.tsx index 0723aff047..0bfe4da8eb 100644 --- a/Common/UI/Components/Graphs/UptimeBarTooltip.tsx +++ b/Common/UI/Components/Graphs/UptimeBarTooltip.tsx @@ -30,24 +30,13 @@ const UptimeBarTooltip: FunctionComponent = ( // Color tiers const isGood: boolean = props.uptimePercent >= 99.9; const isWarn: boolean = !isGood && props.uptimePercent >= 99; + const uptimeColor: string = isGood ? "#059669" : isWarn ? "#d97706" : "#dc2626"; - const uptimeBg: string = isGood - ? "#ecfdf5" - : isWarn - ? "#fffbeb" - : "#fef2f2"; - - const uptimeTrack: string = isGood - ? "#d1fae5" - : isWarn - ? "#fef3c7" - : "#fecaca"; - // Sort: downtime first, then by duration desc const sortedDurations: Array = [ ...props.statusDurations, @@ -82,15 +71,33 @@ const UptimeBarTooltip: FunctionComponent = ( style={{ display: "flex", alignItems: "center", - justifyContent: "space-between", - marginBottom: "12px", + gap: "8px", + paddingBottom: "10px", + marginBottom: "10px", + borderBottom: "1px solid #f0f0f0", }} > + + + + + + @@ -98,21 +105,18 @@ const UptimeBarTooltip: FunctionComponent = ( - {/* ── Uptime meter ── */} + {/* ── Uptime ── */} {props.hasEvents && (
@@ -120,49 +124,50 @@ const UptimeBarTooltip: FunctionComponent = ( style={{ fontSize: "11px", color: "#6b7280", - fontWeight: 600, - textTransform: "uppercase", - letterSpacing: "0.05em", + fontWeight: 500, }} > Uptime - - {props.uptimePercent >= 100 - ? "100" - : props.uptimePercent.toFixed(2)} +
+ {props.uptimePercent >= 100 + ? "100" + : props.uptimePercent.toFixed(2)} + + % - +
- {/* Segmented bar showing all statuses proportionally */} + {/* Segmented bar */} {totalSeconds > 0 && sortedDurations.length > 1 ? (
{sortedDurations.map( @@ -179,12 +184,6 @@ const UptimeBarTooltip: FunctionComponent = ( width: `${widthPercent}%`, height: "100%", backgroundColor: status.color.toString(), - borderRadius: - index === 0 - ? "100px 0 0 100px" - : index === sortedDurations.length - 1 - ? "0 100px 100px 0" - : "0", }} /> ); @@ -195,8 +194,8 @@ const UptimeBarTooltip: FunctionComponent = (
= (
= (
-
- Status Breakdown -
{sortedDurations.map((status: StatusDuration, index: number) => { - const pct: string = + const pct: number = totalSeconds > 0 - ? ((status.seconds / totalSeconds) * 100).toFixed(1) - : "0"; + ? (status.seconds / totalSeconds) * 100 + : 0; return (
+ {/* Color dot + label */}
= ( fontSize: "12px", color: "#374151", fontWeight: 500, + whiteSpace: "nowrap", + overflow: "hidden", + textOverflow: "ellipsis", }} > {status.label} - - {pct}% -
+ {/* Mini bar */} +
+
+
+ {/* Duration */} = ( fontWeight: status.isDowntime ? 600 : 400, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap", - marginLeft: "12px", + flexShrink: 0, }} > {OneUptimeDate.secondsToFormattedFriendlyTimeString( @@ -347,7 +350,7 @@ const UptimeBarTooltip: FunctionComponent = ( {/* ── Incidents ── */} {hasIncidents && ( -
+
= ( marginBottom: "8px", }} > - {/* small warning triangle icon */} - - - @@ -381,7 +372,7 @@ const UptimeBarTooltip: FunctionComponent = ( = ( : undefined } style={{ - border: "1px solid #f3f4f6", - borderRadius: "8px", - padding: "7px 10px", - marginBottom: "5px", + borderLeft: `3px solid ${incident.incidentSeverity ? incident.incidentSeverity.color.toString() : "#dc2626"}`, + padding: "6px 10px", + marginBottom: "6px", cursor: isClickable ? "pointer" : "default", - transition: "all 0.12s ease", - backgroundColor: "#ffffff", + transition: "background-color 0.12s ease", + backgroundColor: "#fafafa", + borderRadius: "0 6px 6px 0", }} onMouseEnter={(e: React.MouseEvent) => { if (isClickable) { - const el: HTMLDivElement = - e.currentTarget as HTMLDivElement; - el.style.backgroundColor = "#f9fafb"; - el.style.borderColor = "#e5e7eb"; + (e.currentTarget as HTMLDivElement).style.backgroundColor = + "#f3f4f6"; } }} onMouseLeave={(e: React.MouseEvent) => { if (isClickable) { - const el: HTMLDivElement = - e.currentTarget as HTMLDivElement; - el.style.backgroundColor = "#ffffff"; - el.style.borderColor = "#f3f4f6"; + (e.currentTarget as HTMLDivElement).style.backgroundColor = + "#fafafa"; } }} > @@ -459,15 +446,15 @@ const UptimeBarTooltip: FunctionComponent = (
{isClickable && ( = ( )}
- {/* Meta row: badges */} + {/* Meta row: badges + time */}
= ( {incident.incidentSeverity && ( {incident.incidentSeverity.name} @@ -504,16 +493,18 @@ const UptimeBarTooltip: FunctionComponent = ( {incident.currentIncidentState && ( {incident.currentIncidentState.name} @@ -522,7 +513,7 @@ const UptimeBarTooltip: FunctionComponent = ( = ( fontSize: "11px", color: "#9ca3af", textAlign: "center", - padding: "3px 0 0", + padding: "4px 0 0", fontWeight: 500, }} > - +{props.incidents.length - 3} more + +{props.incidents.length - 3} more incident + {props.incidents.length - 3 !== 1 ? "s" : ""}
)}