Improve managed NE filters/validation and simplify the workbench UI.

Add column filters and clearer API error mapping for NE management, tighten port validation, and slim the workbench into reusable modules with cleaner styles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-10-13 00:26:58 +08:00
parent 3c9e0efd2b
commit 312f6f2f96
25 changed files with 1484 additions and 2016 deletions

View file

@ -45,6 +45,7 @@
align-items: center;
gap: 12px;
min-width: 0;
flex: 1;
}
.app-brand__apps {
@ -74,6 +75,9 @@
color: rgba(255, 255, 255, 0.92);
white-space: nowrap;
letter-spacing: 0.02em;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.app-brand__actions {
@ -103,3 +107,36 @@
background: var(--nm-chrome, #e8eef6);
color: var(--nm-text, var(--nx-line));
}
.app--shell .app-brand .conn-pill.conn-pill--tasks::before {
content: none;
}
.app--shell .app-brand .conn-pill--tasks {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
}
.app-brand__tasks-count { display: none; }
.app--shell .app-brand .conn-pill--user .chip__label {
max-width: 110px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (max-width: 640px) {
.app--shell .app-brand { padding-inline: 12px; gap: 8px; }
.app-brand__start { gap: 8px; }
.app-brand__actions-group { gap: 4px; }
.app--shell .app-brand .conn-pill--user .chip__label { max-width: 64px; }
}
@media (max-width: 480px) {
.app-brand__tasks-text { display: none; }
.app-brand__tasks-count { display: inline; font-variant-numeric: tabular-nums; }
.app--shell .app-brand .conn-pill--tasks { padding-inline: 7px; }
}

View file

@ -84,6 +84,47 @@
padding: 10px 12px;
}
button.ne-tag-card {
display: block;
width: 100%;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
button.ne-tag-card > .ne-tag-card__title,
button.ne-tag-card > .ne-tag-card__total {
display: block;
}
button.ne-tag-card:hover {
border-color: rgb(var(--nx-accent-rgb) / 0.45);
}
button.ne-tag-card:focus-visible {
outline: 2px solid var(--nx-accent);
outline-offset: 2px;
}
button.ne-tag-card.is-active {
border-color: var(--nx-accent);
box-shadow: inset 0 0 0 1px var(--nx-accent);
}
.ne-selection-meta {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--nx-text-muted);
font-size: 12px;
}
.ne-import-failures {
max-height: 320px;
overflow: auto;
}
.ne-tag-card__title {
font-size: 13px;
font-weight: 650;

File diff suppressed because it is too large Load diff

View file

@ -135,256 +135,7 @@ table,
color: #fff;
}
/* -------------------------------------------------------------- 3. Workbench */
.app--shell .app-main:has(> .workbench) {
background:
radial-gradient(900px 380px at 12% -8%, rgb(var(--nx-accent-rgb) / 0.1), transparent 65%),
radial-gradient(700px 320px at 100% 0%, rgb(52 211 153 / 0.05), transparent 60%),
var(--nx-bg);
}
.app--shell .workbench {
gap: 16px;
}
/* Soft gradient plate instead of the corner-bracket HUD frame. */
.app--shell .wb-panel {
border: 1px solid var(--nx-line);
border-radius: var(--nx-radius-lg);
background: linear-gradient(180deg, var(--nx-surface-2) 0%, var(--nx-surface-1) 100%);
box-shadow: var(--nx-shadow-panel);
}
.app--shell .wb-head__title {
font-family: var(--nx-font-sans);
font-size: 22px;
font-weight: 700;
letter-spacing: 0.01em;
color: var(--nx-text-strong);
}
.app--shell .wb-head__health {
height: 24px;
padding: 0 10px;
border-radius: 999px;
font-family: var(--nx-font-sans);
font-size: 12px;
letter-spacing: 0;
}
/* Section captions: sans, readable, with a small gradient bar. */
.app--shell .wb-section__title,
.app--shell .wb-fleet__title,
.app--shell .wb-rail__title,
.app--shell .wb-fleet__card-label {
font-family: var(--nx-font-sans);
font-size: 13px;
font-weight: 650;
letter-spacing: 0.02em;
text-transform: none;
color: var(--nx-text);
}
.app--shell .wb-section__title {
display: flex;
align-items: center;
gap: 8px;
}
.app--shell .wb-section__title::before {
content: "";
width: 3px;
height: 14px;
border-radius: 2px;
background: var(--nx-gradient-accent);
}
.app--shell .wb-strip__tag,
.app--shell .wb-strip__tag--soft {
font-size: 11px;
color: var(--nx-text-faint);
}
.app--shell .wb-stat__label {
font-size: 12px;
color: var(--nx-text-muted);
}
.app--shell .wb-stat__value {
font-size: 13px;
}
.app--shell .wb-stat__track {
height: 3px;
border-radius: 2px;
}
/* Content-height layout: no stretched empty panel above/below the tiles. */
.app--shell .wb-body {
flex: 0 0 auto;
grid-template-columns: minmax(0, 1fr) clamp(320px, 26vw, 400px);
gap: 16px;
}
.app--shell .wb-main {
height: auto;
gap: 16px;
}
.app--shell .wb-modules {
flex: 0 0 auto;
justify-content: flex-start;
gap: 22px;
padding: 20px 22px 24px;
}
.app--shell .wb-tiles {
grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
gap: 12px;
}
.app--shell .app-main .wb-tile {
min-height: 72px;
padding: 14px 16px;
gap: 14px;
border: 1px solid var(--nx-line);
border-radius: 10px;
background: var(--nx-surface-2);
transition: border-color 0.16s ease, background 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}
.app--shell .app-main .wb-tile:hover,
.app--shell .app-main .wb-tile:focus-visible {
border-color: rgb(var(--nx-accent-rgb) / 0.6);
background: linear-gradient(180deg, rgb(var(--nx-accent-rgb) / 0.16), var(--nx-surface-2));
box-shadow: 0 6px 18px rgb(0 0 0 / 0.3);
transform: translateY(-2px);
}
.app--shell .wb-tile__label {
font-size: 14px;
font-weight: 600;
color: var(--nx-text);
}
.app--shell .wb-card__icon {
--wb-icon: var(--nx-text-muted);
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border-radius: 10px;
color: var(--wb-icon);
background: color-mix(in oklab, var(--wb-icon) 14%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--wb-icon) 28%, transparent);
}
.app--shell .wb-card__icon svg {
width: 20px;
height: 20px;
}
.app--shell .wb-card__icon--blue {
--wb-icon: var(--nx-accent);
}
.app--shell .wb-card__icon--green {
--wb-icon: #34d399;
}
.app--shell .wb-card__icon--amber {
--wb-icon: var(--nx-warn);
}
.app--shell .wb-card__icon--slate {
--wb-icon: var(--nx-text-soft);
}
.app--shell .wb-fleet {
padding: 14px 16px 16px;
gap: 12px;
}
.app--shell .wb-fleet__head {
padding-bottom: 8px;
border-bottom-color: var(--nx-line-soft);
}
.app--shell .wb-fleet__grid {
gap: 12px;
}
.app--shell .wb-fleet__card {
padding: 12px 12px 10px;
border: 1px solid var(--nx-line);
border-radius: 10px;
background: rgb(var(--nx-ink-deep-rgb) / 0.45);
}
.app--shell button.wb-fleet__card:hover,
.app--shell button.wb-fleet__card:focus-visible,
.app--shell .wb-fleet__card--sched:hover,
.app--shell .wb-fleet__card--sched:focus-visible {
border-color: rgb(var(--nx-accent-rgb) / 0.55);
background: rgb(var(--nx-accent-rgb) / 0.1);
}
.app--shell .wb-fleet__card-badge,
.app--shell .wb-fleet__donut-unit,
.app--shell .wb-fleet__foot,
.app--shell .wb-fleet__row-age,
.app--shell .wb-fleet__sched-age,
.app--shell .wb-rail__meta,
.app--shell .wb-rail__progress,
.app--shell .wb-rail__empty {
color: var(--nx-text-faint);
}
.app--shell .wb-fleet__card-badge,
.app--shell .wb-fleet__foot {
font-size: 11px;
}
.app--shell .wb-rail {
padding: 16px 16px 14px;
}
.app--shell .wb-rail__count {
border-radius: 999px;
min-width: 20px;
height: 20px;
background: var(--nx-accent-soft);
color: var(--nx-accent-text);
}
.app--shell .wb-rail__list {
gap: 8px;
}
.app--shell .app-main button.wb-rail__item,
.app--shell .wb-rail__item {
padding: 11px 12px;
border: 1px solid var(--nx-line);
border-radius: 10px;
background: rgb(var(--nx-ink-deep-rgb) / 0.45);
}
.app--shell .app-main button.wb-rail__item:hover,
.app--shell .app-main button.wb-rail__item:focus-visible {
background: var(--nx-accent-soft);
border-color: rgb(var(--nx-accent-rgb) / 0.5);
}
.app--shell .wb-rail__item-title {
font-size: 13px;
}
.app--shell .wb-rail__item-meta {
font-size: 12px;
color: var(--nx-text-muted);
}
/* Workbench styles are owned by pages/workbench.css. */
/* ---------------------------------------------------------- 4. Nav + panels */
.app--shell .network-nav {