fix(ui): consistent attribute badge colors based on value hash across all views
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { Badge } from '@cameleer/design-system';
|
||||
import type { ProcessorNode, ExecutionDetail } from '../types';
|
||||
import { attributeBadgeColor } from '../../../utils/attribute-color';
|
||||
import styles from '../ExecutionDiagram.module.css';
|
||||
|
||||
interface InfoTabProps {
|
||||
@@ -52,9 +54,7 @@ function Attributes({ attrs }: { attrs: Record<string, string> | undefined }) {
|
||||
<div className={styles.attributesLabel}>Attributes</div>
|
||||
<div className={styles.attributesList}>
|
||||
{entries.map(([k, v]) => (
|
||||
<span key={k} className={styles.attributePill}>
|
||||
{k}: {v}
|
||||
</span>
|
||||
<Badge key={k} label={`${k}: ${v}`} color={attributeBadgeColor(String(v))} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
useSearchExecutions,
|
||||
} from '../../api/queries/executions'
|
||||
import type { ExecutionSummary } from '../../api/types'
|
||||
import { attributeBadgeColor } from '../../utils/attribute-color'
|
||||
import styles from './Dashboard.module.css'
|
||||
|
||||
// Row type extends ExecutionSummary with an `id` field for DataTable
|
||||
@@ -127,7 +128,7 @@ function buildBaseColumns(): Column<Row>[] {
|
||||
<div className={styles.attrCell}>
|
||||
{shown.map(([k, v]) => (
|
||||
<span key={k} title={k}>
|
||||
<Badge label={String(v)} color="auto" />
|
||||
<Badge label={String(v)} color={attributeBadgeColor(String(v))} />
|
||||
</span>
|
||||
))}
|
||||
{overflow > 0 && <span className={styles.attrOverflow}>+{overflow}</span>}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { StatusDot, MonoText, Badge } from '@cameleer/design-system';
|
||||
import { useCorrelationChain } from '../../api/queries/correlation';
|
||||
import { useAgents } from '../../api/queries/agents';
|
||||
import type { ExecutionDetail } from '../../components/ExecutionDiagram/types';
|
||||
import { attributeBadgeColor } from '../../utils/attribute-color';
|
||||
import styles from './ExchangeHeader.module.css';
|
||||
|
||||
interface ExchangeHeaderProps {
|
||||
@@ -63,7 +64,7 @@ export function ExchangeHeader({ detail, onCorrelatedSelect }: ExchangeHeaderPro
|
||||
<>
|
||||
<span className={styles.separator} />
|
||||
{attrs.map(([k, v]) => (
|
||||
<Badge key={k} label={`${k}: ${v}`} color="auto" />
|
||||
<Badge key={k} label={`${k}: ${v}`} color={attributeBadgeColor(String(v))} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
24
ui/src/utils/attribute-color.ts
Normal file
24
ui/src/utils/attribute-color.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
/**
|
||||
* Deterministic color for attribute badges.
|
||||
* Uses the value (not the key) to compute the color,
|
||||
* ensuring the same value always gets the same color
|
||||
* regardless of where it's displayed.
|
||||
*
|
||||
* Returns a BadgeColor that the design system accepts.
|
||||
*/
|
||||
const COLORS = ['primary', 'success', 'warning', 'running'] as const;
|
||||
type BadgeColor = 'primary' | 'success' | 'warning' | 'error' | 'running' | 'auto';
|
||||
|
||||
function hashString(s: string): number {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
hash = ((hash << 5) - hash + s.charCodeAt(i)) | 0;
|
||||
}
|
||||
return Math.abs(hash);
|
||||
}
|
||||
|
||||
export function attributeBadgeColor(value: string): BadgeColor {
|
||||
return COLORS[hashString(value) % COLORS.length];
|
||||
}
|
||||
Reference in New Issue
Block a user