Skip to content

Commit 0cf41c8

Browse files
committed
feat: make workspace status icons theme-aware
Update all workspace status icons to use appropriate colors for both light and dark themes. Changes: - Added useStatusIcon hook that uses theme context - Updated getStatusIcon to accept isDarkTheme parameter - Converted WorkspaceStatusLabel and WorkspaceStatusIndicator from class to functional components to use hooks - Removed deprecated greyCssVariable export - Default status icon (InProgressIcon) now uses theme-aware grey: - Light theme: var(--pf-global--palette--black-500) (darker) - Dark theme: var(--pf-global--palette--black-300) (lighter) The StoppedIcon component was already theme-aware and remains unchanged. Assisted-by: Claude Sonnet 4.5 Signed-off-by: Oleksii Orel <oorel@redhat.com>
1 parent 599e43e commit 0cf41c8

File tree

4 files changed

+66
-62
lines changed

4 files changed

+66
-62
lines changed

packages/dashboard-frontend/src/components/Workspace/Status/Indicator/index.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import React from 'react';
1414

1515
import { CheTooltip } from '@/components/CheTooltip';
16-
import { getStatusIcon } from '@/components/Workspace/Status/getStatusIcon';
16+
import { useStatusIcon } from '@/components/Workspace/Status/getStatusIcon';
1717
import styles from '@/components/Workspace/Status/index.module.css';
1818
import {
1919
DeprecatedWorkspaceStatus,
@@ -25,24 +25,20 @@ export type Props = {
2525
status: WorkspaceStatus | DevWorkspaceStatus | DeprecatedWorkspaceStatus;
2626
};
2727

28-
export class WorkspaceStatusIndicator extends React.PureComponent<Props> {
29-
public render(): React.ReactElement {
30-
const { status } = this.props;
28+
export const WorkspaceStatusIndicator: React.FC<Props> = ({ status }) => {
29+
const icon = useStatusIcon(status);
3130

32-
const icon = getStatusIcon(status);
31+
const tooltip = status === 'Deprecated' ? 'Deprecated workspace' : status.toLocaleUpperCase();
3332

34-
const tooltip = status === 'Deprecated' ? 'Deprecated workspace' : status.toLocaleUpperCase();
35-
36-
return (
37-
<CheTooltip content={tooltip}>
38-
<span
39-
className={styles.statusIndicator}
40-
data-testid="workspace-status-indicator"
41-
aria-label={`Workspace status is ${status}`}
42-
>
43-
{icon}
44-
</span>
45-
</CheTooltip>
46-
);
47-
}
48-
}
33+
return (
34+
<CheTooltip content={tooltip}>
35+
<span
36+
className={styles.statusIndicator}
37+
data-testid="workspace-status-indicator"
38+
aria-label={`Workspace status is ${status}`}
39+
>
40+
{icon}
41+
</span>
42+
</CheTooltip>
43+
);
44+
};

packages/dashboard-frontend/src/components/Workspace/Status/Label/index.tsx

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Label, LabelProps } from '@patternfly/react-core';
1414
import React from 'react';
1515

