From 795c16755bc70181e5736381b1339751859e81b3 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 23 Apr 2026 15:57:03 +0100 Subject: [PATCH] Normalize alert and status presentation palette --- .../Alerts/AlertResourceTableRow.tsx | 2 +- .../Alerts/InvestigateAlertButton.tsx | 32 +++++++++---------- .../patrol/InvestigationMessages.tsx | 4 +-- .../src/components/patrol/RunHistoryEntry.tsx | 2 +- .../alertHistoryPresentation.test.ts | 2 +- .../__tests__/alertTabsPresentation.test.ts | 2 +- .../dashboardKpiPresentation.test.ts | 2 +- .../src/utils/__tests__/orgUtils.test.ts | 4 +-- .../recoveryArtifactModePresentation.test.ts | 4 +-- .../recoveryFilterChipPresentation.test.ts | 4 +-- .../src/utils/alertHistoryPresentation.ts | 2 +- .../src/utils/alertTabsPresentation.ts | 2 +- .../src/utils/dashboardKpiPresentation.ts | 4 +-- frontend-modern/src/utils/orgUtils.ts | 2 +- .../utils/recoveryArtifactModePresentation.ts | 4 +-- .../utils/recoveryFilterChipPresentation.ts | 8 ++--- .../src/utils/resourceChangePresentation.ts | 4 +-- .../src/utils/resourcePolicyPresentation.ts | 2 +- .../src/utils/sourceTypePresentation.ts | 2 +- frontend-modern/src/utils/storageSources.ts | 4 +-- 20 files changed, 45 insertions(+), 47 deletions(-) diff --git a/frontend-modern/src/components/Alerts/AlertResourceTableRow.tsx b/frontend-modern/src/components/Alerts/AlertResourceTableRow.tsx index 83c1b45f3..248e2243b 100644 --- a/frontend-modern/src/components/Alerts/AlertResourceTableRow.tsx +++ b/frontend-modern/src/components/Alerts/AlertResourceTableRow.tsx @@ -287,7 +287,7 @@ export function AlertResourceTableRow(props: AlertResourceTableRowProps) { - + {props.resource.node} diff --git a/frontend-modern/src/components/Alerts/InvestigateAlertButton.tsx b/frontend-modern/src/components/Alerts/InvestigateAlertButton.tsx index 8d04fc65f..b006e88d6 100644 --- a/frontend-modern/src/components/Alerts/InvestigateAlertButton.tsx +++ b/frontend-modern/src/components/Alerts/InvestigateAlertButton.tsx @@ -114,13 +114,12 @@ Please: onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} class={`${baseButtonClass} ${sizeClasses[props.size || 'sm']} - bg-purple-100 dark:bg-purple-950 - hover:bg-purple-900 - text-purple-600 dark:text-purple-400 - hover:text-purple-700 dark:hover:text-purple-300 - border border-purple-200 dark:border-purple-700 - hover:border-purple-300 dark:hover:border-purple-600 - ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-purple-100 dark:hover:bg-purple-950' : ''} + bg-surface + hover:bg-surface-hover + text-blue-600 dark:text-blue-400 + hover:text-blue-700 dark:hover:text-blue-300 + border border-border + ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-surface' : ''} ${props.class || ''}`} title={ isLocked() @@ -155,14 +154,13 @@ Please: onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} class={`${baseButtonClass} px-2 py-1 - bg-purple-100 dark:bg-purple-950 - hover:bg-purple-900 - text-purple-600 dark:text-purple-400 - hover:text-purple-700 dark:hover:text-purple-300 - border border-purple-200 dark:border-purple-700 - hover:border-purple-300 dark:hover:border-purple-600 + bg-surface + hover:bg-surface-hover + text-blue-600 dark:text-blue-400 + hover:text-blue-700 dark:hover:text-blue-300 + border border-border gap-1.5 - ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-purple-100 dark:hover:bg-purple-950' : ''} + ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-surface' : ''} ${props.class || ''}`} title={ isLocked() @@ -192,12 +190,12 @@ Please: onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} class={`${baseButtonClass} px-3 py-1.5 - bg-purple-500 - hover:bg-purple-600 + bg-blue-600 + hover:bg-blue-700 text-white font-medium shadow-sm hover:shadow-sm gap-2 - ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-purple-500' : ''} + ${isLocked() ? 'opacity-60 cursor-not-allowed hover:bg-blue-600' : ''} ${props.class || ''}`} title={ isLocked() diff --git a/frontend-modern/src/components/patrol/InvestigationMessages.tsx b/frontend-modern/src/components/patrol/InvestigationMessages.tsx index d9e75c851..f4ecc5792 100644 --- a/frontend-modern/src/components/patrol/InvestigationMessages.tsx +++ b/frontend-modern/src/components/patrol/InvestigationMessages.tsx @@ -66,10 +66,10 @@ export const InvestigationMessages: Component = (pro {/* Reasoning content (extended thinking) */}
- + Show reasoning -
+
{msg.reasoning_content}
diff --git a/frontend-modern/src/components/patrol/RunHistoryEntry.tsx b/frontend-modern/src/components/patrol/RunHistoryEntry.tsx index c47505e11..c37b106de 100644 --- a/frontend-modern/src/components/patrol/RunHistoryEntry.tsx +++ b/frontend-modern/src/components/patrol/RunHistoryEntry.tsx @@ -285,7 +285,7 @@ export function RunHistoryEntry(props: RunHistoryEntryProps) {
0}> - + {run.guests_checked} VM {run.guests_checked !== 1 ? 's' : ''} diff --git a/frontend-modern/src/utils/__tests__/alertHistoryPresentation.test.ts b/frontend-modern/src/utils/__tests__/alertHistoryPresentation.test.ts index 81c4ac9cd..a65a3415c 100644 --- a/frontend-modern/src/utils/__tests__/alertHistoryPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/alertHistoryPresentation.test.ts @@ -9,7 +9,7 @@ describe('alertHistoryPresentation', () => { expect(getAlertHistorySourcePresentation('ai')).toEqual({ label: 'Patrol', className: - 'text-[10px] px-1.5 py-0.5 rounded font-medium bg-violet-100 dark:bg-violet-900 text-violet-700 dark:text-violet-300', + 'text-[10px] px-1.5 py-0.5 rounded font-medium bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300', }); expect(getAlertHistorySourcePresentation('alert')).toEqual({ diff --git a/frontend-modern/src/utils/__tests__/alertTabsPresentation.test.ts b/frontend-modern/src/utils/__tests__/alertTabsPresentation.test.ts index 5b2a7ec89..48b7ed323 100644 --- a/frontend-modern/src/utils/__tests__/alertTabsPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/alertTabsPresentation.test.ts @@ -23,7 +23,7 @@ describe('alertTabsPresentation', () => { it('returns disabled mobile presentation', () => { expect(getAlertsMobileTabClass({ isActive: false, isDisabled: true })).toBe( - 'flex-1 min-w-0 rounded-md px-2 py-1.5 text-[11px] font-medium transition-all sm:px-4 sm:py-2 sm:text-xs cursor-not-allowed bg-surface-alt text-muted', + 'flex-shrink-0 whitespace-nowrap rounded-md px-3 py-1.5 text-[11px] font-medium transition-all sm:flex-1 sm:min-w-0 sm:px-4 sm:py-2 sm:text-xs cursor-not-allowed bg-surface-alt text-muted', ); }); diff --git a/frontend-modern/src/utils/__tests__/dashboardKpiPresentation.test.ts b/frontend-modern/src/utils/__tests__/dashboardKpiPresentation.test.ts index fbc567a6f..b48a538ab 100644 --- a/frontend-modern/src/utils/__tests__/dashboardKpiPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/dashboardKpiPresentation.test.ts @@ -22,7 +22,7 @@ describe('dashboardKpiPresentation', () => { expect(getDashboardKpiPresentation('infrastructure').cardClassName).toContain( 'border-l-blue-500', ); - expect(getDashboardKpiPresentation('workloads').iconClassName).toContain('violet'); + expect(getDashboardKpiPresentation('workloads').iconClassName).toContain('rose'); expect(getDashboardKpiPresentation('storage').iconClassName).toContain('cyan'); expect(getDashboardKpiPresentation('alerts').cardClassName).toContain('border-l-amber-500'); }); diff --git a/frontend-modern/src/utils/__tests__/orgUtils.test.ts b/frontend-modern/src/utils/__tests__/orgUtils.test.ts index 0e358fe20..63b3b0ffc 100644 --- a/frontend-modern/src/utils/__tests__/orgUtils.test.ts +++ b/frontend-modern/src/utils/__tests__/orgUtils.test.ts @@ -97,8 +97,8 @@ describe('canManageOrg', () => { describe('roleBadgeClass', () => { it('returns owner badge class', () => { const result = roleBadgeClass('owner'); - expect(result).toContain('bg-purple-100'); - expect(result).toContain('text-purple-800'); + expect(result).toContain('bg-amber-100'); + expect(result).toContain('text-amber-800'); }); it('returns admin badge class', () => { diff --git a/frontend-modern/src/utils/__tests__/recoveryArtifactModePresentation.test.ts b/frontend-modern/src/utils/__tests__/recoveryArtifactModePresentation.test.ts index 99ba1d9cc..d67bb6bb5 100644 --- a/frontend-modern/src/utils/__tests__/recoveryArtifactModePresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/recoveryArtifactModePresentation.test.ts @@ -18,8 +18,8 @@ describe('recoveryArtifactModePresentation', () => { expect(getRecoveryArtifactModePresentation('remote')).toEqual({ label: 'Remote Copy', aggregateLabel: 'Remote Copies', - badgeClassName: 'bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-300', - segmentClassName: 'bg-violet-500', + badgeClassName: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900 dark:text-indigo-300', + segmentClassName: 'bg-indigo-500', }); }); }); diff --git a/frontend-modern/src/utils/__tests__/recoveryFilterChipPresentation.test.ts b/frontend-modern/src/utils/__tests__/recoveryFilterChipPresentation.test.ts index 2ba216b4b..65ed52c6e 100644 --- a/frontend-modern/src/utils/__tests__/recoveryFilterChipPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/recoveryFilterChipPresentation.test.ts @@ -14,9 +14,9 @@ describe('getRecoveryFilterChipPresentation', () => { it('returns the canonical namespace chip presentation', () => { expect(getRecoveryFilterChipPresentation('namespace')).toMatchObject({ clearButtonClass: - 'rounded px-1 py-0.5 text-[10px] hover:bg-violet-100 dark:hover:bg-violet-900', + 'rounded px-1 py-0.5 text-[10px] hover:bg-indigo-100 dark:hover:bg-indigo-900', label: 'Namespace / Group', }); - expect(getRecoveryFilterChipPresentation('namespace').className).toContain('border-violet-200'); + expect(getRecoveryFilterChipPresentation('namespace').className).toContain('border-indigo-200'); }); }); diff --git a/frontend-modern/src/utils/alertHistoryPresentation.ts b/frontend-modern/src/utils/alertHistoryPresentation.ts index 2f2c5b3f7..de0e33cea 100644 --- a/frontend-modern/src/utils/alertHistoryPresentation.ts +++ b/frontend-modern/src/utils/alertHistoryPresentation.ts @@ -9,7 +9,7 @@ export function getAlertHistorySourcePresentation(source?: string | null): Alert return { label: 'Patrol', className: - 'text-[10px] px-1.5 py-0.5 rounded font-medium bg-violet-100 dark:bg-violet-900 text-violet-700 dark:text-violet-300', + 'text-[10px] px-1.5 py-0.5 rounded font-medium bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300', }; } diff --git a/frontend-modern/src/utils/alertTabsPresentation.ts b/frontend-modern/src/utils/alertTabsPresentation.ts index 8b0b6c6c4..98f216f1d 100644 --- a/frontend-modern/src/utils/alertTabsPresentation.ts +++ b/frontend-modern/src/utils/alertTabsPresentation.ts @@ -80,7 +80,7 @@ export function getAlertsMobileTabClass({ : isActive ? 'bg-surface text-base-content shadow-sm' : 'text-muted hover:text-base-content'; - return `flex-1 min-w-0 rounded-md px-2 py-1.5 text-[11px] font-medium transition-all sm:px-4 sm:py-2 sm:text-xs ${tone}`; + return `flex-shrink-0 whitespace-nowrap rounded-md px-3 py-1.5 text-[11px] font-medium transition-all sm:flex-1 sm:min-w-0 sm:px-4 sm:py-2 sm:text-xs ${tone}`; } export function getAlertsTabTitle({ diff --git a/frontend-modern/src/utils/dashboardKpiPresentation.ts b/frontend-modern/src/utils/dashboardKpiPresentation.ts index 877cd3e7e..793067c8b 100644 --- a/frontend-modern/src/utils/dashboardKpiPresentation.ts +++ b/frontend-modern/src/utils/dashboardKpiPresentation.ts @@ -26,8 +26,8 @@ const DASHBOARD_KPI_PRESENTATION: Record = { - owner: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200', + owner: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200', admin: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200', editor: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200', viewer: defaultBadgeClass, diff --git a/frontend-modern/src/utils/recoveryArtifactModePresentation.ts b/frontend-modern/src/utils/recoveryArtifactModePresentation.ts index 59ffa3a58..c24a36b04 100644 --- a/frontend-modern/src/utils/recoveryArtifactModePresentation.ts +++ b/frontend-modern/src/utils/recoveryArtifactModePresentation.ts @@ -22,8 +22,8 @@ export function getRecoveryArtifactModePresentation( return { label: 'Remote Copy', aggregateLabel: 'Remote Copies', - badgeClassName: 'bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-300', - segmentClassName: 'bg-violet-500', + badgeClassName: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900 dark:text-indigo-300', + segmentClassName: 'bg-indigo-500', }; default: return { diff --git a/frontend-modern/src/utils/recoveryFilterChipPresentation.ts b/frontend-modern/src/utils/recoveryFilterChipPresentation.ts index f42766ca9..df51ac650 100644 --- a/frontend-modern/src/utils/recoveryFilterChipPresentation.ts +++ b/frontend-modern/src/utils/recoveryFilterChipPresentation.ts @@ -34,13 +34,13 @@ const CHIP_PRESENTATION: Record = { }, hybrid: { label: 'Hybrid', - badgeClasses: 'bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-400', + badgeClasses: 'bg-teal-100 text-teal-700 dark:bg-teal-900 dark:text-teal-400', }, }; diff --git a/frontend-modern/src/utils/storageSources.ts b/frontend-modern/src/utils/storageSources.ts index a8dc37d32..138e47a77 100644 --- a/frontend-modern/src/utils/storageSources.ts +++ b/frontend-modern/src/utils/storageSources.ts @@ -7,7 +7,7 @@ export type StorageSourceTone = | 'orange' | 'indigo' | 'rose' - | 'violet' + | 'teal' | 'cyan' | 'blue'; @@ -27,7 +27,7 @@ const STORAGE_SOURCE_TONES: Record = { 'proxmox-pve': 'orange', 'proxmox-pbs': 'indigo', 'proxmox-pmg': 'rose', - ceph: 'violet', + ceph: 'teal', truenas: 'blue', kubernetes: 'cyan', };