diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 5a2fde5..0878bc5 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -491,6 +491,8 @@ const en = { sheetCount: "Sheets", sheetNavTitle: "Checks", sheetNavHint: "{{n}} checks · click to switch", + collapseSheetNav: "Collapse checks", + expandSheetNav: "Expand checks", sheetFailCount: "{{n}} failed", topChangedFields: "Top failed fields", exportTables: "Download tables", diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 6ad8896..2d5e1d4 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -488,6 +488,8 @@ const zh = { sheetCount: "监控表", sheetNavTitle: "检查项", sheetNavHint: "共 {{n}} 项 · 点击切换", + collapseSheetNav: "折叠检查项", + expandSheetNav: "展开检查项", sheetFailCount: "{{n}} 项失败", topChangedFields: "失败字段 Top", exportTables: "下载表格", diff --git a/web/src/index.css b/web/src/index.css index 146cc4d..6694775 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -11327,6 +11327,15 @@ html.login-page--paused .login-page__flare { padding: 2px 0; } +.bs-cmp-board__meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + min-width: 0; + flex: 1 1 auto; +} + .bs-cmp-board__run-select { flex: 0 1 280px; min-width: 140px; @@ -11355,7 +11364,7 @@ html.login-page--paused .login-page__flare { align-items: center; gap: 6px 8px; min-width: 0; - flex: 1 1 320px; + flex: 1 1 280px; height: 32px; padding: 0 8px; border-radius: 8px; @@ -11440,9 +11449,12 @@ html.login-page--paused .login-page__flare { margin-left: 0; } + .bs-cmp-board__meta { + flex: 1 1 100%; + } + .bs-cmp-sides { flex: 1 1 100%; - order: 3; height: auto; min-height: 32px; padding: 4px 8px; @@ -11452,6 +11464,11 @@ html.login-page--paused .login-page__flare { .bs-cmp-sides__name { max-width: none; } + + .bs-cmp-board__run-select { + flex: 1 1 200px; + max-width: none; + } } .bs-cmp-board__body { @@ -11461,6 +11478,11 @@ html.login-page--paused .login-page__flare { flex: 1 1 auto; min-height: 0; align-items: stretch; + transition: grid-template-columns 0.18s ease; +} + +.bs-cmp-board__body.is-nav-collapsed { + grid-template-columns: 44px minmax(0, 1fr); } .bs-cmp-nav { @@ -11475,15 +11497,44 @@ html.login-page--paused .login-page__flare { .bs-cmp-nav__head { display: grid; - grid-template-columns: 8px minmax(0, 1fr) auto; + grid-template-columns: 28px minmax(0, 1fr) auto; align-items: center; - gap: 0 8px; - padding: 8px 10px; + gap: 0 6px; + padding: 6px 8px; border-bottom: 1px solid var(--bs-cmp-border); flex: 0 0 auto; min-height: 36px; } +.bs-cmp-nav.is-collapsed .bs-cmp-nav__head { + grid-template-columns: 1fr; + justify-items: center; + padding: 6px 4px; +} + +.bs-cmp-nav__toggle { + appearance: none; + width: 28px; + height: 28px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid rgba(148, 163, 184, 0.28); + border-radius: 6px; + background: rgba(15, 23, 42, 0.55); + color: #93c5fd; + font-size: 14px; + font-weight: 700; + line-height: 1; + cursor: pointer; + padding: 0; +} + +.bs-cmp-nav__toggle:hover { + background: rgba(37, 99, 235, 0.22); + border-color: rgba(59, 130, 246, 0.45); +} + .bs-cmp-nav__dot--spacer { visibility: hidden; } @@ -11597,6 +11648,34 @@ html.login-page--paused .login-page__flare { transition: background 0.12s ease, border-color 0.12s ease; } +.bs-cmp-nav.is-collapsed .bs-cmp-nav__item { + grid-template-columns: 1fr; + justify-items: center; + padding: 8px 4px; + border-radius: 6px; +} + +.bs-cmp-nav.is-collapsed .bs-cmp-nav__name, +.bs-cmp-nav.is-collapsed .bs-cmp-nav__stats { + display: none; +} + +.bs-cmp-nav.is-collapsed .bs-cmp-nav__list { + padding: 4px; + gap: 2px; + align-items: stretch; +} + +.bs-cmp-nav.is-collapsed .bs-cmp-nav__dot { + width: 8px; + height: 8px; +} + +.bs-cmp-nav.is-collapsed .bs-cmp-nav__item.is-active { + box-shadow: none; + background: rgba(37, 99, 235, 0.28); +} + .bs-cmp-nav__item:hover { background: rgba(30, 41, 59, 0.75); } @@ -12042,10 +12121,18 @@ html.login-page--paused .login-page__flare { grid-template-columns: 1fr; } + .bs-cmp-board__body.is-nav-collapsed { + grid-template-columns: 1fr; + } + .bs-cmp-nav { max-height: 180px; } + .bs-cmp-nav.is-collapsed { + max-height: 52px; + } + .bs-cmp-nav__list { flex-direction: row; flex-wrap: nowrap; @@ -12053,6 +12140,10 @@ html.login-page--paused .login-page__flare { overflow-y: hidden; } + .bs-cmp-nav.is-collapsed .bs-cmp-nav__list { + display: none; + } + .bs-cmp-nav__item { flex: 0 0 auto; min-width: 180px; diff --git a/web/src/pages/network/BizComparePage.tsx b/web/src/pages/network/BizComparePage.tsx index 2fd059f..22454ed 100644 --- a/web/src/pages/network/BizComparePage.tsx +++ b/web/src/pages/network/BizComparePage.tsx @@ -830,6 +830,7 @@ export function BizComparePage({ pageMode = "all" }: { pageMode?: BizComparePage const [diffsLoading, setDiffsLoading] = useState(false); const boardRef = useRef(null); const [boardFs, setBoardFs] = useState(false); + const [navCollapsed, setNavCollapsed] = useState(false); const tplImportRef = useRef(null); const refresh = useCallback(async () => { @@ -2693,109 +2694,119 @@ export function BizComparePage({ pageMode = "all" }: { pageMode?: BizComparePage className={`bs-cmp-board${boardFs ? " is-fullscreen" : ""}`} >
- - {runs.length ? ( - - {t("bizCompare.runCount", { n: String(runs.length) })} - - ) : null} - {runDetail ? ( -
- {(() => { - const before = enrichSide( - runDetail.before, - beforeTaskId, - tasks, - beforeBatches, - ); - const after = enrichSide( - runDetail.after, - afterTaskId || beforeTaskId, - tasks, - afterBatches.length ? afterBatches : beforeBatches, - ); - const beforeName = sideDeviceName(before); - const afterName = sideDeviceName(after); - const beforeTime = sideCollectTime(before); - const afterTime = sideCollectTime(after); - return ( - <> -
- {t("bizCompare.sideBefore")} - - {beforeName} - - - {beforeTime} +
+ {runDetail ? ( +
+ {(() => { + const before = enrichSide( + runDetail.before, + beforeTaskId, + tasks, + beforeBatches, + ); + const after = enrichSide( + runDetail.after, + afterTaskId || beforeTaskId, + tasks, + afterBatches.length ? afterBatches : beforeBatches, + ); + const beforeName = sideDeviceName(before); + const afterName = sideDeviceName(after); + const beforeTime = sideCollectTime(before); + const afterTime = sideCollectTime(after); + return ( + <> +
+ {t("bizCompare.sideBefore")} + + {beforeName} + + + {beforeTime} + +
+ + → -
- - → - -
- {t("bizCompare.sideAfter")} - - {afterName} - - - {afterTime} - -
- - ); - })()} -
- ) : null} +
+ {t("bizCompare.sideAfter")} + + {afterName} + + + {afterTime} + +
+ + ); + })()} +
+ ) : null} + {!boardFs ? ( + <> + + {runs.length ? ( + + {t("bizCompare.runCount", { n: String(runs.length) })} + + ) : null} + + ) : null} +
- - + {!boardFs ? ( + <> + + + + ) : null} + {!navCollapsed ? ( + <> + + {t("bizCompare.sheetNavTitle")} + + {sheetCards.length || runSheets.length} + + + + + {t("bizCompare.kindFail")} + + + {t("bizCompare.kindSuccess")} + + + % + + + + ) : null}
{(sheetCards.length