优化桌面端界面布局
This commit is contained in:
@@ -3,6 +3,7 @@ import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const readLayoutSource = () => readFileSync(resolve(__dirname, "./Layout.vue"), "utf8");
|
||||
const readAppSource = () => readFileSync(resolve(__dirname, "../App.vue"), "utf8");
|
||||
const readDesktopLayoutSource = () => readFileSync(resolve(__dirname, "./DesktopLayout.vue"), "utf8");
|
||||
const readWebLayoutSource = () => readFileSync(resolve(__dirname, "./WebLayout.vue"), "utf8");
|
||||
const readNavigationSource = () => readFileSync(resolve(__dirname, "./layout/navigation.ts"), "utf8");
|
||||
@@ -17,23 +18,40 @@ const readFileTaskFeedbackSource = () => readFileSync(resolve(__dirname, "../uti
|
||||
const readAttachmentListSource = () => readFileSync(resolve(__dirname, "./attachments/AttachmentList.vue"), "utf8");
|
||||
const readDocumentDetailSource = () => readFileSync(resolve(__dirname, "../views/documents/DocumentDetail.vue"), "utf8");
|
||||
const readMainStyleSource = () => readFileSync(resolve(__dirname, "../styles/main.css"), "utf8");
|
||||
const readFaqSource = () => readFileSync(resolve(__dirname, "../views/Faq.vue"), "utf8");
|
||||
const readFaqListSource = () => readFileSync(resolve(__dirname, "./FaqList.vue"), "utf8");
|
||||
const readProjectOverviewSource = () => readFileSync(resolve(__dirname, "../views/ia/ProjectOverview.vue"), "utf8");
|
||||
|
||||
describe("desktop layout shell", () => {
|
||||
it("routes desktop and web shells through the runtime flag", () => {
|
||||
const source = readLayoutSource();
|
||||
const app = readAppSource();
|
||||
|
||||
expect(source).toContain("const isDesktop = isTauriRuntime()");
|
||||
expect(source).toContain("<DesktopLayout v-if=\"isDesktop\" />");
|
||||
expect(source).toContain("<WebLayout v-else />");
|
||||
expect(app).toContain("const isDesktopRuntime = isTauriRuntime();");
|
||||
expect(app).toContain('document.body.classList.add("is-desktop-runtime")');
|
||||
expect(app).toContain('document.body.classList.remove("is-desktop-runtime")');
|
||||
});
|
||||
|
||||
it("uses route-only desktop preference storage", () => {
|
||||
const source = readDesktopLayoutSource();
|
||||
const webSource = readWebLayoutSource();
|
||||
|
||||
expect(source).toContain("readDesktopRecentRoutes");
|
||||
expect(source).toContain("readDesktopFavoriteRoutes");
|
||||
expect(source).toContain("recordDesktopRecentRoute");
|
||||
expect(source).toContain("currentDesktopRoutePreference");
|
||||
expect(source).toContain("toggleDesktopFavoriteRoute");
|
||||
expect(source).not.toContain("readDesktopRecentRoutes");
|
||||
expect(source).not.toContain("recordDesktopRecentRoute");
|
||||
expect(source).not.toContain("desktopRecentRoutes");
|
||||
expect(source).not.toContain("最近访问");
|
||||
expect(webSource).toContain("readDesktopFavoriteRoutes");
|
||||
expect(webSource).toContain("toggleDesktopFavoriteRoute");
|
||||
expect(webSource).not.toContain("readDesktopRecentRoutes");
|
||||
expect(webSource).not.toContain("recordDesktopRecentRoute");
|
||||
expect(webSource).not.toContain("desktopRecentRoutes");
|
||||
expect(webSource).not.toContain("最近访问");
|
||||
});
|
||||
|
||||
it("shares active route mapping between web and desktop shells", () => {
|
||||
@@ -86,12 +104,35 @@ describe("desktop layout shell", () => {
|
||||
expect(tauriConfig).toContain('"titleBarStyle": "Overlay"');
|
||||
expect(tauriConfig).toContain('"hiddenTitle": true');
|
||||
expect(tauriConfig).toContain('"trafficLightPosition": { "x": 16, "y": 18 }');
|
||||
expect(layout).toContain("padding: 54px 16px 14px;");
|
||||
expect(layout).toContain("padding: 44px 10px 10px;");
|
||||
expect(layout).toContain("-webkit-app-region: drag;");
|
||||
expect(layout).toContain("-webkit-app-region: no-drag;");
|
||||
expect(layout).not.toContain(["@tauri-apps", "api", "window"].join("/"));
|
||||
});
|
||||
|
||||
it("keeps the desktop sidebar dense enough for navigation-heavy screens", () => {
|
||||
const layout = readDesktopLayoutSource();
|
||||
const sidebarHeadStart = layout.indexOf('<header class="sidebar-head">');
|
||||
const sidebarHeadEnd = layout.indexOf("</header>", sidebarHeadStart);
|
||||
const sidebarHeadTemplate = layout.slice(sidebarHeadStart, sidebarHeadEnd);
|
||||
|
||||
expect(layout).toContain("grid-template-columns: 248px minmax(0, 1fr);");
|
||||
expect(layout).toContain("padding: 44px 10px 10px;");
|
||||
expect(layout).toContain("grid-template-columns: auto minmax(0, 1fr);");
|
||||
expect(layout).toContain("width: 140px;");
|
||||
expect(layout).toContain("margin-top: 0;");
|
||||
expect(layout).toContain("padding: 10px 8px 24px;");
|
||||
expect(layout).toContain("margin-top: 12px;");
|
||||
expect(layout).toContain("font-size: 14px;");
|
||||
expect(sidebarHeadTemplate).toContain('<div class="sidebar-title-row">');
|
||||
expect(sidebarHeadTemplate.indexOf("<h1>{{ TEXT.common.appName }}</h1>")).toBeLessThan(
|
||||
sidebarHeadTemplate.indexOf('<el-dropdown v-if="study.currentStudy"'),
|
||||
);
|
||||
expect(layout).not.toContain("grid-template-columns: 272px minmax(0, 1fr);");
|
||||
expect(layout).not.toContain("padding: 54px 16px 14px;");
|
||||
expect(layout).not.toContain("padding: 44px 12px 12px;");
|
||||
});
|
||||
|
||||
it("renders desktop preferences as a split settings panel", () => {
|
||||
const preferences = readDesktopPreferencesSource();
|
||||
const desktopLayout = readDesktopLayoutSource();
|
||||
@@ -187,6 +228,8 @@ describe("desktop layout shell", () => {
|
||||
expect(tabsTemplate).not.toContain('@click="router.push(item.path)"');
|
||||
expect(source).not.toContain(".slice(-7)");
|
||||
expect(tabsTemplate).toContain('@contextmenu.prevent.stop="openWorkspaceTabMenu(item, $event)"');
|
||||
expect(tabsTemplate).not.toContain('class="tab-group"');
|
||||
expect(tabsTemplate).not.toContain("{{ item.group }}");
|
||||
expect(source).toContain("const lastClosedWorkspaceTab = ref<DesktopRoutePreference | null>(null);");
|
||||
expect(source).toContain("const workspaceTabMenu = ref<");
|
||||
expect(source).toContain("const closeOtherWorkspaceTabs = (path: string) => {");
|
||||
@@ -306,18 +349,89 @@ describe("desktop layout shell", () => {
|
||||
const styles = readMainStyleSource();
|
||||
|
||||
expect(styles).toContain("/* Desktop workbench density */");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell.page");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell.ctms-page-shell");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-body");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-inner");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .overview");
|
||||
expect(styles).toContain("padding: 0 !important;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .table-card");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .hero-banner");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .faq-hero");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-bg-dots");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .module-placeholder-surface");
|
||||
expect(styles).toContain("box-shadow: none !important;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-table th.el-table__cell");
|
||||
expect(styles).toContain("height: 34px;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-table td.el-table__cell");
|
||||
expect(styles).toContain("padding: 7px 10px;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-pagination");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-drawer__body");
|
||||
expect(styles).toContain(":root[data-ctms-theme=\"dark\"] .desktop-workbench .desktop-route-shell .hero-stat");
|
||||
});
|
||||
|
||||
it("renders Element Plus modals with desktop-native surfaces in the desktop runtime", () => {
|
||||
const styles = readMainStyleSource();
|
||||
|
||||
expect(styles).toContain("/* Desktop runtime modal surfaces */");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay");
|
||||
expect(styles).toContain("left: 0 !important;");
|
||||
expect(styles).toContain("backdrop-filter: blur(12px) saturate(135%);");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay-message-box");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-dialog,");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box");
|
||||
expect(styles).toContain("border-radius: 12px;");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-dialog__header");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box__header");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog .el-dialog__body");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog .el-dialog__body {\n padding: 0;");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box__btns");
|
||||
expect(styles).toContain("body.is-desktop-runtime .dialog-fade-enter-from .el-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .msgbox-fade-enter-from .el-message-box");
|
||||
expect(styles).toContain(':root[data-ctms-theme="dark"] body.is-desktop-runtime .desktop-preferences-dialog');
|
||||
expect(styles).toContain(':root[data-ctms-theme="dark"] body.is-desktop-runtime .el-dialog');
|
||||
});
|
||||
|
||||
it("keeps first-pass desktop content pages workbench-oriented", () => {
|
||||
const faq = readFaqSource();
|
||||
const faqList = readFaqListSource();
|
||||
const projectOverview = readProjectOverviewSource();
|
||||
|
||||
expect(faq).toContain("const isDesktop = isTauriRuntime();");
|
||||
expect(faq).toContain(":class=\"{ 'medical-consult-page--desktop': isDesktop }\"");
|
||||
expect(faq).toContain('v-if="!isDesktop" class="page-bg-dots"');
|
||||
expect(faq).toContain('<h1 v-if="!isDesktop"');
|
||||
expect(faq).toContain('v-else class="desktop-toolbar-meta"');
|
||||
expect(faq).toContain('v-if="isDesktop" action="faq.create"');
|
||||
expect(faq).toContain('<div v-if="!isDesktop" class="list-toolbar">');
|
||||
expect(faq).toContain(".medical-consult-page--desktop .faq-workspace");
|
||||
expect(faq).toContain("grid-template-columns: 236px minmax(0, 1fr);");
|
||||
expect(faqList).toContain(":class=\"{ 'faq-list-card--desktop': isDesktop }\"");
|
||||
expect(faqList).toContain("const isDesktop = isTauriRuntime();");
|
||||
expect(faqList).toContain(".faq-list-card--desktop .faq-table");
|
||||
expect(projectOverview).toContain(":class=\"{ 'project-overview--desktop': isDesktop }\"");
|
||||
expect(projectOverview).not.toContain("overview-summary-strip");
|
||||
expect(projectOverview).not.toContain("const activeCenterCount");
|
||||
expect(projectOverview).toContain("desktop-attention-section");
|
||||
expect(projectOverview).toContain("desktop-attention-head");
|
||||
expect(projectOverview).toContain("更新 {{ overviewUpdatedAtLabel }}");
|
||||
expect(projectOverview).toContain("overview-workbench");
|
||||
expect(projectOverview).toContain("enrollment-snapshot");
|
||||
expect(projectOverview).toContain("desktop-attention-board");
|
||||
expect(projectOverview).toContain("const stageStatusSummary");
|
||||
expect(projectOverview).toContain("const activeStageItems");
|
||||
expect(projectOverview).toContain("const attentionItems");
|
||||
expect(projectOverview).toContain("grid-template-columns: minmax(620px, 1fr) minmax(300px, 360px);");
|
||||
expect(projectOverview).toContain("max-height: min(360px, calc(100vh - 300px));");
|
||||
expect(projectOverview).toContain("@media (max-width: 1240px)");
|
||||
expect(projectOverview).toContain(".project-overview--desktop .overview-card");
|
||||
expect(projectOverview).toContain(".project-overview--desktop .overview-card--enrollment");
|
||||
expect(projectOverview).toContain(".project-overview--desktop :deep(.center-row)");
|
||||
expect(projectOverview).toContain(".project-overview--desktop :deep(.stage-node)");
|
||||
});
|
||||
|
||||
it("keeps desktop entry surfaces stable at the minimum window size", () => {
|
||||
const login = readLoginSource();
|
||||
const serverSettings = readDesktopServerSettingsSource();
|
||||
|
||||
Reference in New Issue
Block a user