fix: replace Proxmox cluster handles with configurable side points
The Proxmox node had two always-on cluster-left/cluster-right handles that rendered independently of the new per-side connection-point config — so a configured side stacked on top of the forced handle (e.g. 0 config still showed 1; 2 config left the forced one in the middle). - ProxmoxGroupNode: remove the always-on cluster handles in both container and non-container modes; cluster links now use the normal per-side points - add migrateClusterHandles(nodes, edges): on load, remap any edge still bound to cluster-left/right onto the left/right slot-0 point and set that node's side count to at least 1, so existing links survive (edge 'cluster' type/style kept). Applied on API load, standalone load, LiveView, and YAML import - App: new cluster links are made by choosing the Cluster edge type in the edge modal (drop the cluster-handle auto-default) ha-relevant: yes
This commit is contained in:
@@ -2,7 +2,7 @@ import { useEffect, useCallback, useRef, useState } from 'react'
|
||||
import { ReactFlowProvider, type Connection, type Edge } from '@xyflow/react'
|
||||
import { type Node } from '@xyflow/react'
|
||||
import { applyDagreLayout } from '@/utils/layout'
|
||||
import { serializeNode, serializeEdge, deserializeApiNode, deserializeApiEdge, type ApiNode, type ApiEdge } from '@/utils/canvasSerializer'
|
||||
import { serializeNode, serializeEdge, deserializeApiNode, deserializeApiEdge, migrateClusterHandles, type ApiNode, type ApiEdge } from '@/utils/canvasSerializer'
|
||||
import { generateUUID } from '@/utils/uuid'
|
||||
import { getCenteredPosition } from '@/utils/viewportCenter'
|
||||
import { resolveVirtualEdgeParent } from '@/utils/virtualEdgeParent'
|
||||
@@ -125,8 +125,10 @@ export default function App() {
|
||||
.filter((n) => n.type === 'group' || n.container_mode === true)
|
||||
.map((n) => [n.id, true])
|
||||
)
|
||||
const rfNodes = (apiNodes as ApiNode[]).map((n) => deserializeApiNode(n, proxmoxContainerMap))
|
||||
const rfEdges = (apiEdges as ApiEdge[]).map(deserializeApiEdge)
|
||||
const { nodes: rfNodes, edges: rfEdges } = migrateClusterHandles(
|
||||
(apiNodes as ApiNode[]).map((n) => deserializeApiNode(n, proxmoxContainerMap)),
|
||||
(apiEdges as ApiEdge[]).map(deserializeApiEdge),
|
||||
)
|
||||
const savedTheme = res.data.viewport?.theme_id
|
||||
if (savedTheme) setTheme(savedTheme)
|
||||
if (res.data.custom_style) setCustomStyle(res.data.custom_style as CustomStyleDef)
|
||||
@@ -154,7 +156,8 @@ export default function App() {
|
||||
if (saved.custom_style) setCustomStyle(saved.custom_style)
|
||||
// Floor plans are backend-only; keep the store clear in standalone mode.
|
||||
setFloorMap(null)
|
||||
loadCanvas(saved.nodes, saved.edges)
|
||||
const migrated = migrateClusterHandles(saved.nodes, saved.edges)
|
||||
loadCanvas(migrated.nodes, migrated.edges)
|
||||
} else {
|
||||
setFloorMap(null)
|
||||
loadCanvas(demoNodes, demoEdges)
|
||||
@@ -788,11 +791,6 @@ export default function App() {
|
||||
open={!!pendingConnection}
|
||||
onClose={() => setPendingConnection(null)}
|
||||
onSubmit={handleEdgeConfirm}
|
||||
initial={
|
||||
pendingConnection?.sourceHandle?.includes('cluster') || pendingConnection?.targetHandle?.includes('cluster')
|
||||
? { type: 'cluster' }
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
|
||||
<EdgeModal
|
||||
|
||||
Reference in New Issue
Block a user