mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-16 19:29:26 +02:00
fix(issues): polish comment trigger chip presentation (#4002)
- Copy: one fixed sentence for single and stacked chips — the avatar(s)
carry who and how many, the text carries condition + outcome
("发送后开始工作" / "Starts working when sent"), killing the
"is it already running?" misread. Drops the per-name and count keys.
- Color: sidebar-style resting state — muted-foreground until hover so
the strip reads as metadata, not content.
- Motion: pure fade-in (no slide offset).
- Spacing: reply composer reserves pb-9 so the chip strip reads as a
footer instead of a second content line glued to the text.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,14 +45,14 @@ describe("CommentTriggerChips", () => {
|
||||
);
|
||||
|
||||
const chip = screen.getByRole("button");
|
||||
expect(chip).toHaveTextContent("Walt will start working");
|
||||
expect(chip).toHaveTextContent("Starts working when sent");
|
||||
expect(chip).toHaveAttribute("aria-pressed", "false");
|
||||
|
||||
fireEvent.click(chip);
|
||||
expect(onToggle).toHaveBeenCalledWith("agent-1");
|
||||
});
|
||||
|
||||
it("dims a suppressed single agent into the skip sentence", () => {
|
||||
it("dims a suppressed single agent into the skip state", () => {
|
||||
renderWithI18n(
|
||||
<CommentTriggerChips
|
||||
agents={[walt]}
|
||||
@@ -62,11 +62,11 @@ describe("CommentTriggerChips", () => {
|
||||
);
|
||||
|
||||
const chip = screen.getByRole("button");
|
||||
expect(chip).toHaveTextContent("Walt won't be triggered this time");
|
||||
expect(chip).toHaveTextContent("not this time");
|
||||
expect(chip).toHaveAttribute("aria-pressed", "true");
|
||||
});
|
||||
|
||||
it("collapses several agents into a stack with an active count", () => {
|
||||
it("collapses several agents into a stack with the shared sentence", () => {
|
||||
renderWithI18n(
|
||||
<CommentTriggerChips
|
||||
agents={[walt, bob]}
|
||||
@@ -75,19 +75,19 @@ describe("CommentTriggerChips", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("button")).toHaveTextContent("2 agents will start working");
|
||||
expect(screen.getByRole("button")).toHaveTextContent("Starts working when sent");
|
||||
});
|
||||
|
||||
it("counts only non-suppressed agents in the sentence", () => {
|
||||
it("switches to the skip state when every agent is suppressed", () => {
|
||||
renderWithI18n(
|
||||
<CommentTriggerChips
|
||||
agents={[walt, bob]}
|
||||
suppressedAgentIds={new Set(["agent-2"])}
|
||||
suppressedAgentIds={new Set(["agent-1", "agent-2"])}
|
||||
onToggle={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("button")).toHaveTextContent("1 agent will start working");
|
||||
expect(screen.getByRole("button")).toHaveTextContent("not this time");
|
||||
});
|
||||
|
||||
it("opens the popover on click and toggles a row", () => {
|
||||
|
||||
@@ -148,9 +148,11 @@ function SingleTriggerChip({
|
||||
t: IssuesT;
|
||||
}) {
|
||||
const state = suppressed ? t(($) => $.comment.trigger_suppressed) : sourceLabel(agent.source, t);
|
||||
// The avatar carries "who"; the sentence carries only condition + outcome,
|
||||
// so it stays fixed-width and never truncates on long agent names.
|
||||
const sentence = suppressed
|
||||
? t(($) => $.comment.trigger_will_skip, { name: agent.name })
|
||||
: t(($) => $.comment.trigger_will_start, { name: agent.name });
|
||||
? t(($) => $.comment.trigger_suppressed)
|
||||
: t(($) => $.comment.trigger_will_start);
|
||||
|
||||
return (
|
||||
<Tooltip>
|
||||
@@ -162,8 +164,10 @@ function SingleTriggerChip({
|
||||
aria-label={t(($) => $.comment.trigger_chip_aria, { name: agent.name, state })}
|
||||
onClick={() => onToggle(agent.id)}
|
||||
className={cn(
|
||||
"inline-flex h-6 min-w-0 max-w-full animate-in fade-in slide-in-from-bottom-1 cursor-pointer items-center gap-1.5 rounded-md px-1.5 text-[11px] font-medium transition-colors duration-200 hover:bg-muted hover:text-foreground",
|
||||
suppressed ? "text-muted-foreground opacity-60" : "text-foreground",
|
||||
// Sidebar-style resting state: muted until hover so the strip
|
||||
// reads as metadata, not content (see app-sidebar nav items).
|
||||
"inline-flex h-6 min-w-0 max-w-full animate-in fade-in cursor-pointer items-center gap-1.5 rounded-md px-1.5 text-[11px] font-medium text-muted-foreground transition-colors duration-200 hover:bg-muted hover:text-foreground",
|
||||
suppressed && "opacity-60",
|
||||
)}
|
||||
>
|
||||
<TriggerAgentAvatar agent={agent} suppressed={suppressed} />
|
||||
@@ -197,10 +201,12 @@ function MultiTriggerChip({
|
||||
// Mirror AgentAvatarStack: ~30% overlap reads as "stacked" without
|
||||
// obscuring the next avatar.
|
||||
const overlap = Math.round(AVATAR_SIZE * 0.3);
|
||||
// The avatar stack already shows who and how many — the sentence is the
|
||||
// same fixed condition + outcome copy as the single chip.
|
||||
const sentence =
|
||||
activeCount === 0
|
||||
? t(($) => $.comment.trigger_suppressed)
|
||||
: t(($) => $.comment.trigger_will_start_count, { count: activeCount });
|
||||
: t(($) => $.comment.trigger_will_start);
|
||||
|
||||
const popoverTrigger = (
|
||||
<PopoverTrigger
|
||||
@@ -210,8 +216,8 @@ function MultiTriggerChip({
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"inline-flex h-6 min-w-0 max-w-full animate-in fade-in slide-in-from-bottom-1 cursor-pointer items-center gap-1.5 rounded-md px-1.5 text-[11px] font-medium transition-colors duration-200 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
||||
activeCount === 0 ? "text-muted-foreground opacity-60" : "text-foreground",
|
||||
"inline-flex h-6 min-w-0 max-w-full animate-in fade-in cursor-pointer items-center gap-1.5 rounded-md px-1.5 text-[11px] font-medium text-muted-foreground transition-colors duration-200 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
||||
activeCount === 0 && "opacity-60",
|
||||
)}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ function ReplyInput({
|
||||
{...dropZoneProps}
|
||||
className={cn(
|
||||
"relative min-w-0 flex-1 flex flex-col",
|
||||
!isEmpty && "pb-7",
|
||||
!isEmpty && "pb-9",
|
||||
)}
|
||||
>
|
||||
<div className="flex-1 min-h-0 overflow-y-auto">
|
||||
|
||||
@@ -284,10 +284,7 @@
|
||||
"trigger_reason_mention_agent": "{{name}} is mentioned in this comment.",
|
||||
"trigger_reason_mention_squad_leader": "{{name}} leads a squad mentioned in this comment.",
|
||||
"trigger_reason_unknown": "{{name}} will be triggered by this comment.",
|
||||
"trigger_will_start": "{{name}} will start working",
|
||||
"trigger_will_skip": "{{name}} won't be triggered this time",
|
||||
"trigger_will_start_count_one": "{{count}} agent will start working",
|
||||
"trigger_will_start_count_other": "{{count}} agents will start working",
|
||||
"trigger_will_start": "Starts working when sent",
|
||||
"trigger_starts_now": "It will start working right away.",
|
||||
"trigger_starts_when_online": "It is offline now and will start once online.",
|
||||
"trigger_click_to_skip": "Click to skip triggering this time.",
|
||||
|
||||
@@ -276,9 +276,7 @@
|
||||
"trigger_reason_mention_agent": "このコメントで {{name}} がメンションされています。",
|
||||
"trigger_reason_mention_squad_leader": "{{name}} はメンションされた Squad のリーダーです。",
|
||||
"trigger_reason_unknown": "このコメントで {{name}} がトリガーされます。",
|
||||
"trigger_will_start": "{{name}} が作業を開始します",
|
||||
"trigger_will_skip": "{{name}} は今回トリガーされません",
|
||||
"trigger_will_start_count_other": "{{count}} 体のエージェントが作業を開始します",
|
||||
"trigger_will_start": "送信後に作業を開始します",
|
||||
"trigger_starts_now": "すぐに作業を開始します。",
|
||||
"trigger_starts_when_online": "現在オフラインのため、オンラインになり次第開始します。",
|
||||
"trigger_click_to_skip": "クリックすると今回はトリガーされません。",
|
||||
|
||||
@@ -284,9 +284,7 @@
|
||||
"trigger_reason_mention_agent": "이 댓글에서 {{name}}님을 멘션했습니다.",
|
||||
"trigger_reason_mention_squad_leader": "{{name}}님은 멘션된 Squad의 리더입니다.",
|
||||
"trigger_reason_unknown": "이 댓글로 {{name}}님이 트리거됩니다.",
|
||||
"trigger_will_start": "{{name}}이(가) 작업을 시작합니다",
|
||||
"trigger_will_skip": "{{name}}은(는) 이번에 트리거되지 않습니다",
|
||||
"trigger_will_start_count_other": "에이전트 {{count}}개가 작업을 시작합니다",
|
||||
"trigger_will_start": "전송 후 작업을 시작합니다",
|
||||
"trigger_starts_now": "바로 작업을 시작합니다.",
|
||||
"trigger_starts_when_online": "현재 오프라인이며 온라인이 되면 시작합니다.",
|
||||
"trigger_click_to_skip": "클릭하면 이번에는 트리거되지 않습니다.",
|
||||
|
||||
@@ -281,9 +281,7 @@
|
||||
"trigger_reason_mention_agent": "这条评论 @ 了 {{name}}。",
|
||||
"trigger_reason_mention_squad_leader": "{{name}} 是被 @ Squad 的 leader。",
|
||||
"trigger_reason_unknown": "这条评论会触发 {{name}}。",
|
||||
"trigger_will_start": "{{name}} 将开始工作",
|
||||
"trigger_will_skip": "{{name}} 本次不触发",
|
||||
"trigger_will_start_count_other": "{{count}} 个智能体将开始工作",
|
||||
"trigger_will_start": "发送后开始工作",
|
||||
"trigger_starts_now": "将立即开始工作。",
|
||||
"trigger_starts_when_online": "当前离线,上线后开始。",
|
||||
"trigger_click_to_skip": "点击后本次不触发。",
|
||||
|
||||
Reference in New Issue
Block a user