mirror of
https://github.com/hansjone/netx.git
synced 2026-10-12 11:43:21 +08:00
Make compare sheet nav collapsible and hide run picker in fullscreen.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
4c3c034c4c
commit
28aa7cd87e
4 changed files with 267 additions and 140 deletions
|
|
@ -491,6 +491,8 @@ const en = {
|
||||||
sheetCount: "Sheets",
|
sheetCount: "Sheets",
|
||||||
sheetNavTitle: "Checks",
|
sheetNavTitle: "Checks",
|
||||||
sheetNavHint: "{{n}} checks · click to switch",
|
sheetNavHint: "{{n}} checks · click to switch",
|
||||||
|
collapseSheetNav: "Collapse checks",
|
||||||
|
expandSheetNav: "Expand checks",
|
||||||
sheetFailCount: "{{n}} failed",
|
sheetFailCount: "{{n}} failed",
|
||||||
topChangedFields: "Top failed fields",
|
topChangedFields: "Top failed fields",
|
||||||
exportTables: "Download tables",
|
exportTables: "Download tables",
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,8 @@ const zh = {
|
||||||
sheetCount: "监控表",
|
sheetCount: "监控表",
|
||||||
sheetNavTitle: "检查项",
|
sheetNavTitle: "检查项",
|
||||||
sheetNavHint: "共 {{n}} 项 · 点击切换",
|
sheetNavHint: "共 {{n}} 项 · 点击切换",
|
||||||
|
collapseSheetNav: "折叠检查项",
|
||||||
|
expandSheetNav: "展开检查项",
|
||||||
sheetFailCount: "{{n}} 项失败",
|
sheetFailCount: "{{n}} 项失败",
|
||||||
topChangedFields: "失败字段 Top",
|
topChangedFields: "失败字段 Top",
|
||||||
exportTables: "下载表格",
|
exportTables: "下载表格",
|
||||||
|
|
|
||||||
|
|
@ -11327,6 +11327,15 @@ html.login-page--paused .login-page__flare {
|
||||||
padding: 2px 0;
|
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 {
|
.bs-cmp-board__run-select {
|
||||||
flex: 0 1 280px;
|
flex: 0 1 280px;
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
|
|
@ -11355,7 +11364,7 @@ html.login-page--paused .login-page__flare {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px 8px;
|
gap: 6px 8px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 320px;
|
flex: 1 1 280px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
@ -11440,9 +11449,12 @@ html.login-page--paused .login-page__flare {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bs-cmp-board__meta {
|
||||||
|
flex: 1 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.bs-cmp-sides {
|
.bs-cmp-sides {
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
order: 3;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
|
|
@ -11452,6 +11464,11 @@ html.login-page--paused .login-page__flare {
|
||||||
.bs-cmp-sides__name {
|
.bs-cmp-sides__name {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bs-cmp-board__run-select {
|
||||||
|
flex: 1 1 200px;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bs-cmp-board__body {
|
.bs-cmp-board__body {
|
||||||
|
|
@ -11461,6 +11478,11 @@ html.login-page--paused .login-page__flare {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
align-items: stretch;
|
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 {
|
.bs-cmp-nav {
|
||||||
|
|
@ -11475,15 +11497,44 @@ html.login-page--paused .login-page__flare {
|
||||||
|
|
||||||
.bs-cmp-nav__head {
|
.bs-cmp-nav__head {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 8px minmax(0, 1fr) auto;
|
grid-template-columns: 28px minmax(0, 1fr) auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0 8px;
|
gap: 0 6px;
|
||||||
padding: 8px 10px;
|
padding: 6px 8px;
|
||||||
border-bottom: 1px solid var(--bs-cmp-border);
|
border-bottom: 1px solid var(--bs-cmp-border);
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
min-height: 36px;
|
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 {
|
.bs-cmp-nav__dot--spacer {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
@ -11597,6 +11648,34 @@ html.login-page--paused .login-page__flare {
|
||||||
transition: background 0.12s ease, border-color 0.12s ease;
|
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 {
|
.bs-cmp-nav__item:hover {
|
||||||
background: rgba(30, 41, 59, 0.75);
|
background: rgba(30, 41, 59, 0.75);
|
||||||
}
|
}
|
||||||
|
|
@ -12042,10 +12121,18 @@ html.login-page--paused .login-page__flare {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bs-cmp-board__body.is-nav-collapsed {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
.bs-cmp-nav {
|
.bs-cmp-nav {
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bs-cmp-nav.is-collapsed {
|
||||||
|
max-height: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
.bs-cmp-nav__list {
|
.bs-cmp-nav__list {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
|
|
@ -12053,6 +12140,10 @@ html.login-page--paused .login-page__flare {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bs-cmp-nav.is-collapsed .bs-cmp-nav__list {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.bs-cmp-nav__item {
|
.bs-cmp-nav__item {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
min-width: 180px;
|
min-width: 180px;
|
||||||
|
|
|
||||||
|
|
@ -830,6 +830,7 @@ export function BizComparePage({ pageMode = "all" }: { pageMode?: BizComparePage
|
||||||
const [diffsLoading, setDiffsLoading] = useState(false);
|
const [diffsLoading, setDiffsLoading] = useState(false);
|
||||||
const boardRef = useRef<HTMLDivElement | null>(null);
|
const boardRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [boardFs, setBoardFs] = useState(false);
|
const [boardFs, setBoardFs] = useState(false);
|
||||||
|
const [navCollapsed, setNavCollapsed] = useState(false);
|
||||||
const tplImportRef = useRef<HTMLInputElement | null>(null);
|
const tplImportRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
const refresh = useCallback(async () => {
|
||||||
|
|
@ -2693,109 +2694,119 @@ export function BizComparePage({ pageMode = "all" }: { pageMode?: BizComparePage
|
||||||
className={`bs-cmp-board${boardFs ? " is-fullscreen" : ""}`}
|
className={`bs-cmp-board${boardFs ? " is-fullscreen" : ""}`}
|
||||||
>
|
>
|
||||||
<div className="bs-cmp-board__toolbar">
|
<div className="bs-cmp-board__toolbar">
|
||||||
<select
|
<div className="bs-cmp-board__meta">
|
||||||
className="ui-field__select bs-cmp-board__run-select"
|
{runDetail ? (
|
||||||
aria-label={t("bizCompare.pickBatchRun")}
|
<div className="bs-cmp-sides" aria-label={t("bizCompare.sidesTitle")}>
|
||||||
value={runDetail?.id || ""}
|
{(() => {
|
||||||
onChange={(e) => {
|
const before = enrichSide(
|
||||||
const id = e.target.value;
|
runDetail.before,
|
||||||
if (id) void loadRun(id);
|
beforeTaskId,
|
||||||
}}
|
tasks,
|
||||||
>
|
beforeBatches,
|
||||||
<option value="">{t("bizCompare.pickRun")}</option>
|
);
|
||||||
{runs.map((r) => {
|
const after = enrichSide(
|
||||||
const before = enrichSide(
|
runDetail.after,
|
||||||
(r as any).before,
|
afterTaskId || beforeTaskId,
|
||||||
beforeTaskId,
|
tasks,
|
||||||
tasks,
|
afterBatches.length ? afterBatches : beforeBatches,
|
||||||
beforeBatches,
|
);
|
||||||
);
|
const beforeName = sideDeviceName(before);
|
||||||
const after = enrichSide(
|
const afterName = sideDeviceName(after);
|
||||||
(r as any).after,
|
const beforeTime = sideCollectTime(before);
|
||||||
afterTaskId || beforeTaskId,
|
const afterTime = sideCollectTime(after);
|
||||||
tasks,
|
return (
|
||||||
afterBatches.length ? afterBatches : beforeBatches,
|
<>
|
||||||
);
|
<div className="bs-cmp-sides__side is-before">
|
||||||
const bl = sideDeviceName(before);
|
<span className="bs-cmp-sides__tag">{t("bizCompare.sideBefore")}</span>
|
||||||
const al = sideDeviceName(after);
|
<strong className="bs-cmp-sides__name" title={`${beforeName} ${beforeTime}`}>
|
||||||
const when = formatSystemTime((r as any).created_at) || "";
|
{beforeName}
|
||||||
return (
|
</strong>
|
||||||
<option key={r.id} value={r.id}>
|
<span className="bs-cmp-sides__meta" title={beforeTime}>
|
||||||
{when ? `${when} · ` : ""}
|
{beforeTime}
|
||||||
{bl} {sideCollectTime(before)} → {al} {sideCollectTime(after)}
|
</span>
|
||||||
</option>
|
</div>
|
||||||
);
|
<span className="bs-cmp-sides__arrow" aria-hidden>
|
||||||
})}
|
→
|
||||||
</select>
|
|
||||||
{runs.length ? (
|
|
||||||
<span className="muted bs-cmp-board__run-count">
|
|
||||||
{t("bizCompare.runCount", { n: String(runs.length) })}
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
{runDetail ? (
|
|
||||||
<div className="bs-cmp-sides" aria-label={t("bizCompare.sidesTitle")}>
|
|
||||||
{(() => {
|
|
||||||
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 (
|
|
||||||
<>
|
|
||||||
<div className="bs-cmp-sides__side is-before">
|
|
||||||
<span className="bs-cmp-sides__tag">{t("bizCompare.sideBefore")}</span>
|
|
||||||
<strong className="bs-cmp-sides__name" title={`${beforeName} ${beforeTime}`}>
|
|
||||||
{beforeName}
|
|
||||||
</strong>
|
|
||||||
<span className="bs-cmp-sides__meta" title={beforeTime}>
|
|
||||||
{beforeTime}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
<div className="bs-cmp-sides__side is-after">
|
||||||
<span className="bs-cmp-sides__arrow" aria-hidden>
|
<span className="bs-cmp-sides__tag">{t("bizCompare.sideAfter")}</span>
|
||||||
→
|
<strong className="bs-cmp-sides__name" title={`${afterName} ${afterTime}`}>
|
||||||
</span>
|
{afterName}
|
||||||
<div className="bs-cmp-sides__side is-after">
|
</strong>
|
||||||
<span className="bs-cmp-sides__tag">{t("bizCompare.sideAfter")}</span>
|
<span className="bs-cmp-sides__meta" title={afterTime}>
|
||||||
<strong className="bs-cmp-sides__name" title={`${afterName} ${afterTime}`}>
|
{afterTime}
|
||||||
{afterName}
|
</span>
|
||||||
</strong>
|
</div>
|
||||||
<span className="bs-cmp-sides__meta" title={afterTime}>
|
</>
|
||||||
{afterTime}
|
);
|
||||||
</span>
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</>
|
) : null}
|
||||||
);
|
{!boardFs ? (
|
||||||
})()}
|
<>
|
||||||
</div>
|
<select
|
||||||
) : null}
|
className="ui-field__select bs-cmp-board__run-select"
|
||||||
|
aria-label={t("bizCompare.pickBatchRun")}
|
||||||
|
value={runDetail?.id || ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
const id = e.target.value;
|
||||||
|
if (id) void loadRun(id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="">{t("bizCompare.pickRun")}</option>
|
||||||
|
{runs.map((r) => {
|
||||||
|
const before = enrichSide(
|
||||||
|
(r as any).before,
|
||||||
|
beforeTaskId,
|
||||||
|
tasks,
|
||||||
|
beforeBatches,
|
||||||
|
);
|
||||||
|
const after = enrichSide(
|
||||||
|
(r as any).after,
|
||||||
|
afterTaskId || beforeTaskId,
|
||||||
|
tasks,
|
||||||
|
afterBatches.length ? afterBatches : beforeBatches,
|
||||||
|
);
|
||||||
|
const bl = sideDeviceName(before);
|
||||||
|
const al = sideDeviceName(after);
|
||||||
|
const when = formatSystemTime((r as any).created_at) || "";
|
||||||
|
return (
|
||||||
|
<option key={r.id} value={r.id}>
|
||||||
|
{when ? `${when} · ` : ""}
|
||||||
|
{bl} {sideCollectTime(before)} → {al} {sideCollectTime(after)}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
{runs.length ? (
|
||||||
|
<span className="muted bs-cmp-board__run-count">
|
||||||
|
{t("bizCompare.runCount", { n: String(runs.length) })}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
<div className="btn-row bs-cmp-board__actions">
|
<div className="btn-row bs-cmp-board__actions">
|
||||||
<Button
|
{!boardFs ? (
|
||||||
size="sm"
|
<>
|
||||||
variant="secondary"
|
<Button
|
||||||
isDisabled={busy || !runDetail?.id}
|
size="sm"
|
||||||
onPress={() => void downloadRunTables()}
|
variant="secondary"
|
||||||
>
|
isDisabled={busy || !runDetail?.id}
|
||||||
{t("bizCompare.exportTables")}
|
onPress={() => void downloadRunTables()}
|
||||||
</Button>
|
>
|
||||||
<Button
|
{t("bizCompare.exportTables")}
|
||||||
size="sm"
|
</Button>
|
||||||
variant="danger"
|
<Button
|
||||||
isDisabled={busy || !runDetail?.id}
|
size="sm"
|
||||||
onPress={() => void removeRun(String(runDetail?.id || ""))}
|
variant="danger"
|
||||||
>
|
isDisabled={busy || !runDetail?.id}
|
||||||
{t("bizCompare.deleteRun")}
|
onPress={() => void removeRun(String(runDetail?.id || ""))}
|
||||||
</Button>
|
>
|
||||||
|
{t("bizCompare.deleteRun")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
|
@ -2808,41 +2819,62 @@ export function BizComparePage({ pageMode = "all" }: { pageMode?: BizComparePage
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{runDetail ? (
|
{runDetail ? (
|
||||||
<div className="bs-cmp-board__body">
|
<div
|
||||||
<aside className="bs-cmp-nav" aria-label={t("bizCompare.sheetNavTitle")}>
|
className={`bs-cmp-board__body${navCollapsed ? " is-nav-collapsed" : ""}`}
|
||||||
|
>
|
||||||
|
<aside
|
||||||
|
className={`bs-cmp-nav${navCollapsed ? " is-collapsed" : ""}`}
|
||||||
|
aria-label={t("bizCompare.sheetNavTitle")}
|
||||||
|
>
|
||||||
<div className="bs-cmp-nav__head">
|
<div className="bs-cmp-nav__head">
|
||||||
<span className="bs-cmp-nav__dot bs-cmp-nav__dot--spacer" aria-hidden />
|
<button
|
||||||
<span className="bs-cmp-nav__head-main">
|
type="button"
|
||||||
<span className="bs-cmp-nav__title">{t("bizCompare.sheetNavTitle")}</span>
|
className="bs-cmp-nav__toggle"
|
||||||
<span
|
aria-expanded={!navCollapsed}
|
||||||
className="bs-cmp-nav__count"
|
title={
|
||||||
title={t("bizCompare.sheetNavHint", {
|
navCollapsed
|
||||||
n: String(sheetCards.length || runSheets.length),
|
? t("bizCompare.expandSheetNav")
|
||||||
})}
|
: t("bizCompare.collapseSheetNav")
|
||||||
>
|
}
|
||||||
{sheetCards.length || runSheets.length}
|
onClick={() => setNavCollapsed((v) => !v)}
|
||||||
</span>
|
>
|
||||||
</span>
|
{navCollapsed ? "»" : "«"}
|
||||||
<span className="bs-cmp-nav__legend" aria-hidden>
|
</button>
|
||||||
<span
|
{!navCollapsed ? (
|
||||||
className="bs-cmp-nav__num bs-cmp-nav__num--fail is-hot"
|
<>
|
||||||
title={t("bizCompare.kindFail")}
|
<span className="bs-cmp-nav__head-main">
|
||||||
>
|
<span className="bs-cmp-nav__title">{t("bizCompare.sheetNavTitle")}</span>
|
||||||
{t("bizCompare.kindFail")}
|
<span
|
||||||
</span>
|
className="bs-cmp-nav__count"
|
||||||
<span
|
title={t("bizCompare.sheetNavHint", {
|
||||||
className="bs-cmp-nav__num bs-cmp-nav__num--ok is-hot"
|
n: String(sheetCards.length || runSheets.length),
|
||||||
title={t("bizCompare.kindSuccess")}
|
})}
|
||||||
>
|
>
|
||||||
{t("bizCompare.kindSuccess")}
|
{sheetCards.length || runSheets.length}
|
||||||
</span>
|
</span>
|
||||||
<span
|
</span>
|
||||||
className="bs-cmp-nav__num bs-cmp-nav__num--rate"
|
<span className="bs-cmp-nav__legend" aria-hidden>
|
||||||
title={t("bizCompare.passRateShort")}
|
<span
|
||||||
>
|
className="bs-cmp-nav__num bs-cmp-nav__num--fail is-hot"
|
||||||
%
|
title={t("bizCompare.kindFail")}
|
||||||
</span>
|
>
|
||||||
</span>
|
{t("bizCompare.kindFail")}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="bs-cmp-nav__num bs-cmp-nav__num--ok is-hot"
|
||||||
|
title={t("bizCompare.kindSuccess")}
|
||||||
|
>
|
||||||
|
{t("bizCompare.kindSuccess")}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="bs-cmp-nav__num bs-cmp-nav__num--rate"
|
||||||
|
title={t("bizCompare.passRateShort")}
|
||||||
|
>
|
||||||
|
%
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className="bs-cmp-nav__list" role="tablist">
|
<div className="bs-cmp-nav__list" role="tablist">
|
||||||
{(sheetCards.length
|
{(sheetCards.length
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue