style(usage): extract DeletedTag, unify deleted-entity tag across filters

This commit is contained in:
jialin
2026-07-09 15:17:53 +08:00
committed by jialin
parent c691df25c0
commit 7d9f68da2d
3 changed files with 79 additions and 12 deletions
@@ -0,0 +1,44 @@
/**
* Deleted-entity marker for the usage filter dropdowns (model / user / api-key
* on the Tokens tab; user / instance / volume on the resource tabs). Renders an
* outlined transparent pill "Deleted·#{id}" — the id keeps two entries sharing
* a now-stale label distinguishable. Pairs with dimming the option label to the
* tertiary text color.
*
* Presentational only: each filter resolves the entity id from its own option
* shape (Tokens tab ← ``identity.current``; resource tabs ← option ``value``)
* and passes it in. When no id is available the tag falls back to plain
* "Deleted".
*/
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import React from 'react';
interface DeletedTagProps {
id?: string | number | null;
}
const DeletedTag: React.FC<DeletedTagProps> = ({ id }) => {
const intl = useIntl();
const label = intl.formatMessage({ id: 'usage.table.deleted' });
return (
<Tag
variant="outlined"
style={{
margin: 0,
fontSize: 11,
borderRadius: 12,
background: 'transparent'
}}
>
{label}
{id != null && (
<span className="text-tertiary">
<span style={{ margin: '0 2px' }}>·</span>#{id}
</span>
)}
</Tag>
);
};
export default DeletedTag;
+24 -9
View File
@@ -13,6 +13,7 @@ import React from 'react';
import { GroupOption } from '../config';
import { UsageFilterItem } from '../config/types';
import FilterBarCss from '../styles/filter-bar.less';
import DeletedTag from './deleted-tag';
type valueType = string | number | null;
const DefaultDateConfig = {
@@ -156,6 +157,17 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
);
};
// The entity id behind a deleted option, shown in the "Deleted·#{id}" tag so
// two deleted entries with the same (now-stale) label stay distinguishable.
const getEntityId = (data: any): valueType => {
const current = data?.identity?.current;
if (!current) return null;
return current.user_id ?? current.api_key_id ?? current.route_id ?? null;
};
const deletedLabelStyle = (deleted?: boolean) =>
deleted ? { color: 'var(--ant-color-text-tertiary)' } : undefined;
const handleOnApiKeysChange = (
value: valueType[][],
selectedOptions: any
@@ -175,9 +187,10 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
if (!data.isParent) {
return (
<span className="flex-center gap-4">
<AutoTooltip ghost>{data.label}</AutoTooltip>
{data.deleted &&
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
<AutoTooltip ghost style={deletedLabelStyle(data.deleted)}>
{data.label}
</AutoTooltip>
{data.deleted && <DeletedTag id={getEntityId(data)} />}
</span>
);
}
@@ -193,9 +206,10 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
const { data } = option;
return (
<span className="flex-center gap-4">
<AutoTooltip ghost>{data.label}</AutoTooltip>
{data.deleted &&
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
<AutoTooltip ghost style={deletedLabelStyle(data.deleted)}>
{data.label}
</AutoTooltip>
{data.deleted && <DeletedTag id={getEntityId(data)} />}
</span>
);
};
@@ -214,11 +228,12 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
const { data } = option;
return (
<span className="flex-center gap-4">
<AutoTooltip ghost>{data.label}</AutoTooltip>
<AutoTooltip ghost style={deletedLabelStyle(data.deleted)}>
{data.label}
</AutoTooltip>
{data.isCurrent &&
renderTag(intl.formatMessage({ id: 'usage.user.currentAccount' }))}
{data.deleted &&
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
{data.deleted && <DeletedTag id={getEntityId(data)} />}
</span>
);
};
@@ -17,6 +17,7 @@ import { Button, DatePicker, Dropdown, MenuProps } from 'antd';
import dayjs from 'dayjs';
import React from 'react';
import FilterBarCss from '../styles/filter-bar.less';
import DeletedTag from './deleted-tag';
const DefaultDateConfig = {
maxRange: 90,
@@ -144,15 +145,22 @@ const ResourceFilterBar: React.FC<ResourceFilterBarProps> = (props) => {
</span>
);
const deletedLabelStyle = (deleted?: boolean) =>
deleted ? { color: 'var(--ant-color-text-tertiary)' } : undefined;
// The user / instance / volume filters mirror the Tokens tab: the option
// ``value`` is the entity id, so a deleted entry stays distinguishable via the
// "Deleted·#{id}" tag.
const userOptionRender = (option: any) => {
const { data } = option;
return (
<span className="flex-center gap-4">
<AutoTooltip ghost>{data?.label}</AutoTooltip>
<AutoTooltip ghost style={deletedLabelStyle(data?.deleted)}>
{data?.label}
</AutoTooltip>
{data?.isCurrent &&
renderTag(intl.formatMessage({ id: 'usage.user.currentAccount' }))}
{data?.deleted &&
renderTag(intl.formatMessage({ id: 'usage.table.deleted' }))}
{data?.deleted && <DeletedTag id={data?.value} />}
</span>
);
};