Skip to content

Commit b167216

Browse files
committed
fix: use SemanticColor type for status color maps in DeploymentStatusTag and ReplicaStatusTag
1 parent 7e9e499 commit b167216

3 files changed

Lines changed: 114 additions & 83 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
@license
3+
Copyright (c) 2015-2026 Lablup Inc. All rights reserved.
4+
*/
5+
import { DeploymentOwnerInfo_deployment$key } from '../__generated__/DeploymentOwnerInfo_deployment.graphql';
6+
import { UserOutlined } from '@ant-design/icons';
7+
import { Avatar, Tooltip, Typography, theme } from 'antd';
8+
import { BAIFlex } from 'backend.ai-ui';
9+
import React from 'react';
10+
import { useTranslation } from 'react-i18next';
11+
import { graphql, useFragment } from 'react-relay';
12+
13+
interface DeploymentOwnerInfoProps {
14+
deploymentFrgmt: DeploymentOwnerInfo_deployment$key | null | undefined;
15+
}
16+
17+
const DeploymentOwnerInfo: React.FC<DeploymentOwnerInfoProps> = ({
18+
deploymentFrgmt,
19+
}) => {
20+
'use memo';
21+
const { t } = useTranslation();
22+
const { token } = theme.useToken();
23+
24+
const deployment = useFragment(
25+
graphql`
26+
fragment DeploymentOwnerInfo_deployment on ModelDeployment {
27+
id
28+
creator @since(version: "26.4.3") {
29+
id
30+
basicInfo {
31+
email
32+
username
33+
fullName
34+
}
35+
}
36+
}
37+
`,
38+
deploymentFrgmt,
39+
);
40+
41+
const email = deployment?.creator?.basicInfo?.email ?? '';
42+
const fullName = deployment?.creator?.basicInfo?.fullName ?? '';
43+
const username = deployment?.creator?.basicInfo?.username ?? '';
44+
45+
if (!email) {
46+
return <Typography.Text type="secondary">-</Typography.Text>;
47+
}
48+
49+
const initial = (fullName || username || email)
50+
.trim()
51+
.charAt(0)
52+
.toUpperCase();
53+
const tooltipLines = [
54+
t('deployment.CreatedBy'),
55+
fullName || username || email,
56+
email,
57+
]
58+
.filter(Boolean)
59+
.join('\n');
60+
61+
return (
62+
<BAIFlex gap="xs" align="center">
63+
<Tooltip
64+
title={<span style={{ whiteSpace: 'pre-line' }}>{tooltipLines}</span>}
65+
>
66+
<Avatar
67+
size="small"
68+
style={{
69+
backgroundColor: token.colorFillSecondary,
70+
color: token.colorText,
71+
flexShrink: 0,
72+
}}
73+
icon={!initial ? <UserOutlined /> : undefined}
74+
>
75+
{initial || null}
76+
</Avatar>
77+
</Tooltip>
78+
<Typography.Text ellipsis={{ tooltip: email }} style={{ maxWidth: 200 }}>
79+
{email}
80+
</Typography.Text>
81+
</BAIFlex>
82+
);
83+
};
84+
85+
export default DeploymentOwnerInfo;

react/src/components/DeploymentStatusTag.tsx

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
@license
33
Copyright (c) 2015-2026 Lablup Inc. All rights reserved.
44
*/
5-
import { BadgeProps } from 'antd';
6-
import { BAIBadge, SemanticColor } from 'backend.ai-ui';
5+
import type { TagProps } from 'antd';
6+
import { BAITag, type SemanticColor } from 'backend.ai-ui';
77
import React from 'react';
88
import { useTranslation } from 'react-i18next';
99

@@ -21,14 +21,14 @@ export type DeploymentStatus =
2121
| 'READY';
2222

