Skip to content

Commit 636efbe

Browse files
committed
feat: Replace inline related pages component with reusable RelatedPages component
- Introduce NavigationContext for centralized navigation handling - Refactor RelatedPages component to use context-based navigation - Replace hardcoded related pages section in EndToEndWalkthrough with reusable component - Move related pages logic from SessionPersistence into reusable component - Update component API to remove onNavigate prop and use navigate function from context - Standardize related pages display across pages using new component
1 parent f63856b commit 636efbe

8 files changed

Lines changed: 82 additions & 186 deletions

src/components/RelatedPages.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
interface RelatedPage {
1+
import { useNavigation } from '../contexts/NavigationContext';
2+
3+
export interface RelatedPage {
24
id: string;
35
label: string;
46
description?: string;
@@ -7,10 +9,11 @@ interface RelatedPage {
79
interface RelatedPagesProps {
810
title?: string;
911
pages: RelatedPage[];
10-
onNavigate?: (id: string) => void;
1112
}
1213

13-
export function RelatedPages({ title = '🔗 相关阅读', pages, onNavigate }: RelatedPagesProps) {
14+
export function RelatedPages({ title = '🔗 相关阅读', pages }: RelatedPagesProps) {
15+
const { navigate } = useNavigation();
16+
1417
return (
1518
<div className="mt-8 p-5 bg-[var(--bg-panel)] rounded-xl border border-[var(--border-subtle)]">
1619
<h3 className="text-sm font-bold font-mono text-[var(--text-muted)] mb-4 flex items-center gap-2">
@@ -20,7 +23,7 @@ export function RelatedPages({ title = '🔗 相关阅读', pages, onNavigate }:
2023
{pages.map((page) => (
2124
<button
2225
key={page.id}
23-
onClick={() => onNavigate?.(page.id)}
26+
onClick={() => navigate(page.id)}
2427
className="text-left p-3 bg-[var(--bg-card)] rounded-lg border border-[var(--border-subtle)] hover:border-[var(--terminal-green)] hover:bg-[var(--terminal-green)]/5 transition-all group"
2528
>
2629
<div className="font-mono text-sm text-[var(--text-primary)] group-hover:text-[var(--terminal-green)] flex items-center gap-2">

src/pages/EndToEndWalkthrough.tsx

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState } from 'react';
22
import { Layer } from '../components/Layer';
33
import { HighlightBox } from '../components/HighlightBox';
44
import { MermaidDiagram } from '../components/MermaidDiagram';
5+
import { RelatedPages } from '../components/RelatedPages';
56

67
// ============================================================
78
// 端到端走读 - 一次完整请求的全流程解析
@@ -527,26 +528,19 @@ data: [DONE]`}
527528
</Layer>
528529

529530
{/* 相关页面 */}
530-
<div className="mt-8 p-6 rounded-xl bg-gray-800/30 border border-gray-700">
531-
<h3 className="text-lg font-semibold text-gray-200 mb-4">细节页建议配合阅读</h3>
532-
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
533-
{[
534-
{ title: '请求生命周期', desc: '详细流程' },
535-
{ title: '交互主循环', desc: '核心循环' },
536-
{ title: '工具调度详解', desc: '调度逻辑' },
537-
{ title: '审批模式', desc: '安全门禁' },
538-
{ title: '沙箱系统', desc: '隔离执行' },
539-
{ title: 'Token 计费', desc: '成本控制' },
540-
{ title: '循环检测', desc: '防死循环' },
541-
{ title: '会话持久化', desc: '状态保存' },
542-
].map((item, i) => (
543-
<div key={i} className="p-3 bg-gray-800/50 rounded border border-gray-700 text-center">
544-
<div className="text-cyan-400">{item.title}</div>
545-
<div className="text-gray-500 text-xs">{item.desc}</div>
546-
</div>
547-
))}
548-
</div>
549-
</div>
531+
<RelatedPages
532+
title="📚 细节页建议配合阅读"
533+
pages={[
534+
{ id: 'lifecycle', label: '请求生命周期', description: '详细流程' },
535+
{ id: 'interaction-loop', label: '交互主循环', description: '核心循环' },
536+
{ id: 'tool-scheduler', label: '工具调度详解', description: '调度逻辑' },
537+
{ id: 'approval-mode', label: '审批模式', description: '安全门禁' },
538+
{ id: 'sandbox', label: '沙箱系统', description: '隔离执行' },
539+
{ id: 'token-accounting', label: 'Token 计费', description: '成本控制' },
540+
{ id: 'loop-detect', label: '循环检测', description: '防死循环' },
541+
{ id: 'session-persistence', label: '会话持久化', description: '状态保存' },
542+
]}
543+
/>
550544
</div>
551545
);
552546
}

src/pages/SessionPersistence.tsx

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState } from 'react';
2+
import { RelatedPages } from '../components/RelatedPages';
23

34
// ============================================================
45
// Session 持久化与上下文压缩 - 深度解析页面
@@ -635,35 +636,15 @@ function BestPracticesSection() {
635636
);
636637
}
637638

638-
// 关联页面
639-
function RelatedPagesSection() {
640-
const pages = [
641-
{ id: 'turn-state-machine', label: 'Turn 状态机', desc: '了解 CompressionStatus 的来源' },
642-
{ id: 'token-accounting', label: 'Token 计费系统', desc: '了解 Token 计数机制' },
643-
{ id: 'memory', label: '上下文管理', desc: '了解整体内存管理策略' },
644-
{ id: 'checkpointing', label: '检查点恢复', desc: '了解 Git 级别的恢复机制' },
645-
{ id: 'history-compression-anim', label: '历史压缩动画', desc: '可视化压缩过程' },
646-
{ id: 'chat-compression-anim', label: '聊天压缩动画', desc: '分割点选择可视化' },
647-
];
648-
649-
return (
650-
<div className="mt-8 p-6 bg-gray-800/30 rounded-xl border border-gray-700/50">
651-
<h3 className="text-lg font-semibold text-gray-200 mb-4">📚 相关页面</h3>
652-
<div className="grid grid-cols-2 gap-3">
653-
{pages.map((page) => (
654-
<a
655-
key={page.id}
656-
href={`?tab=${page.id}`}
657-
className="p-3 bg-gray-900/50 rounded-lg hover:bg-gray-700/50 transition-colors group"
658-
>
659-
<div className="text-cyan-400 group-hover:text-cyan-300 font-medium">{page.label}</div>
660-
<div className="text-xs text-gray-500 mt-1">{page.desc}</div>
661-
</a>
662-
))}
663-
</div>
664-
</div>
665-
);
666-
}
639+
// 关联页面配置
640+
const sessionRelatedPages = [
641+
{ id: 'turn-state-machine', label: 'Turn 状态机', description: '了解 CompressionStatus 的来源' },
642+
{ id: 'token-accounting', label: 'Token 计费系统', description: '了解 Token 计数机制' },
643+
{ id: 'memory', label: '上下文管理', description: '了解整体内存管理策略' },
644+
{ id: 'checkpointing', label: '检查点恢复', description: '了解 Git 级别的恢复机制' },
645+
{ id: 'history-compression-anim', label: '历史压缩动画', description: '可视化压缩过程' },
646+
{ id: 'chat-compression-anim', label: '聊天压缩动画', description: '分割点选择可视化' },
647+
];
667648

668649
// 主组件
669650
export function SessionPersistence() {
@@ -707,7 +688,7 @@ export function SessionPersistence() {
707688
<BestPracticesSection />
708689
</CollapsibleSection>
709690

710-
<RelatedPagesSection />
691+
<RelatedPages title="📚 相关页面" pages={sessionRelatedPages} />
711692
</div>
712693
);
713694
}

src/pages/SubagentArchitecture.tsx

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useState } from 'react';
22
import { CodeBlock } from '../components/CodeBlock';
33
import { MermaidDiagram } from '../components/MermaidDiagram';
4+
import { RelatedPages } from '../components/RelatedPages';
45

56
export function SubagentArchitecture() {
67
const [expandedSections, setExpandedSections] = useState<Set<string>>(
@@ -934,34 +935,14 @@ const estimatedCost = this.inputTokens * 3e-5 + this.outputTokens * 6e-5;
934935
</section>
935936

936937
{/* 相关页面 */}
937-
<section className="bg-[var(--bg-card)] rounded-xl p-6 border border-[var(--border-subtle)]">
938-
<h2 className="text-xl font-bold text-[var(--text-primary)] mb-4">
939-
🔗 相关页面
940-
</h2>
941-
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
942-
<a
943-
href="?tab=subagent"
944-
className="block p-4 bg-[var(--bg-terminal)]/50 rounded-lg hover:bg-[var(--bg-terminal)] transition-colors"
945-
>
946-
<div className="text-[var(--terminal-green)] font-bold">子代理系统概览</div>
947-
<div className="text-xs text-[var(--text-muted)]">基础概念和快速入门</div>
948-
</a>
949-
<a
950-
href="?tab=subagent-anim"
951-
className="block p-4 bg-[var(--bg-terminal)]/50 rounded-lg hover:bg-[var(--bg-terminal)] transition-colors"
952-
>
953-
<div className="text-[var(--cyber-blue)] font-bold">子代理执行动画</div>
954-
<div className="text-xs text-[var(--text-muted)]">可视化执行流程</div>
955-
</a>
956-
<a
957-
href="?tab=subagent-resolution-anim"
958-
className="block p-4 bg-[var(--bg-terminal)]/50 rounded-lg hover:bg-[var(--bg-terminal)] transition-colors"
959-
>
960-
<div className="text-[var(--amber)] font-bold">优先级解析动画</div>
961-
<div className="text-xs text-[var(--text-muted)]">三级优先级可视化</div>
962-
</a>
963-
</div>
964-
</section>
938+
<RelatedPages
939+
title="🔗 相关页面"
940+
pages={[
941+
{ id: 'subagent', label: '子代理系统概览', description: '基础概念和快速入门' },
942+
{ id: 'subagent-anim', label: '子代理执行动画', description: '可视化执行流程' },
943+
{ id: 'subagent-resolution-anim', label: '优先级解析动画', description: '三级优先级可视化' },
944+
]}
945+
/>
965946
</div>
966947
);
967948
}

src/pages/TelemetrySystem.tsx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { HighlightBox } from '../components/HighlightBox';
22
import { MermaidDiagram } from '../components/MermaidDiagram';
33
import { CodeBlock } from '../components/CodeBlock';
4+
import { RelatedPages } from '../components/RelatedPages';
45

56
export function TelemetrySystem() {
67
// 30秒速览
@@ -1139,27 +1140,15 @@ export const EVENT_PERFORMANCE_REGRESSION = 'qwen-code.performance.regression';`
11391140
</section>
11401141

11411142
{/* 相关页面 */}
1142-
<section>
1143-
<h3 className="text-xl font-semibold text-cyan-400 mb-4">相关页面</h3>
1144-
<div className="grid grid-cols-2 md:grid-cols-4 gap-2">
1145-
<div className="bg-gray-800/50 rounded p-3 text-center">
1146-
<span className="text-cyan-400">配置系统</span>
1147-
<p className="text-xs text-gray-400 mt-1">遥测配置选项</p>
1148-
</div>
1149-
<div className="bg-gray-800/50 rounded p-3 text-center">
1150-
<span className="text-cyan-400">上下文管理</span>
1151-
<p className="text-xs text-gray-400 mt-1">压缩事件记录</p>
1152-
</div>
1153-
<div className="bg-gray-800/50 rounded p-3 text-center">
1154-
<span className="text-cyan-400">工具系统</span>
1155-
<p className="text-xs text-gray-400 mt-1">工具调用指标</p>
1156-
</div>
1157-
<div className="bg-gray-800/50 rounded p-3 text-center">
1158-
<span className="text-cyan-400">子代理系统</span>
1159-
<p className="text-xs text-gray-400 mt-1">子代理执行指标</p>
1160-
</div>
1161-
</div>
1162-
</section>
1143+
<RelatedPages
1144+
title="🔗 相关页面"
1145+
pages={[
1146+
{ id: 'config', label: '配置系统', description: '遥测配置选项' },
1147+
{ id: 'memory', label: '上下文管理', description: '压缩事件记录' },
1148+
{ id: 'tool-arch', label: '工具架构', description: '工具调用指标' },
1149+
{ id: 'subagent', label: '子代理系统', description: '子代理执行指标' },
1150+
]}
1151+
/>
11631152
</div>
11641153
);
11651154
}

src/pages/ToolDeveloperGuide.tsx

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState } from 'react';
2+
import { RelatedPages } from '../components/RelatedPages';
23

34
// ============================================================
45
// 工具开发者指南 - 如何为 Qwen CLI 开发自定义工具
@@ -625,34 +626,14 @@ describe('WordCountTool', () => {
625626
);
626627
}
627628

628-
// 关联页面
629-
function RelatedPagesSection() {
630-
const pages = [
631-
{ id: 'tool-ref', label: '工具参考', desc: '所有内置工具的完整文档' },
632-
{ id: 'tool-scheduler', label: '工具调度详解', desc: '了解工具如何被调度执行' },
633-
{ id: 'tool-arch', label: '工具架构', desc: '工具系统的整体架构' },
634-
{ id: 'approval-mode', label: '审批模式', desc: '了解权限审批机制' },
635-
{ id: 'tool-scheduler-anim', label: '工具调度动画', desc: '可视化调度过程' },
636-
];
637-
638-
return (
639-
<div className="mt-8 p-6 bg-gray-800/30 rounded-xl border border-gray-700/50">
640-
<h3 className="text-lg font-semibold text-gray-200 mb-4">📚 相关页面</h3>
641-
<div className="grid grid-cols-2 gap-3">
642-
{pages.map((page) => (
643-
<a
644-
key={page.id}
645-
href={`?tab=${page.id}`}
646-
className="p-3 bg-gray-900/50 rounded-lg hover:bg-gray-700/50 transition-colors group"
647-
>
648-
<div className="text-cyan-400 group-hover:text-cyan-300 font-medium">{page.label}</div>
649-
<div className="text-xs text-gray-500 mt-1">{page.desc}</div>
650-
</a>
651-
))}
652-
</div>
653-
</div>
654-
);
655-
}
629+
// 关联页面配置
630+
const toolDevRelatedPages = [
631+
{ id: 'tool-ref', label: '工具参考', description: '所有内置工具的完整文档' },
632+
{ id: 'tool-scheduler', label: '工具调度详解', description: '了解工具如何被调度执行' },
633+
{ id: 'tool-arch', label: '工具架构', description: '工具系统的整体架构' },
634+
{ id: 'approval-mode', label: '审批模式', description: '了解权限审批机制' },
635+
{ id: 'tool-scheduler-anim', label: '工具调度动画', description: '可视化调度过程' },
636+
];
656637

657638
// 主组件
658639
export function ToolDeveloperGuide() {
@@ -696,7 +677,7 @@ export function ToolDeveloperGuide() {
696677
<BestPracticesSection />
697678
</CollapsibleSection>
698679

699-
<RelatedPagesSection />
680+
<RelatedPages title="📚 相关页面" pages={toolDevRelatedPages} />
700681
</div>
701682
);
702683
}

src/pages/TurnStateMachine.tsx

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useState } from 'react';
22
import { CodeBlock } from '../components/CodeBlock';
3+
import { RelatedPages } from '../components/RelatedPages';
34

45
/**
56
* Turn 状态机深度解析
@@ -682,38 +683,15 @@ function CompressionStatusSection() {
682683
);
683684
}
684685

685-
// ===== Related Pages Section =====
686-
function RelatedPagesSection() {
687-
const relatedPages = [
688-
{ id: 'gemini-chat', label: 'GeminiChat 核心循环', icon: '🔄' },
689-
{ id: 'lifecycle', label: '请求生命周期', icon: '🔁' },
690-
{ id: 'tool-scheduler', label: '工具调度详解', icon: '🔧' },
691-
{ id: 'context-compression-anim', label: '上下文压缩动画', icon: '📦' },
692-
{ id: 'turn-internal-anim', label: 'Turn 状态流转动画', icon: '🎬' },
693-
{ id: 'loop-detect', label: '循环检测', icon: '🔁' },
694-
];
695-
696-
return (
697-
<div className="mb-8">
698-
<h2 className="text-xl font-bold text-gray-100 mb-4 flex items-center gap-2">
699-
<span>🔗</span> 相关页面
700-
</h2>
701-
702-
<div className="grid grid-cols-2 md:grid-cols-3 gap-2">
703-
{relatedPages.map((page) => (
704-
<a
705-
key={page.id}
706-
href={`?tab=${page.id}`}
707-
className="flex items-center gap-2 p-3 bg-gray-800/50 rounded-lg border border-gray-700 hover:border-purple-500/50 hover:bg-purple-900/20 transition-all"
708-
>
709-
<span className="text-xl">{page.icon}</span>
710-
<span className="text-sm text-gray-300">{page.label}</span>
711-
</a>
712-
))}
713-
</div>
714-
</div>
715-
);
716-
}
686+
// 关联页面配置
687+
const turnRelatedPages = [
688+
{ id: 'gemini-chat', label: '🔄 GeminiChat 核心循环' },
689+
{ id: 'lifecycle', label: '🔁 请求生命周期' },
690+
{ id: 'tool-scheduler', label: '🔧 工具调度详解' },
691+
{ id: 'context-compression-anim', label: '📦 上下文压缩动画' },
692+
{ id: 'turn-internal-anim', label: '🎬 Turn 状态流转动画' },
693+
{ id: 'loop-detect', label: '🔁 循环检测' },
694+
];
717695

718696
// ===== Main Component =====
719697
export function TurnStateMachine() {
@@ -739,7 +717,7 @@ export function TurnStateMachine() {
739717
<DesignRationaleSection />
740718
<CompressionStatusSection />
741719
<CoreCodeSection />
742-
<RelatedPagesSection />
720+
<RelatedPages title="🔗 相关页面" pages={turnRelatedPages} />
743721
</div>
744722
);
745723
}

0 commit comments

Comments
 (0)