From d8b3a0337596e021d0595f1fd6395f178f517293 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:41:04 -0700 Subject: [PATCH] fix(skills): place the status glyph left of the skill name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback on the row header: the badge belongs immediately right of the name so it reads as part of it, and the run's status circle/check belongs to the left of the name rather than sharing the badge's slot on the far right. Name, glyph and badge are now one left-aligned group; the location count and chevron stay right-aligned. `available` still has no leading glyph — an empty reserved box only indents the name past a gap with nothing in it. --- .../src/components/skills/SkillUpdateRow.tsx | 68 +++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/renderer/src/components/skills/SkillUpdateRow.tsx b/src/renderer/src/components/skills/SkillUpdateRow.tsx index 84d7c76af67..6b5a77382e0 100644 --- a/src/renderer/src/components/skills/SkillUpdateRow.tsx +++ b/src/renderer/src/components/skills/SkillUpdateRow.tsx @@ -1,4 +1,4 @@ -import { CheckCircle2, ChevronDown, Circle, XCircle } from 'lucide-react' +import { AlertTriangle, CheckCircle2, ChevronDown, Circle, XCircle } from 'lucide-react' import type { SkillFreshnessGroupModel } from './skill-freshness-grouping' import { translate } from '@/i18n/i18n' import { Badge } from '@/components/ui/badge' @@ -10,14 +10,10 @@ import { skippedReason } from './skill-freshness-skipped-reason' export type SkillRowState = 'available' | 'blocked' | 'pending' | 'done' | 'failed' /** - * The single status slot, sitting between the name and the location count. - * - * Why one slot rather than a leading icon column: a leading icon has nothing to - * show in the resting state, and reserving the box for it just indents every - * name past an empty gap. Swapping badge for icon in place keeps the name - * flush-left and the row's right edge fixed in every state. + * Leading status glyph. Absent for `available` on purpose: an empty reserved box + * would just indent the name past a gap with nothing in it. */ -function StateSlot({ state }: { state: SkillRowState }): React.JSX.Element { +function StateIcon({ state }: { state: SkillRowState }): React.JSX.Element | null { switch (state) { case 'done': return @@ -26,31 +22,44 @@ function StateSlot({ state }: { state: SkillRowState }): React.JSX.Element { case 'pending': return case 'blocked': - return ( - - {translate('auto.components.skills.SkillFreshnessRow.statusCantUpdate', 'Skipped')} - - ) + return case 'available': - return ( - - {translate( - 'auto.components.skills.SkillFreshnessRow.statusUpdateAvailable', - 'Update available' - )} - - ) + return null } } +/** Sits immediately right of the name, so the label reads as part of it. */ +function StateBadge({ state }: { state: SkillRowState }): React.JSX.Element | null { + if (state === 'blocked') { + return ( + + {translate('auto.components.skills.SkillFreshnessRow.statusCantUpdate', 'Skipped')} + + ) + } + if (state === 'available') { + return ( + + {translate( + 'auto.components.skills.SkillFreshnessRow.statusUpdateAvailable', + 'Update available' + )} + + ) + } + // Why: once a run owns the row the leading glyph carries the state. A stale + // "Update available" beside a green check would contradict it. + return null +} + /** * One skill in the update dialog, used unchanged in every state. * * The header keeps identical geometry from "update available" through running to - * the result — only the status slot's contents change — so pressing Update + * the result — the row keeps its place and its right edge — so pressing Update * doesn't replace the dialog's layout with a different one. Locations live * behind a per-skill disclosure instead of being dumped inline, because a skill * with several plugin-cache copies otherwise buries the actions. @@ -76,10 +85,13 @@ export function SkillUpdateRow({ state === 'pending' ? 'opacity-60' : '' }`} > - - {group.name} + + + + {group.name} + + - {locationCount === 1 ? translate('auto.components.skills.SkillUpdateRow.oneLocation', '1 location')