2323
/**
24-
* Maps each deployment status to a semantic color.
24+
* Maps each deployment status to a Tag color.
2525
*
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.
26+
* - success: HEALTHY, READY — fully operational.
27+
* - processing: DEPLOYING, SCALING, PENDING — transient, in-flight states.
28+
* - warning: DEGRADED, UNHEALTHY, STOPPING — attention needed or transitioning away.
29+
* - default: NOT_CHECKED, STOPPED, TERMINATED — neutral / inactive.
3030
*/
31-
const deploymentStatusSemanticMap: Record<DeploymentStatus, SemanticColor> = {
31+
const deploymentStatusColorMap: Record<DeploymentStatus, SemanticColor> = {
3232
HEALTHY: 'success',
3333
READY: 'success',
3434
DEPLOYING: 'info',
@@ -42,15 +42,6 @@ const deploymentStatusSemanticMap: Record<DeploymentStatus, SemanticColor> = {
4242
TERMINATED: 'default',
4343
};
4444

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-
*/
5445
const deploymentStatusI18nMap: Record<DeploymentStatus, string> = {
5546
HEALTHY: 'deployment.status.Healthy',
5647
UNHEALTHY: 'deployment.status.Unhealthy',
@@ -65,10 +56,7 @@ const deploymentStatusI18nMap: Record<DeploymentStatus, string> = {
6556
READY: 'deployment.status.Ready',
6657
};
6758

68-
export interface DeploymentStatusTagProps extends Omit<
69-
BadgeProps,
70-
'color' | 'status' | 'styles' | 'text'
71-
> {
59+
export interface DeploymentStatusTagProps extends Omit<TagProps, 'color'> {
7260
/**
7361
* The deployment-level status to display. Consolidates lifecycle (e.g.
7462
* `DEPLOYING`, `STOPPED`, `TERMINATED`) and health (e.g. `HEALTHY`,
@@ -78,26 +66,20 @@ export interface DeploymentStatusTagProps extends Omit<
7866
}
7967

8068
/**
81-
* DeploymentStatusTag — consolidated lifecycle + health status badge for a
69+
* DeploymentStatusTag — consolidated lifecycle + health status tag for a
8270
* 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.
8671
*/
8772
const DeploymentStatusTag: React.FC<DeploymentStatusTagProps> = ({
8873
status,
89-
...badgeProps
74+
...tagProps
9075
}) => {
9176
'use memo';
9277
const { t } = useTranslation();
9378

9479
return (
95-
<BAIBadge
96-
{...badgeProps}
97-
color={deploymentStatusSemanticMap[status]}
98-
processing={processingStatuses.has(status)}
99-
text={t(deploymentStatusI18nMap[status])}
100-
/>
80+
<BAITag {...tagProps} color={deploymentStatusColorMap[status]}>
81+
{t(deploymentStatusI18nMap[status])}
82+
</BAITag>
10183
);
10284
};
10385

react/src/components/ReplicaStatusTag.tsx

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
@license
33
Copyright (c) 2015-2026 Lablup Inc. All rights reserved.
44
*/
5-
import { BadgeProps, Tooltip } from 'antd';
6-
import { BAIBadge, SemanticColor } from 'backend.ai-ui';
5+
import { Tooltip } from 'antd';
6+
import type { TagProps } from 'antd';
7+
import { BAITag, type SemanticColor } from 'backend.ai-ui';
78
import React from 'react';
89
import { useTranslation } from 'react-i18next';
910

@@ -16,55 +17,30 @@ export type ReplicaStatus =
1617
| 'TERMINATING'
1718
| 'TERMINATED';
1819

19-
export interface ReplicaStatusTagProps extends Omit<
20-
BadgeProps,
21-
'color' | 'status'
22-
> {
20+
export interface ReplicaStatusTagProps extends Omit<TagProps, 'color'> {
2321
/**
2422
* Replica health/lifecycle state.
2523
* Health states: `HEALTHY`, `UNHEALTHY`, `DEGRADED`, `NOT_CHECKED`.
2624
* Lifecycle states: `PROVISIONING`, `TERMINATING`, `TERMINATED`.
2725
*/
2826
status: ReplicaStatus;
2927
/**
30-
* When true, wraps the badge in a tooltip explaining the state.
28+
* When true, wraps the tag in a tooltip explaining the state.
3129
* @default true
3230
*/
3331
showTooltip?: boolean;
3432
}
3533

36-
/**
37-
* Maps each replica status to a semantic color from the BAI design system.
38-
* `NOT_CHECKED` intentionally maps to `undefined` so `BAIBadge` renders an
39-
* outline-only (border) dot, matching the "unknown/indeterminate" convention.
40-
*/
41-
const replicaStatusSemanticMap: Record<
42-
ReplicaStatus,
43-
SemanticColor | undefined
44-
> = {
34+
const replicaStatusColorMap: Record<ReplicaStatus, SemanticColor> = {
4535
HEALTHY: 'success',
4636
UNHEALTHY: 'error',
4737
DEGRADED: 'warning',
48-
NOT_CHECKED: undefined,
38+
NOT_CHECKED: 'default',
4939
PROVISIONING: 'info',
5040
TERMINATING: 'warning',
5141
TERMINATED: 'default',
5242
};
5343

54-
/**
55-
* Statuses that should render with a ripple/processing animation on the dot
56-
* to convey an in-progress lifecycle transition.
57-
*/
58-
const processingStatuses: ReadonlySet<ReplicaStatus> = new Set([
59-
'PROVISIONING',
60-
'TERMINATING',
61-
]);
62-
63-
/**
64-
* i18n key suffix (PascalCase) for each replica status. Matches the keys
65-
* registered under `replicaStatus.*` and `replicaStatus.tooltip.*` in
66-
* `resources/i18n/en.json` (see FR-2666).
67-
*/
6844
const replicaStatusI18nKey: Record<ReplicaStatus, string> = {
6945
HEALTHY: 'Healthy',
7046
UNHEALTHY: 'Unhealthy',
@@ -75,46 +51,34 @@ const replicaStatusI18nKey: Record<ReplicaStatus, string> = {
7551
TERMINATED: 'Terminated',
7652
};
7753

78-
/**
79-
* ReplicaStatusTag - Displays the health/lifecycle state of a deployment replica.
80-
*
81-
* Renders a `BAIBadge` whose dot color and processing animation map to the
82-
* new replica health state machine used by the Endpoint Deployment UI
83-
* (FR-1368 / FR-2658). When `showTooltip` is true (default), the badge is
84-
* wrapped in a `Tooltip` that explains the state to the user.
85-
*/
8654
const ReplicaStatusTag: React.FC<ReplicaStatusTagProps> = ({
8755
status,
8856
showTooltip = true,
89-
...badgeProps
57+
...tagProps
9058
}) => {
9159
'use memo';
9260
const { t } = useTranslation();
9361

94-
const color = replicaStatusSemanticMap[status];
95-
const processing = processingStatuses.has(status);
62+
const color = replicaStatusColorMap[status];
9663
const i18nKey = replicaStatusI18nKey[status];
9764
const label = t(`replicaStatus.${i18nKey}`);
9865
const tooltipTitle = showTooltip
9966
? t(`replicaStatus.tooltip.${i18nKey}`, { defaultValue: '' })
10067
: undefined;
10168

102-
const badge = (
103-
<BAIBadge
104-
{...badgeProps}
105-
color={color}
106-
processing={processing}
107-
text={label}
108-
/>
69+
const tag = (
70+
<BAITag {...tagProps} color={color}>
71+
{label}
72+
</BAITag>
10973
);
11074

11175
if (!showTooltip || !tooltipTitle) {
112-
return badge;
76+
return tag;
11377
}
11478

11579
return (
11680
<Tooltip title={tooltipTitle}>
117-
<span>{badge}</span>
81+
<span>{tag}</span>
11882
</Tooltip>
11983
);
12084
};

0 commit comments

Comments
 (0)