Unify site badge links across console pages

This commit is contained in:
ciat-777
2026-03-16 14:48:46 +08:00
parent bfb7ea180f
commit d9e33e71ed
5 changed files with 113 additions and 37 deletions
+37
View File
@@ -0,0 +1,37 @@
import React from 'react';
import { Link } from 'react-router-dom';
type SiteBadgeLinkProps = {
siteId?: number | null;
siteName?: string | null;
className?: string;
badgeClassName?: string;
badgeStyle?: React.CSSProperties;
};
export default function SiteBadgeLink({
siteId,
siteName,
className = 'badge-link',
badgeClassName = 'badge badge-muted',
badgeStyle,
}: SiteBadgeLinkProps) {
const label = String(siteName || '').trim() || '-';
const normalizedSiteId = Number(siteId);
if (!Number.isFinite(normalizedSiteId) || normalizedSiteId <= 0) {
return (
<span className={badgeClassName} style={badgeStyle}>
{label}
</span>
);
}
return (
<Link to={`/sites?focusSiteId=${Math.trunc(normalizedSiteId)}`} className={className}>
<span className={badgeClassName} style={badgeStyle}>
{label}
</span>
</Link>
);
}
@@ -0,0 +1,34 @@
import { describe, expect, it } from 'vitest';
import { create } from 'react-test-renderer';
import { MemoryRouter } from 'react-router-dom';
import SiteBadgeLink from './SiteBadgeLink.js';
describe('SiteBadgeLink', () => {
it('renders a focus-navigation link when site id is valid', () => {
const root = create(
<MemoryRouter>
<SiteBadgeLink siteId={7} siteName="Demo Site" />
</MemoryRouter>,
);
const link = root.root.findByType('a');
expect(String(link.props.href || '')).toContain('/sites?focusSiteId=7');
expect(String(link.props.className || '')).toContain('badge-link');
expect(root.root.findByProps({ className: 'badge badge-muted' }).children.join('')).toContain('Demo Site');
root.unmount();
});
it('falls back to plain badge text when site id is invalid', () => {
const root = create(
<MemoryRouter>
<SiteBadgeLink siteId={0} siteName="Unknown Site" />
</MemoryRouter>,
);
expect(root.root.findAllByType('a')).toHaveLength(0);
expect(root.root.findByProps({ className: 'badge badge-muted' }).children.join('')).toContain('Unknown Site');
root.unmount();
});
});