1616
import { CheTooltip } from '@/components/CheTooltip';
17-
import { getStatusIcon } from '@/components/Workspace/Status/getStatusIcon';
17+
import { useStatusIcon } from '@/components/Workspace/Status/getStatusIcon';
1818
import styles from '@/components/Workspace/Status/index.module.css';
1919
import {
2020
DeprecatedWorkspaceStatus,
@@ -26,40 +26,38 @@ type Props = {
2626
status: WorkspaceStatus | DevWorkspaceStatus | DeprecatedWorkspaceStatus;
2727
};
2828

29-
export class WorkspaceStatusLabel extends React.PureComponent<Props> {
30-
render(): React.ReactElement {
31-
const { status } = this.props;
29+
export const WorkspaceStatusLabel: React.FC<Props> = ({ status }) => {
30+
const icon = useStatusIcon(status);
3231

33-
let statusLabelColor: LabelProps['color'];
34-
switch (status) {
35-
case WorkspaceStatus.RUNNING:
36-
case DevWorkspaceStatus.RUNNING:
37-
statusLabelColor = 'green';
38-
break;
39-
case WorkspaceStatus.STARTING:
40-
case DevWorkspaceStatus.STARTING:
41-
statusLabelColor = 'blue';
42-
break;
43-
case DevWorkspaceStatus.FAILING:
44-
case WorkspaceStatus.ERROR:
45-
case DevWorkspaceStatus.FAILED:
46-
case 'Deprecated':
47-
statusLabelColor = 'orange';
48-
break;
49-
case WorkspaceStatus.STOPPED:
50-
case DevWorkspaceStatus.STOPPED:
51-
case WorkspaceStatus.STOPPING:
52-
case DevWorkspaceStatus.STOPPING:
53-
case DevWorkspaceStatus.TERMINATING:
54-
statusLabelColor = 'grey';
55-
}
56-
57-
return (
58-
<CheTooltip content={status === 'Deprecated' ? 'Deprecated workspace' : status}>
59-
<Label className={styles.statusLabel} color={statusLabelColor} icon={getStatusIcon(status)}>
60-
{status}
61-
</Label>
62-
</CheTooltip>
63-
);
32+
let statusLabelColor: LabelProps['color'];
33+
switch (status) {
34+
case WorkspaceStatus.RUNNING:
35+
case DevWorkspaceStatus.RUNNING:
36+
statusLabelColor = 'green';
37+
break;
38+
case WorkspaceStatus.STARTING:
39+
case DevWorkspaceStatus.STARTING:
40+
statusLabelColor = 'blue';
41+
break;
42+
case DevWorkspaceStatus.FAILING:
43+
case WorkspaceStatus.ERROR:
44+
case DevWorkspaceStatus.FAILED:
45+
case 'Deprecated':
46+
statusLabelColor = 'orange';
47+
break;
48+
case WorkspaceStatus.STOPPED:
49+
case DevWorkspaceStatus.STOPPED:
50+
case WorkspaceStatus.STOPPING:
51+
case DevWorkspaceStatus.STOPPING:
52+
case DevWorkspaceStatus.TERMINATING:
53+
statusLabelColor = 'grey';
6454
}
65-
}
55+
56+
return (
57+
<CheTooltip content={status === 'Deprecated' ? 'Deprecated workspace' : status}>
58+
<Label className={styles.statusLabel} color={statusLabelColor} icon={icon}>
59+
{status}
60+
</Label>
61+
</CheTooltip>
62+
);
63+
};

packages/dashboard-frontend/src/components/Workspace/Status/StoppedIcon.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ import { useTheme } from '@/contexts/ThemeContext';
1818
const lightGreyCssVariable = 'var(--pf-global--palette--black-500)';
1919
const darkGreyCssVariable = 'var(--pf-global--palette--black-300)';
2020

21-
// Deprecated: kept for backward compatibility
22-
export const greyCssVariable = lightGreyCssVariable;
23-
2421
export function StoppedIcon(): React.ReactElement {
2522
const { isDarkTheme } = useTheme();
2623
const fillColor = isDarkTheme ? darkGreyCssVariable : lightGreyCssVariable;

packages/dashboard-frontend/src/components/Workspace/Status/getStatusIcon.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,17 @@ import {
1919
import React from 'react';
2020

2121
import styles from '@/components/Workspace/Status/index.module.css';
22-
import { greyCssVariable, StoppedIcon } from '@/components/Workspace/Status/StoppedIcon';
22+
import { StoppedIcon } from '@/components/Workspace/Status/StoppedIcon';
23+
import { useTheme } from '@/contexts/ThemeContext';
2324
import { DevWorkspaceStatus, WorkspaceStatus } from '@/services/helpers/types';
2425

25-
export function getStatusIcon(status: string) {
26+
// Theme-aware grey colors
27+
const lightGreyCssVariable = 'var(--pf-global--palette--black-500)';
28+
const darkGreyCssVariable = 'var(--pf-global--palette--black-300)';
29+
30+
export function getStatusIcon(status: string, isDarkTheme: boolean) {
31+
const greyColor = isDarkTheme ? darkGreyCssVariable : lightGreyCssVariable;
32+
2633
let icon: React.ReactElement;
2734
switch (status) {
2835
case DevWorkspaceStatus.STOPPED:
@@ -68,9 +75,15 @@ export function getStatusIcon(status: string) {
6875
default:
6976
icon = (
7077
<Icon isInline>
71-
<InProgressIcon className={styles.rotate} color={greyCssVariable} />
78+
<InProgressIcon className={styles.rotate} color={greyColor} />
7279
</Icon>
7380
);
7481
}
7582
return icon;
7683
}
84+
85+
// Hook version that automatically uses theme context
86+
export function useStatusIcon(status: string): React.ReactElement {
87+
const { isDarkTheme } = useTheme();
88+
return getStatusIcon(status, isDarkTheme);
89+
}

0 commit comments

Comments
 (0)