Commit 5696e951 by luoqi

fix(web): 多值画像标签 chip 显示「首值 +N」而非静默只显示第一个

治疗史/权益/禁忌/潜在治疗/时间偏好/治疗敏感/特别关注 这 7 个特征是 `/` 并列多值,
原 chip 用 shortPersonaValueLabel 在 `/` 处截断 → 只剩第一个值且不提示还有更多。
改读结构化 data.labels(后端这 7 个都带):多值显示首值 + 灰色 +N,完整列表走 hover 卡片;
单值特征不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent ee00c6c5
...@@ -68,3 +68,22 @@ export function shortPersonaValueLabel(raw: string | null | undefined): string { ...@@ -68,3 +68,22 @@ export function shortPersonaValueLabel(raw: string | null | undefined): string {
const stop = raw.search(/[·\/(()]/); const stop = raw.search(/[·\/(()]/);
return (stop > 0 ? raw.slice(0, stop) : raw).trim(); return (stop > 0 ? raw.slice(0, stop) : raw).trim();
} }
/**
* 多值标签的紧凑显示(方案 A:首值 + "+N" 溢出)
*
* 治疗史 / 权益 / 禁忌 / 潜在治疗 / 时间偏好 / 治疗敏感 / 特别关注 这 7 个特征
* 是"`/` 并列多值",description 会被 shortPersonaValueLabel 在 `/` 处误截只剩第一个、
* 且不提示还有更多。这里改读结构化 `data.labels`(后端这 7 个都带),chip 显示
* 第一个值 + `+N`(N=剩余个数),完整列表走 hover 卡片。单值特征 → { text, more:0 }。
*/
export function compactPersonaValue(
raw: string | null | undefined,
data?: unknown,
): { text: string; more: number } {
const labels = (data as { labels?: unknown } | null | undefined)?.labels;
if (Array.isArray(labels) && labels.length > 0 && typeof labels[0] === 'string') {
return { text: labels[0] as string, more: labels.length - 1 };
}
return { text: shortPersonaValueLabel(raw), more: 0 };
}
...@@ -40,7 +40,7 @@ import { ...@@ -40,7 +40,7 @@ import {
import { AIStamp, Chip, PriorityBar, SidebarCard, tone } from './shared'; import { AIStamp, Chip, PriorityBar, SidebarCard, tone } from './shared';
import { PriorityHover, type PriorityBreakdown } from '@/components/priority-hover'; import { PriorityHover, type PriorityBreakdown } from '@/components/priority-hover';
import { HoverCard, HoverCardTrigger, HoverCardContent } from '@/components/ui/hover-card'; import { HoverCard, HoverCardTrigger, HoverCardContent } from '@/components/ui/hover-card';
import { shortPersonaValueLabel } from './persona-display'; import { shortPersonaValueLabel, compactPersonaValue } from './persona-display';
import { PersonaFeatureHover } from './persona-feature-hover'; import { PersonaFeatureHover } from './persona-feature-hover';
import { ReasonLine } from './reason-line'; import { ReasonLine } from './reason-line';
import { ScriptView, type ScriptViewMode } from './script-viewer'; import { ScriptView, type ScriptViewMode } from './script-viewer';
...@@ -1630,7 +1630,7 @@ function PersonaTagCloud({ features }: { features: typeof mockPersona.features } ...@@ -1630,7 +1630,7 @@ function PersonaTagCloud({ features }: { features: typeof mockPersona.features }
<div className="flex flex-wrap gap-1.5"> <div className="flex flex-wrap gap-1.5">
{features.map((f) => { {features.map((f) => {
const T = tone(f.tone); const T = tone(f.tone);
const short = shortPersonaValueLabel(f.value); const { text: short, more } = compactPersonaValue(f.value, f.data);
return ( return (
<PersonaFeatureHover key={f.key} featureKey={f.key} value={f.value}> <PersonaFeatureHover key={f.key} featureKey={f.key} value={f.value}>
<span <span
...@@ -1644,6 +1644,11 @@ function PersonaTagCloud({ features }: { features: typeof mockPersona.features } ...@@ -1644,6 +1644,11 @@ function PersonaTagCloud({ features }: { features: typeof mockPersona.features }
{short && short !== f.label && ( {short && short !== f.label && (
<span className="text-[10.5px] text-slate-700 truncate">{short}</span> <span className="text-[10.5px] text-slate-700 truncate">{short}</span>
)} )}
{more > 0 && (
<span className="flex-none text-[9.5px] font-medium text-slate-400 tabular-nums">
+{more}
</span>
)}
</span> </span>
</PersonaFeatureHover> </PersonaFeatureHover>
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment