mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 05:30:46 +08:00
Stop auto-creating maps on new regions; keep aggregate edges single-width by default.
This commit is contained in:
parent
4abb037dce
commit
af29977878
10 changed files with 58 additions and 40 deletions
|
|
@ -1260,7 +1260,7 @@ const en = {
|
|||
maps: "Maps",
|
||||
tree: "Topology tree",
|
||||
treeLoading: "Loading tree…",
|
||||
treeHint: "Regions hold a physical map plus optional custom maps; open a map to edit the canvas.",
|
||||
treeHint: "Regions hold maps you create; open a map to edit the canvas.",
|
||||
treeSearch: "Search NEs across maps",
|
||||
treeSearchPh: "Name / IP",
|
||||
treeSearchEmpty: "No matching NEs",
|
||||
|
|
@ -1279,7 +1279,7 @@ const en = {
|
|||
layerNodeEmpty: "Click to create & open",
|
||||
rootCanvasHint: "Pick a region from the left tree.",
|
||||
regionCanvasHint: "Open a map to edit devices, or create a custom map.",
|
||||
regionBrowseHint: "Region folder: physical + custom maps. Click to open.",
|
||||
regionBrowseHint: "Region folder: maps you add. Click to open.",
|
||||
browserTitle: "Topology folder",
|
||||
browserRegionSub: "{{count}} map(s)",
|
||||
browserRegionsSub: "{{count}} region(s)",
|
||||
|
|
@ -1292,7 +1292,7 @@ const en = {
|
|||
regionCreated: "Region created",
|
||||
regionDeleted: "Region deleted",
|
||||
deleteRegion: "Delete region",
|
||||
deleteRegionConfirm: "Delete region \"{{name}}\"? Its physical and custom maps will also be deleted.",
|
||||
deleteRegionConfirm: "Delete region \"{{name}}\"? Its maps will also be deleted.",
|
||||
renameRegion: "Rename region",
|
||||
renameRegionPrompt: "Region name",
|
||||
regionRenamed: "Region renamed",
|
||||
|
|
@ -1301,7 +1301,7 @@ const en = {
|
|||
newCustom: "Custom map",
|
||||
newCustomName: "Custom topology",
|
||||
newCustomPrompt: "Custom map name",
|
||||
folderHint: "Regions group maps. Each region gets a physical map; add custom maps as needed.",
|
||||
folderHint: "Regions group maps. After creating a region, add a physical or custom map yourself.",
|
||||
folderHintShort: "Region folder",
|
||||
outsidePeers: "{{count}} outside peer(s) linked but not on this map",
|
||||
newMap: "New",
|
||||
|
|
@ -1341,9 +1341,10 @@ const en = {
|
|||
endpointB: "Endpoint B",
|
||||
port: "port",
|
||||
expandPhysicalLinks: "Expand physical links",
|
||||
scaleBundleWidth: "Thicken bundles by link count",
|
||||
linkMembers: "Physical members ({{count}})",
|
||||
canvasHint:
|
||||
"Left tree lists regions with a physical map and optional custom maps. Open a map to edit devices; use Add NE and save positions.",
|
||||
"Left tree lists regions; add maps yourself, then open a map to edit devices with Add NE and save positions.",
|
||||
selected: "Selected",
|
||||
selectedEdge: "Selected edge",
|
||||
selectedCount: "{{count}} selected",
|
||||
|
|
|
|||
|
|
@ -1254,7 +1254,7 @@ const zh = {
|
|||
maps: "拓扑图",
|
||||
tree: "拓扑树",
|
||||
treeLoading: "加载拓扑树…",
|
||||
treeHint: "区域下为物理拓扑与自定义图;点图打开设备画布。",
|
||||
treeHint: "区域下为画布列表;点图打开设备画布(区域本身不自动建图)。",
|
||||
treeSearch: "全拓扑搜索网元",
|
||||
treeSearchPh: "名称 / IP",
|
||||
treeSearchEmpty: "没有匹配的网元",
|
||||
|
|
@ -1273,7 +1273,7 @@ const zh = {
|
|||
layerNodeEmpty: "点击创建并打开",
|
||||
rootCanvasHint: "从左侧选择区域进入目录。",
|
||||
regionCanvasHint: "点击图打开设备画布,或新建自定义图。",
|
||||
regionBrowseHint: "区域目录:物理拓扑 + 自定义图。点击打开。",
|
||||
regionBrowseHint: "区域目录:自行添加的画布。点击打开。",
|
||||
browserTitle: "拓扑目录",
|
||||
browserRegionSub: "共 {{count}} 张拓扑图",
|
||||
browserRegionsSub: "共 {{count}} 个区域",
|
||||
|
|
@ -1286,7 +1286,7 @@ const zh = {
|
|||
regionCreated: "区域已创建",
|
||||
regionDeleted: "区域已删除",
|
||||
deleteRegion: "删除区域",
|
||||
deleteRegionConfirm: "删除区域「{{name}}」?其下物理拓扑与自定义图将一并删除。",
|
||||
deleteRegionConfirm: "删除区域「{{name}}」?其下画布将一并删除。",
|
||||
renameRegion: "重命名区域",
|
||||
renameRegionPrompt: "区域名称",
|
||||
regionRenamed: "区域已重命名",
|
||||
|
|
@ -1295,7 +1295,7 @@ const zh = {
|
|||
newCustom: "自定义图",
|
||||
newCustomName: "自定义拓扑",
|
||||
newCustomPrompt: "自定义拓扑图名称",
|
||||
folderHint: "区域用于分组。每区有一张物理拓扑,可再加自定义图。",
|
||||
folderHint: "区域用于分组。新建区域后请自行添加物理拓扑或自定义图。",
|
||||
folderHintShort: "区域目录",
|
||||
outsidePeers: "图外对端 {{count}} 个(有链路未上图)",
|
||||
newMap: "新建",
|
||||
|
|
@ -1335,9 +1335,10 @@ const zh = {
|
|||
endpointB: "端点 B",
|
||||
port: "端口",
|
||||
expandPhysicalLinks: "展开物理链路",
|
||||
scaleBundleWidth: "聚合线按条数加粗",
|
||||
linkMembers: "物理成员({{count}})",
|
||||
canvasHint:
|
||||
"左侧为区域目录(物理拓扑 + 自定义图);打开本图后进入设备画布,用「添加网元」上图并保存。",
|
||||
"左侧为区域目录(需自行添加画布);打开本图后进入设备画布,用「添加网元」上图并保存。",
|
||||
selected: "已选节点",
|
||||
selectedEdge: "已选链路",
|
||||
selectedCount: "已选 {{count}}",
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ const EDGE_DEFAULTS_KEY = "netx.topology.edgeDefaults";
|
|||
const AUTO_LAYOUT_DISCOVER_KEY = "netx.topology.autoLayoutAfterDiscover";
|
||||
const DISCOVER_AUTO_ADD_KEY = "netx.topology.discoverAutoAddUnmatched";
|
||||
const DISCOVER_PROJECT_NEIGHBORS_KEY = "netx.topology.discoverProjectNeighbors";
|
||||
const SCALE_BUNDLE_WIDTH_KEY = "netx.topology.scaleBundleWidth";
|
||||
|
||||
function loadBoolFlag(key: string, defaultValue: boolean): boolean {
|
||||
try {
|
||||
|
|
@ -696,6 +697,10 @@ export function TopologyPage() {
|
|||
const [hidePorts, setHidePorts] = useState(true);
|
||||
/** Default: logical aggregate of parallel links; expand to see each physical edge. */
|
||||
const [expandPhysicalLinks, setExpandPhysicalLinks] = useState(false);
|
||||
/** When aggregating, optionally thicken the line by member count (off = single-line width). */
|
||||
const [scaleBundleWidth, setScaleBundleWidth] = useState(() =>
|
||||
loadBoolFlag(SCALE_BUNDLE_WIDTH_KEY, false),
|
||||
);
|
||||
const [edgeFlow, setEdgeFlow] = useState(false);
|
||||
const [edgeDefaults, setEdgeDefaults] = useState<EdgeDefaults>(() => loadEdgeDefaults());
|
||||
const [toolMode, setToolMode] = useState<ToolMode>("select");
|
||||
|
|
@ -802,7 +807,7 @@ export function TopologyPage() {
|
|||
[hideIp, hideVendor, hidePorts, toolMode],
|
||||
);
|
||||
const displayEdges = useMemo(() => {
|
||||
const built = buildLinkDisplayEdges(edges, expandPhysicalLinks, hidePorts).map((e) =>
|
||||
const built = buildLinkDisplayEdges(edges, expandPhysicalLinks, hidePorts, scaleBundleWidth).map((e) =>
|
||||
withEdgeVisual(e, edgeDefaults),
|
||||
);
|
||||
return built.map((e) => {
|
||||
|
|
@ -818,7 +823,7 @@ export function TopologyPage() {
|
|||
animated: edgeFlow,
|
||||
};
|
||||
});
|
||||
}, [edges, expandPhysicalLinks, hidePorts, edgeFlow, edgeDefaults, selectedEdgeId]);
|
||||
}, [edges, expandPhysicalLinks, hidePorts, scaleBundleWidth, edgeFlow, edgeDefaults, selectedEdgeId]);
|
||||
|
||||
const treeQuery = useQuery({
|
||||
queryKey: queryKeys.topologyTree,
|
||||
|
|
@ -2757,6 +2762,19 @@ export function TopologyPage() {
|
|||
/>
|
||||
{t("topology.expandPhysicalLinks")}
|
||||
</label>
|
||||
<label className="topo-display-toggles__item">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={scaleBundleWidth}
|
||||
disabled={expandPhysicalLinks}
|
||||
onChange={(e) => {
|
||||
const next = e.target.checked;
|
||||
setScaleBundleWidth(next);
|
||||
persistBoolFlag(SCALE_BUNDLE_WIDTH_KEY, next);
|
||||
}}
|
||||
/>
|
||||
{t("topology.scaleBundleWidth")}
|
||||
</label>
|
||||
<label className="topo-display-toggles__item">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ export function buildLinkDisplayEdges(
|
|||
edges: Edge[],
|
||||
expandPhysical: boolean,
|
||||
hidePorts = false,
|
||||
scaleBundleWidth = false,
|
||||
): Edge[] {
|
||||
const groups = new Map<string, Edge[]>();
|
||||
for (const e of edges) {
|
||||
|
|
@ -153,9 +154,11 @@ export function buildLinkDisplayEdges(
|
|||
aggregated: true,
|
||||
member_count: list.length,
|
||||
members,
|
||||
// Slightly thicker logical bundle.
|
||||
stroke_width: Math.max(Number(prev.stroke_width || 0), Math.min(8, 2 + list.length)),
|
||||
};
|
||||
// Optional: thicken logical bundles by member count (default keeps single-line width).
|
||||
if (scaleBundleWidth) {
|
||||
data.stroke_width = Math.max(Number(prev.stroke_width || 0), Math.min(8, 2 + list.length));
|
||||
}
|
||||
out.push({
|
||||
...primary,
|
||||
id: aggregateIdForPair(primary.source, primary.target),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue