mirror of
https://github.com/hansjone/netx.git
synced 2026-10-19 01:53:18 +08:00
Default discover auto-placeholder and canvas neighbor project on.
Sync the canvas auto-add toggle with the shared LLDP collect policy so topology collect and canvas discover stay consistent. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
af91c09d80
commit
51f061032a
4 changed files with 43 additions and 8 deletions
|
|
@ -335,7 +335,9 @@ const en = {
|
||||||
policyTitle: "Collect policy",
|
policyTitle: "Collect policy",
|
||||||
policySaved: "Policy saved",
|
policySaved: "Policy saved",
|
||||||
enabled: "Enable scheduled collect",
|
enabled: "Enable scheduled collect",
|
||||||
autoAddUnmatched: "Create SSH placeholder NEs for unmatched neighbors",
|
autoAddUnmatched: "Auto-add unmatched neighbors as placeholders on discover",
|
||||||
|
autoAddUnmatchedHint:
|
||||||
|
"Shared by scheduled collect and canvas discover. Off = record unmatched only, no placeholder NE. Default on.",
|
||||||
intervalDays: "Interval (days)",
|
intervalDays: "Interval (days)",
|
||||||
interval: "Collect interval",
|
interval: "Collect interval",
|
||||||
intervalUnitDays: "days",
|
intervalUnitDays: "days",
|
||||||
|
|
@ -1444,7 +1446,7 @@ const en = {
|
||||||
alignNeedSelection: "Select at least two nodes",
|
alignNeedSelection: "Select at least two nodes",
|
||||||
snapGrid: "Snap to grid",
|
snapGrid: "Snap to grid",
|
||||||
autoLayoutDiscover: "Auto-layout after discover",
|
autoLayoutDiscover: "Auto-layout after discover",
|
||||||
discoverAutoAddUnmatched: "Auto-add unmatched NEs to fabric on discover",
|
discoverAutoAddUnmatched: "Auto-add unmatched NEs as placeholders on discover",
|
||||||
discoverProjectNeighbors: "Project direct neighbors onto canvas after discover",
|
discoverProjectNeighbors: "Project direct neighbors onto canvas after discover",
|
||||||
undo: "Undo",
|
undo: "Undo",
|
||||||
redo: "Redo",
|
redo: "Redo",
|
||||||
|
|
|
||||||
|
|
@ -332,7 +332,8 @@ const zh = {
|
||||||
policyTitle: "采集策略",
|
policyTitle: "采集策略",
|
||||||
policySaved: "策略已保存",
|
policySaved: "策略已保存",
|
||||||
enabled: "启用周期调度",
|
enabled: "启用周期调度",
|
||||||
autoAddUnmatched: "未纳管邻居建 SSH 占位网元",
|
autoAddUnmatched: "发现时自动入库未匹配网元(占位)",
|
||||||
|
autoAddUnmatchedHint: "周期采集与画布单点发现共用;关闭则未匹配邻居只记未匹配、不建占位网元。默认开启。",
|
||||||
intervalDays: "周期(天)",
|
intervalDays: "周期(天)",
|
||||||
interval: "采集周期",
|
interval: "采集周期",
|
||||||
intervalUnitDays: "天",
|
intervalUnitDays: "天",
|
||||||
|
|
@ -1437,7 +1438,7 @@ const zh = {
|
||||||
alignNeedSelection: "请至少选中两个节点",
|
alignNeedSelection: "请至少选中两个节点",
|
||||||
snapGrid: "网格吸附",
|
snapGrid: "网格吸附",
|
||||||
autoLayoutDiscover: "发现后自动布局",
|
autoLayoutDiscover: "发现后自动布局",
|
||||||
discoverAutoAddUnmatched: "发现时自动入库未匹配网元",
|
discoverAutoAddUnmatched: "发现时自动入库未匹配网元(占位)",
|
||||||
discoverProjectNeighbors: "发现后将直连邻居加入画布",
|
discoverProjectNeighbors: "发现后将直连邻居加入画布",
|
||||||
undo: "撤销",
|
undo: "撤销",
|
||||||
redo: "重做",
|
redo: "重做",
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import {
|
||||||
createTopologyView,
|
createTopologyView,
|
||||||
deleteTopologyFolder,
|
deleteTopologyFolder,
|
||||||
deleteTopologyMap,
|
deleteTopologyMap,
|
||||||
|
fetchLldpCollectDashboard,
|
||||||
fetchLldpDiscoverJob,
|
fetchLldpDiscoverJob,
|
||||||
fetchManagedNe,
|
fetchManagedNe,
|
||||||
fetchManagedNeById,
|
fetchManagedNeById,
|
||||||
|
|
@ -52,6 +53,7 @@ import {
|
||||||
removeTopologyViewNodes,
|
removeTopologyViewNodes,
|
||||||
searchFabricNodes,
|
searchFabricNodes,
|
||||||
startLldpDiscover,
|
startLldpDiscover,
|
||||||
|
updateLldpCollectPolicy,
|
||||||
updateTopologyFolder,
|
updateTopologyFolder,
|
||||||
updateTopologyMap,
|
updateTopologyMap,
|
||||||
} from "../services/api";
|
} from "../services/api";
|
||||||
|
|
@ -458,8 +460,8 @@ type EdgeDefaults = Record<EdgeSourceKind, EdgeDefaultStyle>;
|
||||||
|
|
||||||
const EDGE_DEFAULTS_KEY = "netx.topology.edgeDefaults";
|
const EDGE_DEFAULTS_KEY = "netx.topology.edgeDefaults";
|
||||||
const AUTO_LAYOUT_DISCOVER_KEY = "netx.topology.autoLayoutAfterDiscover";
|
const AUTO_LAYOUT_DISCOVER_KEY = "netx.topology.autoLayoutAfterDiscover";
|
||||||
const DISCOVER_AUTO_ADD_KEY = "netx.topology.discoverAutoAddUnmatched";
|
const DISCOVER_AUTO_ADD_KEY = "netx.topology.discoverAutoAddUnmatched.v2";
|
||||||
const DISCOVER_PROJECT_NEIGHBORS_KEY = "netx.topology.discoverProjectNeighbors";
|
const DISCOVER_PROJECT_NEIGHBORS_KEY = "netx.topology.discoverProjectNeighbors.v2";
|
||||||
const SCALE_BUNDLE_WIDTH_KEY = "netx.topology.scaleBundleWidth";
|
const SCALE_BUNDLE_WIDTH_KEY = "netx.topology.scaleBundleWidth";
|
||||||
const CANVAS_BG_KEY = "netx.topology.canvasBg";
|
const CANVAS_BG_KEY = "netx.topology.canvasBg";
|
||||||
const DEFAULT_CANVAS_BG = "#0f172a";
|
const DEFAULT_CANVAS_BG = "#0f172a";
|
||||||
|
|
@ -845,10 +847,10 @@ export function TopologyPage() {
|
||||||
const [snapToGrid, setSnapToGrid] = useState(true);
|
const [snapToGrid, setSnapToGrid] = useState(true);
|
||||||
const [autoLayoutAfterDiscover, setAutoLayoutAfterDiscover] = useState(loadAutoLayoutAfterDiscover);
|
const [autoLayoutAfterDiscover, setAutoLayoutAfterDiscover] = useState(loadAutoLayoutAfterDiscover);
|
||||||
const [discoverAutoAddUnmatched, setDiscoverAutoAddUnmatched] = useState(() =>
|
const [discoverAutoAddUnmatched, setDiscoverAutoAddUnmatched] = useState(() =>
|
||||||
loadBoolFlag(DISCOVER_AUTO_ADD_KEY, false),
|
loadBoolFlag(DISCOVER_AUTO_ADD_KEY, true),
|
||||||
);
|
);
|
||||||
const [discoverProjectNeighbors, setDiscoverProjectNeighbors] = useState(() =>
|
const [discoverProjectNeighbors, setDiscoverProjectNeighbors] = useState(() =>
|
||||||
loadBoolFlag(DISCOVER_PROJECT_NEIGHBORS_KEY, false),
|
loadBoolFlag(DISCOVER_PROJECT_NEIGHBORS_KEY, true),
|
||||||
);
|
);
|
||||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
||||||
const [addNeOpen, setAddNeOpen] = useState(false);
|
const [addNeOpen, setAddNeOpen] = useState(false);
|
||||||
|
|
@ -1049,6 +1051,24 @@ export function TopologyPage() {
|
||||||
}
|
}
|
||||||
}, [mapId]);
|
}, [mapId]);
|
||||||
|
|
||||||
|
// Keep canvas "auto placeholder" in sync with topology LLDP collect policy (shared strategy).
|
||||||
|
useEffect(() => {
|
||||||
|
let alive = true;
|
||||||
|
void fetchLldpCollectDashboard()
|
||||||
|
.then((dash) => {
|
||||||
|
if (!alive || !dash?.policy) return;
|
||||||
|
const next = Boolean(dash.policy.auto_add_unmatched);
|
||||||
|
setDiscoverAutoAddUnmatched(next);
|
||||||
|
persistBoolFlag(DISCOVER_AUTO_ADD_KEY, next);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
/* keep local default */
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
alive = false;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const neQuery = useQuery({
|
const neQuery = useQuery({
|
||||||
queryKey: [...queryKeys.managedNeAll, "topology-add-ne", debouncedKeyword],
|
queryKey: [...queryKeys.managedNeAll, "topology-add-ne", debouncedKeyword],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
|
|
@ -3097,6 +3117,15 @@ export function TopologyPage() {
|
||||||
const next = e.target.checked;
|
const next = e.target.checked;
|
||||||
setDiscoverAutoAddUnmatched(next);
|
setDiscoverAutoAddUnmatched(next);
|
||||||
persistBoolFlag(DISCOVER_AUTO_ADD_KEY, next);
|
persistBoolFlag(DISCOVER_AUTO_ADD_KEY, next);
|
||||||
|
void updateLldpCollectPolicy({ auto_add_unmatched: next })
|
||||||
|
.then(() => {
|
||||||
|
void queryClient.invalidateQueries({
|
||||||
|
queryKey: queryKeys.lldpCollectDashboard,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
/* local toggle still applies to this canvas discover */
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{t("topology.discoverAutoAddUnmatched")}
|
{t("topology.discoverAutoAddUnmatched")}
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,9 @@ export function LldpLinksPage() {
|
||||||
<input type="checkbox" checked={autoAdd} onChange={(e) => setAutoAdd(e.target.checked)} />
|
<input type="checkbox" checked={autoAdd} onChange={(e) => setAutoAdd(e.target.checked)} />
|
||||||
<span>{t("lldpLinks.autoAddUnmatched")}</span>
|
<span>{t("lldpLinks.autoAddUnmatched")}</span>
|
||||||
</label>
|
</label>
|
||||||
|
<p className="muted" style={{ margin: "0 0 8px", gridColumn: "1 / -1" }}>
|
||||||
|
{t("lldpLinks.autoAddUnmatchedHint")}
|
||||||
|
</p>
|
||||||
<label className="config-sync-policy-field">
|
<label className="config-sync-policy-field">
|
||||||
<span>{t("lldpLinks.interval")}</span>
|
<span>{t("lldpLinks.interval")}</span>
|
||||||
<input
|
<input
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue