Skip to content

Commit 906f3f2

Browse files
committed
feat(FR-2667): add ReplicaStatusTag component with tooltip
1 parent d755523 commit 906f3f2

4 files changed

Lines changed: 114 additions & 293 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.stories.tsx

Lines changed: 0 additions & 210 deletions
This file was deleted.

0 commit comments

Comments
 (0)