(() => { /** * 文件职责:侧边导航组件,负责视图切换、目录快捷操作与仓库信息入口展示。 */ const { Box, Typography } = MaterialUI; function SidebarActionButton({ icon, label, onClick, iconStyle }) { return ( ); } function Sidebar({ currentView, onChange }) { const { state } = useAppContext(); // 版本号来自全局状态的 status 快照;未加载前先展示占位文本。 const version = state.status?.version || '...'; const unreadNotificationCount = Math.max(0, Number(state.notificationsMeta?.unread_count ?? 0)); const [logoSrc, setLogoSrc] = React.useState('/logo.png'); React.useEffect(() => { // 管理端可能被挂载在不同层级路径,依次尝试多个 logo 地址以提高兼容性。 const candidates = ['/logo.png', '../logo.png', 'logo.png']; let cancelled = false; async function resolveLogo() { for (const candidate of candidates) { try { const response = await fetch(candidate, { method: 'HEAD' }); if (response.ok) { if (!cancelled) setLogoSrc(candidate); return; } } catch (e) { // 某个候选地址失败并不代表整体失败,继续尝试下一个即可。 } } } resolveLogo(); return () => { cancelled = true; }; }, []); // 当前管理端开放的主导航项集中定义在这里,便于后续扩展新视图。 const menus = [ { key: 'status', label: '运行状态', icon: '📊' }, { key: 'tasks', label: '任务管理', icon: '📋' }, { key: 'notifications', label: '通知中心', icon: '🔔' }, { key: 'docs', label: '文档浏览', icon: '📚' }, { key: 'config', label: '配置管理', icon: '⚙️' }, ]; const openDirectory = async (path) => { try { // 通过后端调用本机资源管理器打开目录,前端无需感知具体平台命令。 const response = await window.HttpUtil.post('/api/open-directory', { path }); if (!response || response.ok === false) { // 读取后端可能传回来的错误描述与详细 message const errorTitle = response?.error || '打开目录失败'; const errorMsg = response?.message ? `\n详情: ${response.message}` : ''; throw new Error(`${errorTitle}${errorMsg}`); } // 可选:如果是 Docker 环境等虽然成功响应但并非打开了窗口的场景,给出提示 if (response.message && response.message.includes('已在系统文件管理器中打开目录')) { // 正常打开,可以什么都不做,也可以给个轻提示 console.log(response.message); } } catch (e) { const message = e?.message || '打开目录失败'; window.alert(message); } }; return (