Files
AgentCompany/src/renderer/components/communication/ChannelHeader.tsx
T
ZacharyZhang-NY 3608578ba3 refactor(communication): localize ChannelHeader strings; bump tiny chips from 9px to 10px
Stragglers from the Communication audit that did not fit into C10's
FilterBar scope:

- ChannelHeader carried two hardcoded English strings: the sidebar
  reveal button's aria-label ("Show sidebar") and the "Open task"
  link that appears on task-discussion channels. Both now go through
  i18n — added `comm.showSidebar` ("显示侧边栏" / "Show sidebar") and
  reused the existing `comm.openTask` key. Users running in Chinese
  now get a fully Chinese header.

- MessageBubble had two 9px uppercase chips (department badge and
  priority badge). 9px with tracking is unreadable at standard display
  density; bumped both to 10px and loosened the tracking slightly so
  the letters don't collide. Same typography decision we made for
  the OrgChart connector label in C3.

Covers the remaining Communication audit items. J-C1 (resizable
sidebar) and J-C6 (resizable ThreadPanel) are feature additions and
stay out of scope per the audit's "bug fix only" contract.
2026-04-17 20:16:43 -04:00

81 lines
2.3 KiB
TypeScript

import type { AgentMessageRecord, CommentRecord, TaskRecord, MessageChannel } from "@shared/types"
import { CaretDown } from "../ui/icons"
import { useT } from "../../i18n"
export interface ChannelDescriptor {
key: string
kind: "message"
channel: MessageChannel
label: string
targetId: string | null
agentId: string | null
participantIds: string[]
}
export interface TaskDiscussionDescriptor {
key: string
kind: "task"
taskId: string
label: string
}
export type AnyChannel = ChannelDescriptor | TaskDiscussionDescriptor
interface ChannelHeaderProps {
activeChannel: AnyChannel | null
showSidebar: boolean
onShowSidebar: () => void
channelMessages: AgentMessageRecord[]
taskDiscussionComments: CommentRecord[]
activeTask: TaskRecord | null
unreadByChannel: Map<string, { unread: number; hasUrgent: boolean }>
onNavigateToTask: (taskId: string) => void
filterBar: React.ReactNode
}
export function ChannelHeader({
activeChannel,
showSidebar,
onShowSidebar,
channelMessages: _channelMessages,
taskDiscussionComments: _taskDiscussionComments,
activeTask,
unreadByChannel: _unreadByChannel,
onNavigateToTask,
filterBar,
}: ChannelHeaderProps) {
const t = useT()
return (
<div className="flex items-center gap-3 border-b border-border bg-card px-4 py-2.5">
{!showSidebar ? (
<button
type="button"
onClick={onShowSidebar}
className="rounded-[4px] p-1 text-muted-foreground transition hover:text-foreground"
aria-label={t("comm.showSidebar")}
>
<CaretDown size={12} className="rotate-90" />
</button>
) : null}
{activeChannel ? (
<div className="min-w-0 flex-1">
<div className="truncate text-[13px] font-semibold text-foreground">{activeChannel.label}</div>
{activeChannel.kind === "task" && activeTask ? (
<button type="button" onClick={() => onNavigateToTask(activeTask.id)} className="mt-0.5 text-[11px] font-medium text-primary transition hover:underline">
{t("comm.openTask")}
</button>
) : null}
</div>
) : (
<span className="text-[13px] text-muted-foreground">{t("comm.selectChannel")}</span>
)}
<div className="ml-auto w-full max-w-[320px]">
{filterBar}
</div>
</div>
)
}