feat(console): 任务树筛选/折叠/统一标题 + 侧栏全局Agent卡片/拖拽排序/全局设置弹框/记忆项目 + 状态点真实化

任务树:四维多选下拉筛选(状态/复杂度/优先级/执行者)、已选置顶、新建任务按钮移右上角(0任务也能建)。
四块主区(Agent/审批闸/任务树/归档)统一标题组件(图标+名称+数量徽标)+ 折叠按钮(localStorage 记忆)。
侧栏:全局 Agent 弹层改常驻卡片(项目默认3+折叠+按活跃排序)、顶部项目拖拽排序、全局设置移入用户菜单弹框(保存/取消,落库)、记忆当前项目。
adaptProject 用后端 summary 的 running/attention 判状态点颜色(青/琥珀/灰)+ 紫色关注数徽标;agent 标题不再越界;i18n 5 语言补全。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-29 11:30:32 +08:00
parent 43fa1f7dbb
commit 8765e61498
9 changed files with 430 additions and 194 deletions
+8 -6
View File
@@ -47,20 +47,22 @@ function GatePreview({ item, t, onDecide, onClose }) {
// 审批闸区:斜纹条 + GateCard 列表(accept/reject + 驳回必填理由)
function GateSection({ approvals, onDecide, t }) {
const { GateCard, GateStripe, Button, Textarea, SectionHead } = window.MaestroDesignSystem_a6a290;
const { GateCard, GateStripe, Button, Textarea } = window.MaestroDesignSystem_a6a290;
const [rejecting, setRejecting] = React.useState(null);
const [reason, setReason] = React.useState('');
const [preview, setPreview] = React.useState(null);
const [sectionFolded, setSectionFolded] = React.useState(() => localStorage.getItem('maestro-kit-fold-gate') === '1');
const toggleSectionFold = () => setSectionFolded((f) => { localStorage.setItem('maestro-kit-fold-gate', f ? '0' : '1'); return !f; });
const [folded, setFolded] = React.useState(() => new Set());
const toggleFold = (id) => setFolded((prev) => {
const next = new Set(prev); next.has(id) ? next.delete(id) : next.add(id); return next;
});
if (approvals.length === 0) return null;
return (
<section style={{ marginTop: 18 }}>
<GateStripe />
<SectionHead mark="violet" title={t.gateSection} style={{ paddingTop: 12, color: 'var(--violet)' }} />
{approvals.map((a) => {
<section>
<window.MaestroKitSectionHead icon="gate" title={t.gateSection} count={approvals.length} accent="var(--violet)" folded={sectionFolded} onToggleFold={toggleSectionFold} t={t} />
{!sectionFolded ? <GateStripe /> : null}
{!sectionFolded ? approvals.map((a) => {
const isFolded = folded.has(a.id);
return (
<div key={a.id} style={{ marginBottom: 12 }}>
@@ -93,7 +95,7 @@ function GateSection({ approvals, onDecide, t }) {
</GateCard>
</div>
);
})}
}) : null}
<GatePreview item={preview} t={t} onDecide={onDecide} onClose={() => setPreview(null)} />
</section>
);