feat: Admin/Workbench 双入口架构
- 抽取 ConsoleShell 共享外壳(Layout/Header/Sider/主题切换/侧边栏折叠) - Sidebar 纯化为接受 menuItems prop 的展示组件 - Admin 管理台:/ 总览 + /projects 项目管理 - Workbench 工作台:/workbench/:projectId 项目作用域 - WorkbenchProjectGate 入口守卫(loading/error/archived/不存在拦截) - ProjectContext 提供当前项目上下文 - 项目管理表格 active 行增加'进入工作台'按钮 - 项目名称 trim 后最多 10 字符(前后端一致) - Workbench 总览页展示项目 Descriptions - Header 区分:管理台显示副标题,工作台显示项目名 + 返回管理台按钮 - 28/28 前端测试通过 - 文档更新:frontend.md ConsoleShell 规范、usage.md 双入口说明
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
import { screen } from "@testing-library/react";
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { createElement } from "react";
|
||||
@@ -9,7 +8,7 @@ import { renderWithProviders } from "./test-utils";
|
||||
|
||||
describe("App", () => {
|
||||
test("渲染 Layout 骨架和品牌名", () => {
|
||||
window.fetch = (async () => {
|
||||
window.fetch = (() => {
|
||||
return new Response(
|
||||
JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }),
|
||||
{
|
||||
@@ -27,8 +26,8 @@ describe("App", () => {
|
||||
expect(screen.getByText("黑暗")).not.toBeNull();
|
||||
});
|
||||
|
||||
test("渲染侧边栏菜单项", () => {
|
||||
window.fetch = (async () => {
|
||||
test("渲染 Admin 侧边栏菜单项", () => {
|
||||
window.fetch = (() => {
|
||||
return new Response(
|
||||
JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }),
|
||||
{
|
||||
@@ -40,12 +39,12 @@ describe("App", () => {
|
||||
|
||||
renderWithProviders(createElement(App));
|
||||
|
||||
expect(screen.getAllByText("仪表盘").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("总览").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("项目管理").length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("Sider 渲染侧边栏菜单", () => {
|
||||
window.fetch = (async () => {
|
||||
window.fetch = (() => {
|
||||
return new Response(
|
||||
JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }),
|
||||
{
|
||||
@@ -62,4 +61,20 @@ describe("App", () => {
|
||||
const menu = document.querySelector(".ant-menu");
|
||||
expect(menu).not.toBeNull();
|
||||
});
|
||||
|
||||
test("Admin header 显示管理台标题", () => {
|
||||
window.fetch = (() => {
|
||||
return new Response(
|
||||
JSON.stringify({ ok: true, service: "test-app", timestamp: new Date().toISOString(), version: "0.1.0" }),
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
status: 200,
|
||||
},
|
||||
);
|
||||
}) as unknown as typeof fetch;
|
||||
|
||||
renderWithProviders(createElement(App));
|
||||
|
||||
expect(screen.getByText("管理台")).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user