Optimize topology canvas per the 2026-10-12 plan.

Save path: one atomic POST /views/{id}/commit (edges, ports, styles, node
add/remove, positions) replaces the multi-request save. Edge styles and
manual-edge port edits now go through dirty/undo/save instead of writing
immediately; non-manual edge ports are read-only.

Data safety: UI saves no longer clear MCP node locks or freeze the device
name into the placement label (label_override + omit-means-keep semantics,
also applied to the MCP positions tool). Adding NEs/neighbors with unsaved
edits now saves first instead of silently dropping them. Positions no longer
bypass membership caps, except persisting synthesized child-region icons.

Fixes found in acceptance: nodes added in the same commit kept (40,40)
under autoflush=False; edits on edges deleted in the same save 404'd the
whole save; box-selection drags and arrow-key moves were not marked dirty;
large canvases far from the origin opened blank and locate did nothing
because fitView waits for measurement that onlyRenderVisibleElements never
does (now fitBounds from known geometry).

Also: batch N+1 lookups in graph/positions, deterministic truncation,
outside-peer scan excludes internal edges, split TopologyPage into hooks,
fix flaky UME/LLDP port test, add scripts/topology_clear_frozen_labels.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
oliver 2026-10-12 22:11:22 +08:00
parent 60a0ea6021
commit f301544b99
40 changed files with 5587 additions and 1916 deletions

View file

@ -3086,6 +3086,22 @@
opacity: 0.92;
}
.topo-node__lock {
position: absolute;
top: -4px;
left: -6px;
z-index: 2;
display: inline-flex;
align-items: center;
justify-content: center;
width: 14px;
height: 14px;
border-radius: 999px;
background: color-mix(in srgb, var(--nx-surface-2) 82%, #94a3b8 18%);
border: 1px solid rgb(var(--nx-ink-rgb) / 0.28);
color: var(--nx-text-muted);
pointer-events: none;
}
.topo-node__badge {
position: absolute;
top: -4px;