Skip to content

Commit add1678

Browse files
jfillmanclaude
authored andcommitted
style(rollouts): use the shared Badge/health-tone system instead of ad-hoc classes and a parallel vocabulary
- Metric provider badge (AnalysisTemplate renderer) hand-wrote `badge-sm status-neutral` instead of the shared <Badge> component — everywhere else in a drawer body (not a table cell, where .status-* is the documented exception) uses it directly. - Arguments, AnalysisRun History, and ReplicaSets sections explicitly defaulted to collapsed with real, non-empty, non-low-priority content — every other populated section on the same pages already relies on Section's own default (expanded). Pod Template stays collapsed deliberately — it's not part of this fix; the same raw pod-spec dump already collapses by default in the generic WorkloadRenderer, a pre-existing, intentional convention. - CanaryStepTimeline's step-analysis dot/badge used a hand-rolled 'ok'/'warning'/'fail' vocabulary with hardcoded red/amber Tailwind backgrounds, duplicating (and requiring hand-translation back to) the canonical HealthLevel tones the badge already used one line away. Switched to HealthLevel + the shared healthColors token map throughout — same visual states (a failed/inconclusive analysis on the current step still gets its own color; a successful one doesn't change the dot, matching the original behavior exactly), no parallel vocabulary or raw colors left. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 04f8a93 commit add1678

2 files changed

Lines changed: 26 additions & 23 deletions

File tree

‎packages/k8s-ui/src/components/resources/renderers/AnalysisTemplateRenderer.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Activity, Server } from 'lucide-react'
22
import { Section, PropertyList, Property } from '../../ui/drawer-components'
3+
import { Badge } from '../../ui/Badge'
34

