Why: The first S4 pass makes the project the navigation context, keeps deep views in one overlay, and leaves domain panels empty until a plugin declares them. Evidence: npx tsc -b and npm test (61 passed) in modules/frontend. Impact: Top bar, project sidebar, inbox all/todo filter, one-way scroll sync, drag-and-drop on the whole chat column, and local molv/system themes. Refs: feature/s4-shell-overhaul Co-authored-by: Cursor <cursoragent@cursor.com>
25 lines
1.1 KiB
TypeScript
25 lines
1.1 KiB
TypeScript
// 顶栏:产品标识、当前项目与阶段徽章、待处理铃铛。不参与具体操作。
|
|
import { BrandMark, Icon, pendingCount } from '@ui'
|
|
import { store, useStore } from '../store'
|
|
import { projectStage } from '../projectmeta'
|
|
|
|
export function TopBar() {
|
|
const project = useStore(s => s.projects.find(p => p.id === s.currentProjectId))
|
|
const pending = useStore(s => pendingCount(s.cards) + pendingCount(s.projectCards))
|
|
const stage = projectStage(project?.settings)
|
|
return (
|
|
<header className="topbar">
|
|
<BrandMark size={22} />
|
|
<span className="topbar-name">Agent-System</span>
|
|
{project && <span className="topbar-project" title="当前项目">{project.name}</span>}
|
|
{stage && <span className="topbar-stage" title="当前阶段">{stage}</span>}
|
|
<span className="topbar-spacer" />
|
|
<button className="topbar-bell" title={pending > 0 ? `待处理 ${pending},打开收件箱` : '收件箱'}
|
|
onClick={() => store.focusPending()}>
|
|
<Icon name="inbox" size={16} />
|
|
{pending > 0 && <span className="rail-badge" data-testid="topbar-pending">{pending}</span>}
|
|
</button>
|
|
</header>
|
|
)
|
|
}
|