Skip to content

Commit d5a8672

Browse files
committed
feat(FR-2668): add DeploymentStatusTag component
1 parent d374d59 commit d5a8672

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
@license
3+
Copyright (c) 2015-2026 Lablup Inc. All rights reserved.
4+
*/
5+
import { BadgeProps } from 'antd';
6+
import { BAIBadge, SemanticColor } from 'backend.ai-ui';
7+
import React from 'react';
8+
import { useTranslation } from 'react-i18next';
9+
10+
export type DeploymentStatus =
11+
| 'HEALTHY'
12+
| 'UNHEALTHY'
13+
| 'DEGRADED'
14+
| 'NOT_CHECKED'
15+
| 'DEPLOYING'
16+
| 'SCALING'
17+
| 'STOPPED'
18+
| 'STOPPING'
19+
| 'TERMINATED'
20+
| 'PENDING'
21+
| 'READY';
22+
23+
/**
24+
* Maps each deployment status to a semantic color.
25+
*
26+
* - success: HEALTHY, READY — the deployment is fully operational.
27+
* - info: DEPLOYING, SCALING, PENDING — transient, in-flight states.
28+
* - warning: DEGRADED, UNHEALTHY, STOPPING — user attention needed or transitioning away.
29+
* - default: NOT_CHECKED, STOPPED, TERMINATED — neutral / inactive / pre-check states.
30+
*/
31+
const deploymentStatusSemanticMap: Record<DeploymentStatus, SemanticColor> = {
32+
HEALTHY: 'success',
33+
READY: 'success',
34+
DEPLOYING: 'info',
35+
SCALING: 'info',
36+
PENDING: 'info',
37+
DEGRADED: 'warning',
38+
UNHEALTHY: 'warning',
39+
STOPPING: 'warning',
40+
NOT_CHECKED: 'default',
41+
STOPPED: 'default',
42+
TERMINATED: 'default',
43+
};
44+
45+
/**
46+
* In-flight statuses that should render with the processing ripple animation.
47+
*/
48+
const processingStatuses: ReadonlySet<DeploymentStatus> =
49+
new Set<DeploymentStatus>(['DEPLOYING', 'SCALING', 'STOPPING']);
50+
51+
/**
52+
* Maps each deployment status to its i18n translation key under `deployment.status.*`.
53+
*/
54+
const deploymentStatusI18nMap: Record<DeploymentStatus, string> = {
55+
HEALTHY: 'deployment.status.Healthy',
56+
UNHEALTHY: 'deployment.status.Unhealthy',
57+
DEGRADED: 'deployment.status.Degraded',
58+
NOT_CHECKED: 'deployment.status.NotChecked',
59+
DEPLOYING: 'deployment.status.Deploying',
60+
SCALING: 'deployment.status.Scaling',
61+
STOPPED: 'deployment.status.Stopped',
62+
STOPPING: 'deployment.status.Stopping',
63+
TERMINATED: 'deployment.status.Terminated',
64+
PENDING: 'deployment.status.Pending',
65+
READY: 'deployment.status.Ready',
66+
};
67+
68+
export interface DeploymentStatusTagProps extends Omit<
69+
BadgeProps,
70+
'color' | 'status' | 'styles' | 'text'
71+
> {
72+
/**
73+
* The deployment-level status to display. Consolidates lifecycle (e.g.
74+
* `DEPLOYING`, `STOPPED`, `TERMINATED`) and health (e.g. `HEALTHY`,
75+
* `UNHEALTHY`, `DEGRADED`) into a single tag.
76+
*/
77+
status: DeploymentStatus;
78+
}
79+
80+
/**
81+
* DeploymentStatusTag — consolidated lifecycle + health status badge for a
82+
* deployment. Used in list rows and detail page headers.
83+
*
84+
* In-flight states (`DEPLOYING`, `SCALING`, `STOPPING`) automatically render
85+
* with a processing ripple animation.
86+
*/
87+
const DeploymentStatusTag: React.FC<DeploymentStatusTagProps> = ({
88+
status,
89+
...badgeProps
90+
}) => {
91+
'use memo';
92+
const { t } = useTranslation();
93+
94+
return (
95+
<BAIBadge
96+
{...badgeProps}
97+
color={deploymentStatusSemanticMap[status]}
98+
processing={processingStatuses.has(status)}
99+
text={t(deploymentStatusI18nMap[status])}
100+
/>
101+
);
102+
};
103+
104+
export default DeploymentStatusTag;

0 commit comments

Comments
 (0)