45
interface AnalysisTemplateRendererProps {
56
data: any
@@ -101,7 +102,7 @@ export function AnalysisTemplateRenderer({ data }: AnalysisTemplateRendererProps
101102
<div key={metric.name} className="card-inner space-y-1.5">
102103
<div className="flex items-center justify-between gap-2">
103104
<span className="font-mono text-sm text-theme-text-primary">{metric.name}</span>
104-
{provider && <span className="badge-sm status-neutral">{providerLabel(provider.name)}</span>}
105+
{provider && <Badge severity="neutral" size="sm">{providerLabel(provider.name)}</Badge>}
105106
</div>
106107
<PropertyList>
107108
{metric.interval && <Property label="Interval" value={metric.interval} />}
@@ -128,7 +129,7 @@ export function AnalysisTemplateRenderer({ data }: AnalysisTemplateRendererProps
128129
)}
129130

130131
{args.length > 0 && (
131-
<Section title={`Arguments (${args.length})`} icon={Server} defaultExpanded={false}>
132+
<Section title={`Arguments (${args.length})`} icon={Server}>
132133
<PropertyList>
133134
{args.map((arg: any) => (
134135
<Property

‎packages/k8s-ui/src/components/resources/renderers/rollout/CanaryStepTimeline.tsx‎

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Check, X, AlertTriangle, Minus, Clock } from 'lucide-react'
22
import { clsx } from 'clsx'
33
import { canaryStepLabel, canaryStepTemplateRefs } from '../RolloutRenderer'
4+
import { healthColors, type HealthLevel } from '../../resource-utils'
45

56
export interface StepAnalysisStatus {
67
name?: string
@@ -21,26 +22,32 @@ interface CanaryStepTimelineProps {
2122

2223
type StepState = 'completed' | 'current' | 'pending'
2324

24-
function stepDotTone(state: StepState, analysisTone?: 'ok' | 'warning' | 'fail') {
25-
if (state === 'current' && analysisTone) {
26-
if (analysisTone === 'fail') return 'bg-red-500/25 text-red-500 dark:bg-red-500/35'
27-
if (analysisTone === 'warning') return 'bg-amber-500/25 text-amber-600 dark:text-amber-400 dark:bg-amber-500/35'
25+
// analysisLevel only ever arrives as 'unhealthy' (Failed/Error) or 'alert'
26+
// (Inconclusive) — a Successful analysis on the current step deliberately
27+
// gets no special color; the step itself may still be paused/in-progress
28+
// regardless, so it stays the same "current" tone as any other in-progress
29+
// step rather than reading as done. Reuses the shared HealthLevel/
30+
// healthColors vocabulary + theme tokens instead of a parallel ok/warning/
31+
// fail set and hand-picked Tailwind colors.
32+
function stepDotTone(state: StepState, analysisLevel?: HealthLevel) {
33+
if (state === 'current' && (analysisLevel === 'unhealthy' || analysisLevel === 'alert')) {
34+
return healthColors[analysisLevel]
2835
}
2936
switch (state) {
3037
case 'completed':
31-
return 'bg-emerald-500/20 text-emerald-500 dark:bg-emerald-500/30'
38+
return healthColors.healthy
3239
case 'current':
33-
return 'bg-blue-500/20 text-blue-400 dark:bg-blue-500/30'
40+
return healthColors.neutral
3441
default:
3542
return 'bg-theme-hover text-theme-text-tertiary'
3643
}
3744
}
3845

39-
function StepDot({ state, analysisTone }: { state: StepState; analysisTone?: 'ok' | 'warning' | 'fail' }) {
40-
const tone = stepDotTone(state, analysisTone)
46+
function StepDot({ state, analysisLevel }: { state: StepState; analysisLevel?: HealthLevel }) {
47+
const tone = stepDotTone(state, analysisLevel)
4148
let Icon = Minus
42-
if (state === 'current' && analysisTone === 'fail') Icon = X
43-
else if (state === 'current' && analysisTone === 'warning') Icon = AlertTriangle
49+
if (state === 'current' && analysisLevel === 'unhealthy') Icon = X
50+
else if (state === 'current' && analysisLevel === 'alert') Icon = AlertTriangle
4451
else if (state === 'completed') Icon = Check
4552
else if (state === 'current') Icon = Clock
4653
return (
@@ -67,32 +74,27 @@ export function CanaryStepTimeline({ steps, currentStepIndex, stepAnalysisStatus
6774
const label = canaryStepLabel(step)
6875
const templateRefs = step.analysis ? canaryStepTemplateRefs(step) : []
6976
const showAnalysisStatus = isCurrent && step.analysis && stepAnalysisStatus?.status
70-
const analysisTone: 'ok' | 'warning' | 'fail' | undefined = showAnalysisStatus
77+
const analysisLevel: HealthLevel | undefined = showAnalysisStatus
7178
? stepAnalysisStatus!.status === 'Successful'
72-
? 'ok'
79+
? 'healthy'
7380
: stepAnalysisStatus!.status === 'Failed' || stepAnalysisStatus!.status === 'Error'
74-
? 'fail'
81+
? 'unhealthy'
7582
: stepAnalysisStatus!.status === 'Inconclusive'
76-
? 'warning'
83+
? 'alert'
7784
: undefined
7885
: undefined
7986

8087
return (
8188
<div key={index} className="relative flex items-start gap-2 py-1.5 pr-1 text-sm">
82-
<StepDot state={state} analysisTone={analysisTone} />
89+
<StepDot state={state} analysisLevel={analysisLevel} />
8390
<div className="min-w-0 flex-1 pl-1">
8491
<div className="flex items-center gap-2">
8592
<span className="text-[11px] text-theme-text-tertiary">#{index}</span>
8693
<span className={clsx(isCurrent ? 'font-medium text-theme-text-primary' : state === 'completed' ? 'text-theme-text-secondary' : 'text-theme-text-tertiary')}>
8794
{label}
8895
</span>
8996
{showAnalysisStatus && (
90-
<span
91-
className={clsx(
92-
'badge-sm',
93-
analysisTone === 'ok' ? 'status-healthy' : analysisTone === 'fail' ? 'status-unhealthy' : 'status-alert'
94-
)}
95-
>
97+
<span className={clsx('badge-sm', healthColors[analysisLevel ?? 'alert'])}>
9698
{stepAnalysisStatus!.status}
9799
</span>
98100
)}

0 commit comments

Comments
 (0)