// Generate different gray shades for different metadata keys
const getMetadataKeyColor = (key: string): string => {
const grayShades = [
'bg-stone-200 text-stone-800',
'bg-gray-200 text-gray-800',
'bg-slate-200 text-slate-800',
'bg-zinc-200 text-zinc-800',
'bg-neutral-200 text-neutral-800',
'bg-stone-300 text-stone-800',
'bg-gray-300 text-gray-800',
'bg-slate-300 text-slate-800'
];
// Simple hash function to get consistent shade for each key
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash = ((hash << 5) - hash + key.charCodeAt(i)) & 0xffffffff;
}
return grayShades[Math.abs(hash) % grayShades.length];
};
// Render metadata as visual tags
const renderMetadata = (metadata: unknown) => {
if (!metadata) return "—";
try {
const metaObj = typeof metadata === 'string'
? JSON.parse(metadata)
: metadata;
if (typeof metaObj === 'object' && metaObj !== null) {
const entries = Object.entries(metaObj);
return (
<div className="flex flex-wrap gap-1">
{entries.map(([key, value]) => {
const colorClass = getMetadataKeyColor(key);
if (Array.isArray(value)) {
// Render array values as separate tags with same color
return value.map((item, index) => {
const cleanItem = String(item).replace(/[\[\]"]/g, '').trim();
return (
<div
key={`${key}-${index}`}
className={`inline-block px-3 py-1 rounded-full text-xs font-medium ${colorClass} text-center whitespace-nowrap overflow-hidden text-ellipsis`}
title={`${key}: ${cleanItem}`}
>
{cleanItem}
</div>
);
});
} else {
// Render single value
const displayValue = String(value).replace(/[\[\]"]/g, '').trim();
return (
<div
key={key}
className={`inline-block px-3 py-1 rounded-full text-xs font-medium ${colorClass} text-center whitespace-nowrap overflow-hidden text-ellipsis`}
title={`${key}: ${displayValue}`}
>
{displayValue}
</div>
);
}
})}
</div>
);
}
return JSON.stringify(metaObj);
} catch (e) {
console.error("Error formatting metadata:", e);
return typeof metadata === 'string'
? (metadata as string).substring(0, 50)
: "Invalid metadata";
}
};