Доработки

This commit is contained in:
NikitaKalitov
2026-07-15 09:16:04 +03:00
parent 8bbee2dc7e
commit be2504d60d
7 changed files with 133 additions and 54 deletions
+69
View File
@@ -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">