diff --git a/web/WEB.md b/web/WEB.md
index bc4f742..aceb178 100644
--- a/web/WEB.md
+++ b/web/WEB.md
@@ -35,17 +35,17 @@ src/
| `/ume` | UME 同步 | `ume` |
| `/network` | 网络管理(左栏 + 子路由) | `network` |
| `/network/devices` | 设备列表 | `network` |
-| `/network/topology` | 拓扑信息 | `network` |
| `/network/alarms` | 告警信息 | `network` |
| `/network/configs` | 配置信息(同步快照) | `network` |
-| `/network/webcrt` | WebCRT 终端 | `network` |
+| `/network/webcrt` | redirect → `/webcrt`(保留 query) | — |
+| `/network/topology` | redirect → `/topology` | — |
| `/network/tasks/collect` | 采集任务 | `network` |
| `/network/tasks/config-sync` | 配置同步 | `network` |
| `/network/tasks/port-traffic` | 端口流量(占位) | `network` |
+| `/topology` | 拓扑管理 | `topology` |
+| `/webcrt` | WebCRT 终端 | `webcrt` |
| `/ne` | redirect → `/network/devices` | — |
| `/collect` | redirect → `/network/tasks/collect` | — |
-| `/topology` | redirect → `/network/topology` | — |
-| `/webcrt` | redirect → `/network/webcrt`(保留 query) | — |
菜单树见 `config/networkNav.ts`。**新增网络子页:**
diff --git a/web/src/App.tsx b/web/src/App.tsx
index b3f6577..b50bd43 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -21,10 +21,10 @@ import { ForceChangePasswordPage } from "./pages/ForceChangePasswordPage";
import { fetchIntegrationStatus } from "./services/api";
import { useAuth } from "./auth/AuthContext";
-/** Preserve ?ne_id=… when redirecting legacy /webcrt into the network module. */
-function WebcrtLegacyRedirect() {
+/** Preserve query when redirecting legacy /network/webcrt → /webcrt. */
+function NetworkWebcrtRedirect() {
const { search } = useLocation();
- return ;
+ return ;
}
function ProtectedApp() {
@@ -82,21 +82,21 @@ function ProtectedApp() {
} />
} />
} />
+ } />
+ } />
}>
} />
} />
- } />
} />
} />
- } />
+ } />
+ } />
} />
} />
} />
} />
} />
- } />
- } />
} />
} />
} />
diff --git a/web/src/config/modules.ts b/web/src/config/modules.ts
index 053b6ed..ea5078c 100644
--- a/web/src/config/modules.ts
+++ b/web/src/config/modules.ts
@@ -35,6 +35,24 @@ export const MODULES: readonly ModuleDefinition[] = [
iconTone: "green",
titleKey: "layout.titleNetwork",
},
+ {
+ moduleId: "topology",
+ path: "/topology",
+ section: "operations",
+ labelKey: "workbench.cards.topology",
+ descKey: "workbench.cards.topologyDesc",
+ iconTone: "amber",
+ titleKey: "layout.titleTopology",
+ },
+ {
+ moduleId: "webcrt",
+ path: "/webcrt",
+ section: "operations",
+ labelKey: "workbench.cards.webcrt",
+ descKey: "workbench.cards.webcrtDesc",
+ iconTone: "slate",
+ titleKey: "layout.titleWebcrt",
+ },
{
moduleId: "users",
path: "/users",
diff --git a/web/src/config/networkNav.ts b/web/src/config/networkNav.ts
index cacedc8..2c34720 100644
--- a/web/src/config/networkNav.ts
+++ b/web/src/config/networkNav.ts
@@ -24,10 +24,8 @@ export const NETWORK_NAV: readonly NetworkNavGroup[] = [
labelKey: "network.nav.detail",
items: [
{ id: "devices", path: "/network/devices", labelKey: "network.nav.devices", group: "detail" },
- { id: "topology", path: "/network/topology", labelKey: "network.nav.topology", group: "detail" },
{ id: "alarms", path: "/network/alarms", labelKey: "network.nav.alarms", group: "detail" },
{ id: "configs", path: "/network/configs", labelKey: "network.nav.configs", group: "detail" },
- { id: "webcrt", path: "/network/webcrt", labelKey: "network.nav.webcrt", group: "detail" },
],
},
{
diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts
index a342363..c4f1d4a 100644
--- a/web/src/i18n/en.ts
+++ b/web/src/i18n/en.ts
@@ -24,7 +24,7 @@ const en = {
umeSync: "UME Sync",
umeSyncDesc: "UME alarms, subscription & inventory",
network: "Network Management",
- networkDesc: "Devices, topology, alarms, WebCRT, and monitoring tasks",
+ networkDesc: "Devices, alarms, config sync, and monitoring tasks",
managedNe: "NE Management",
managedNeDesc: "Multi-vendor SSH/Telnet NEs & connectivity test",
collect: "Batch Collect",
diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts
index 0c33358..8906f29 100644
--- a/web/src/i18n/zh.ts
+++ b/web/src/i18n/zh.ts
@@ -24,7 +24,7 @@ const zh = {
umeSync: "UME同步",
umeSyncDesc: "UME 告警同步、订阅与清单",
network: "网络管理",
- networkDesc: "设备、拓扑、告警、WebCRT 与监控任务",
+ networkDesc: "设备、告警、配置同步与监控任务",
managedNe: "网元管理",
managedNeDesc: "多厂商 SSH/Telnet 网元与连通性测试",
collect: "批量采集",
diff --git a/web/src/index.css b/web/src/index.css
index b87cc07..ded196a 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -798,6 +798,52 @@ pre {
width: 100%;
}
+.config-sync-policy-row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 10px 16px;
+}
+
+.config-sync-policy-check {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin: 0;
+ font-size: 13px;
+ color: #334155;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.config-sync-policy-check input {
+ width: 14px;
+ height: 14px;
+ margin: 0;
+ flex-shrink: 0;
+}
+
+.config-sync-policy-field {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin: 0;
+ font-size: 13px;
+ color: #334155;
+ white-space: nowrap;
+}
+
+.config-sync-policy-field input[type="number"] {
+ width: 64px;
+ margin: 0;
+}
+
+.config-sync-policy-field select {
+ width: auto;
+ min-width: 110px;
+ margin: 0;
+}
+
.ne-stats-card {
padding: 12px 14px;
}
@@ -2708,12 +2754,13 @@ pre {
width: 28px;
height: 28px;
padding: 0;
- border: 1px solid #cbd5e1;
+ border: 0;
border-radius: 6px;
- background: #fff;
- color: #475569;
+ background: transparent;
+ color: #64748b;
cursor: pointer;
line-height: 1;
+ box-shadow: none;
}
.app-main .network-nav__collapse-btn:hover,
diff --git a/web/src/pages/ConfigSyncPage.tsx b/web/src/pages/ConfigSyncPage.tsx
index 920b031..509a386 100644
--- a/web/src/pages/ConfigSyncPage.tsx
+++ b/web/src/pages/ConfigSyncPage.tsx
@@ -235,46 +235,43 @@ export function ConfigSyncPage() {
{t("configSync.policyTitle")}
-
-