Доработки
This commit is contained in:
@@ -12,10 +12,12 @@ import {
|
||||
ViewportPortal,
|
||||
useReactFlow,
|
||||
addEdge,
|
||||
reconnectEdge,
|
||||
applyNodeChanges,
|
||||
applyEdgeChanges,
|
||||
type Node,
|
||||
type Edge,
|
||||
type Connection,
|
||||
type OnConnect,
|
||||
type NodeChange,
|
||||
type EdgeChange,
|
||||
@@ -132,6 +134,7 @@ function toRfNodes(doc: DiagramDocument | null): Node[] {
|
||||
data: node.data,
|
||||
width: node.width ?? defaults.width,
|
||||
height: node.height ?? defaults.height,
|
||||
zIndex: node.zIndex,
|
||||
...(node.parentId ? { parentId: node.parentId } : {}),
|
||||
};
|
||||
});
|
||||
@@ -147,6 +150,7 @@ function toRfEdges(doc: DiagramDocument | null): Edge[] {
|
||||
type: edge.type ?? DEFAULT_EDGE_TYPE,
|
||||
markerEnd: DEFAULT_MARKER_END,
|
||||
label: edge.label,
|
||||
zIndex: edge.zIndex,
|
||||
data: edge.data,
|
||||
}));
|
||||
}
|
||||
@@ -330,6 +334,17 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
[nodes, edges, emitChange, pushHistory],
|
||||
);
|
||||
|
||||
const onReconnect = useCallback(
|
||||
(oldEdge: Edge, connection: Connection) => {
|
||||
pushHistory(nodes, edges);
|
||||
// Keep the original edge id stable so selection/history don't go stale mid-drag.
|
||||
const next = reconnectEdge(oldEdge, connection, edges, { shouldReplaceId: false });
|
||||
setEdges(next);
|
||||
emitChange(nodes, next);
|
||||
},
|
||||
[nodes, edges, emitChange, pushHistory],
|
||||
);
|
||||
|
||||
const onNodeClick: NodeMouseHandler = useCallback((_event, node) => {
|
||||
setSelectedNodeId(node.id);
|
||||
setSelectedEdgeId(null);
|
||||
@@ -462,6 +477,53 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
setSelectedEdgeId(null);
|
||||
}, [selectedEdgeId, nodes, edges, emitChange, pushHistory]);
|
||||
|
||||
// Nodes and edges share one z-index space (zIndexMode="manual"), so front/back
|
||||
// always means "above/below everything currently on the canvas", not just siblings.
|
||||
const maxZIndex = useCallback(
|
||||
() => Math.max(0, ...nodes.map((n) => n.zIndex ?? 0), ...edges.map((e) => e.zIndex ?? 0)),
|
||||
[nodes, edges],
|
||||
);
|
||||
const minZIndex = useCallback(
|
||||
() => Math.min(0, ...nodes.map((n) => n.zIndex ?? 0), ...edges.map((e) => e.zIndex ?? 0)),
|
||||
[nodes, edges],
|
||||
);
|
||||
|
||||
const bringSelectedNodeToFront = useCallback(() => {
|
||||
if (!selectedNodeId) return;
|
||||
const z = maxZIndex() + 1;
|
||||
pushHistory(nodes, edges);
|
||||
const next = nodes.map((n) => (n.id === selectedNodeId ? { ...n, zIndex: z } : n));
|
||||
setNodes(next);
|
||||
emitChange(next, edges);
|
||||
}, [selectedNodeId, nodes, edges, emitChange, pushHistory, maxZIndex]);
|
||||
|
||||
const sendSelectedNodeToBack = useCallback(() => {
|
||||
if (!selectedNodeId) return;
|
||||
const z = minZIndex() - 1;
|
||||
pushHistory(nodes, edges);
|
||||
const next = nodes.map((n) => (n.id === selectedNodeId ? { ...n, zIndex: z } : n));
|
||||
setNodes(next);
|
||||
emitChange(next, edges);
|
||||
}, [selectedNodeId, nodes, edges, emitChange, pushHistory, minZIndex]);
|
||||
|
||||
const bringSelectedEdgeToFront = useCallback(() => {
|
||||
if (!selectedEdgeId) return;
|
||||
const z = maxZIndex() + 1;
|
||||
pushHistory(nodes, edges);
|
||||
const next = edges.map((e) => (e.id === selectedEdgeId ? { ...e, zIndex: z } : e));
|
||||
setEdges(next);
|
||||
emitChange(nodes, next);
|
||||
}, [selectedEdgeId, nodes, edges, emitChange, pushHistory, maxZIndex]);
|
||||
|
||||
const sendSelectedEdgeToBack = useCallback(() => {
|
||||
if (!selectedEdgeId) return;
|
||||
const z = minZIndex() - 1;
|
||||
pushHistory(nodes, edges);
|
||||
const next = edges.map((e) => (e.id === selectedEdgeId ? { ...e, zIndex: z } : e));
|
||||
setEdges(next);
|
||||
emitChange(nodes, next);
|
||||
}, [selectedEdgeId, nodes, edges, emitChange, pushHistory, minZIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
function onKeyDown(event: KeyboardEvent) {
|
||||
if (mode !== 'edit' || isEditableTarget(event.target)) return;
|
||||
@@ -500,6 +562,8 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
onReconnect={onReconnect}
|
||||
edgesReconnectable={mode === 'edit'}
|
||||
onNodeClick={onNodeClick}
|
||||
onEdgeClick={onEdgeClick}
|
||||
onPaneClick={onPaneClick}
|
||||
@@ -508,6 +572,7 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
deleteKeyCode={mode === 'edit' ? undefined : null}
|
||||
zoomOnDoubleClick={false}
|
||||
connectionMode={ConnectionMode.Loose}
|
||||
zIndexMode="manual"
|
||||
className={mode === 'view' ? 'diagram-flow--view-mode' : undefined}
|
||||
fitView
|
||||
>
|
||||
@@ -589,6 +654,8 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
onEnterSubProcess={enterSubProcess}
|
||||
onDuplicate={duplicateSelectedNode}
|
||||
onDelete={deleteSelectedNode}
|
||||
onBringToFront={bringSelectedNodeToFront}
|
||||
onSendToBack={sendSelectedNodeToBack}
|
||||
/>
|
||||
) : selectedEdge ? (
|
||||
<EdgeInspector
|
||||
@@ -596,6 +663,8 @@ function DiagramCanvas({ initialValue, onChange }: DiagramEditorProps) {
|
||||
label={typeof selectedEdge.label === 'string' ? selectedEdge.label : ''}
|
||||
onChange={updateSelectedEdgeLabel}
|
||||
onDelete={deleteSelectedEdge}
|
||||
onBringToFront={bringSelectedEdgeToFront}
|
||||
onSendToBack={sendSelectedEdgeToBack}
|
||||
/>
|
||||
) : (
|
||||
<p className="diagram-aside__hint">
|
||||
|
||||
Reference in New Issue
Block a user