顶栏精简:移除 ⋯ 更多菜单,Mock 直达按钮 + 官网入口下沉侧栏
- 原 ⋯ 内容分流:设置/Mock/重置→设置弹窗已有;环境/主题/文档→顶栏已有按钮; 自动化测试→侧栏底部已有;官网与价格→侧栏底部新增链接 - Mock 数据作为核心能力提升为顶栏一键直达(烧瓶图标 → 设置 Mock 页) - 53 前端用例绿;顶栏近景截图评审通过
This commit is contained in:
1 parent
17528a7e9d
commit
522e5d6300
4 files changed
+20
-81
No files matched your search
Binary file not shown.
@@ -115,8 +115,8 @@ export function Sidebar() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 自动化测试入口 */}
|
||||
<div className="p-2" style={{ borderTop: "1px solid var(--border)" }}>
|
||||
{/* 自动化测试 / 官网入口 */}
|
||||
<div className="space-y-1.5 p-2" style={{ borderTop: "1px solid var(--border)" }}>
|
||||
<button
|
||||
className="ops-btn ops-btn-secondary w-full"
|
||||
onClick={() => useWorkspace.getState().setView("testing")}
|
||||
@@ -124,6 +124,15 @@ export function Sidebar() {
|
||||
>
|
||||
<Icon name="list-checks" size={13} /> 自动化测试
|
||||
</button>
|
||||
<a
|
||||
className="ops-btn ops-btn-ghost w-full text-[11px]"
|
||||
href="/home"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="官网与价格"
|
||||
>
|
||||
<Icon name="globe" size={11} /> 官网与价格
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ContextMenu menu={menu} onClose={() => setMenu(null)} />
|
||||
|
||||
@@ -197,7 +197,7 @@ export function TestingView() {
|
||||
<div className="ops-faint mt-1 text-xs leading-5">
|
||||
手动编排 · AI 生成 · 定时调度,三种方式共用同一套场景用例
|
||||
<br />
|
||||
左侧新建用例,或从「⋯ 菜单 → 自动化测试」随时返回
|
||||
左侧新建用例;侧栏底部「自动化测试」随时进出本视图
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 顶栏:logo / 新建 / 导入导出 / 环境 / 主题 / 文档 / 设置 / 更多。
|
||||
* 顶栏:logo / 新建 / 导入导出 / 环境 / Mock / 账号 / 主题 / 文档 / 设置。
|
||||
*/
|
||||
import { useEffect, useState } from "react";
|
||||
import { useWorkspace } from "../workspaceStore";
|
||||
@@ -30,7 +30,6 @@ export function TopBar() {
|
||||
|
||||
const [newMenu, setNewMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const [exportMenu, setExportMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const [moreMenu, setMoreMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const [spaceMenu, setSpaceMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const [accountMenu, setAccountMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const account = useWorkspace((s) => s.account);
|
||||
@@ -154,68 +153,6 @@ export function TopBar() {
|
||||
]
|
||||
: [];
|
||||
|
||||
const moreItems: MenuItem[] = [
|
||||
{
|
||||
label: "设置…",
|
||||
icon: <Icon name="settings" size={14} />,
|
||||
onClick: () => setDialog({ type: "settings" }),
|
||||
},
|
||||
{
|
||||
label: "Mock 数据…",
|
||||
icon: <Icon name="flask-conical" size={14} />,
|
||||
onClick: () => setDialog({ type: "settings", tab: "mock" }),
|
||||
},
|
||||
{
|
||||
label: "自动化测试",
|
||||
icon: <Icon name="list-checks" size={14} />,
|
||||
onClick: () => useWorkspace.getState().setView("testing"),
|
||||
},
|
||||
{
|
||||
label: "环境管理…",
|
||||
icon: <Icon name="arrow-left-right" size={14} />,
|
||||
onClick: () => setDialog({ type: "environments" }),
|
||||
},
|
||||
{
|
||||
label: settings.theme === "dark" ? "切换到浅色主题" : "切换到深色主题",
|
||||
icon: <Icon name={settings.theme === "dark" ? "sun" : "moon"} size={14} />,
|
||||
onClick: () => setTheme(settings.theme === "dark" ? "light" : "dark"),
|
||||
},
|
||||
{ type: "sep" as const },
|
||||
{
|
||||
label: (
|
||||
<span className="flex items-center gap-2">
|
||||
用户文档
|
||||
<Icon name="external-link" size={11} className="ops-faint" />
|
||||
</span>
|
||||
),
|
||||
icon: <Icon name="book-open" size={14} />,
|
||||
onClick: () => window.open("/docs", "_blank", "noopener,noreferrer"),
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<span className="flex items-center gap-2">
|
||||
官网与价格
|
||||
<Icon name="external-link" size={11} className="ops-faint" />
|
||||
</span>
|
||||
),
|
||||
icon: <Icon name="globe" size={14} />,
|
||||
onClick: () => window.open("/home", "_blank", "noopener,noreferrer"),
|
||||
},
|
||||
{ type: "sep" as const },
|
||||
{
|
||||
label: "重置工作区…",
|
||||
icon: <Icon name="trash" size={14} />,
|
||||
danger: true,
|
||||
onClick: () =>
|
||||
setDialog({
|
||||
type: "confirm",
|
||||
title: "重置工作区",
|
||||
message: "将恢复到初始示例数据,当前集合 / 环境 / 历史会被覆盖(建议先在「导出」中生成全量备份)。确定继续吗?",
|
||||
action: () => useWorkspace.getState().resetWorkspace(),
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<header
|
||||
className="ops-panel ops-divider flex h-12 shrink-0 items-center justify-between gap-3 px-4"
|
||||
@@ -286,6 +223,13 @@ export function TopBar() {
|
||||
<button className="ops-btn ops-btn-ghost" onClick={() => setDialog({ type: "environments" })} title="环境管理">
|
||||
<Icon name="settings" size={14} /> 环境
|
||||
</button>
|
||||
<button
|
||||
className="ops-btn ops-btn-ghost"
|
||||
onClick={() => setDialog({ type: "settings", tab: "mock" })}
|
||||
title="Mock 数据:@表达式 + 智能匹配规则 + 预览"
|
||||
>
|
||||
<Icon name="flask-conical" size={15} />
|
||||
</button>
|
||||
|
||||
<div className="mx-1 h-5 w-px" style={{ background: "var(--border)" }} />
|
||||
|
||||
@@ -352,16 +296,6 @@ export function TopBar() {
|
||||
>
|
||||
<Icon name="settings" size={15} />
|
||||
</button>
|
||||
<button
|
||||
className="ops-btn ops-btn-ghost"
|
||||
title="更多"
|
||||
onClick={(e) => {
|
||||
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
||||
setMoreMenu({ x: rect.right, y: rect.bottom + 4 });
|
||||
}}
|
||||
>
|
||||
<Icon name="ellipsis" size={16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ContextMenu
|
||||
@@ -372,10 +306,6 @@ export function TopBar() {
|
||||
menu={accountMenu ? { x: accountMenu.x, y: accountMenu.y, items: accountItems } : null}
|
||||
onClose={() => setAccountMenu(null)}
|
||||
/>
|
||||
<ContextMenu
|
||||
menu={moreMenu ? { x: moreMenu.x, y: moreMenu.y, items: moreItems } : null}
|
||||
onClose={() => setMoreMenu(null)}
|
||||
/>
|
||||
<ContextMenu
|
||||
menu={newMenu ? { x: newMenu.x, y: newMenu.y, items: newItems } : null}
|
||||
onClose={() => setNewMenu(null)}
|
||||
|
||||
Reference in new issue
Block a user