@inspirer-dev/crm-dashboard 1.0.71 → 1.0.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -119,7 +119,7 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
119
119
 
120
120
  const getClosestEdge = useCallback(
121
121
  (node: Node<FlowNodeData>) => {
122
- const { nodeInternals } = store.getState();
122
+ const { nodeInternals, edges: currentEdges } = store.getState();
123
123
  const internalNode = nodeInternals.get(node.id);
124
124
  if (!internalNode) return null;
125
125
 
@@ -155,60 +155,67 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
155
155
  const closestData = closestNode.node.data as FlowNodeData;
156
156
  const draggedData = node.data;
157
157
 
158
- const draggedIsBelow = draggedPos.y > closestPos.y;
158
+ const nonTempEdges = currentEdges.filter((e) => e.className !== 'temp');
159
159
 
160
- if (draggedIsBelow) {
161
- if (closestData.stepType === 'exit') {
162
- return null;
163
- }
164
- if (closestData.stepType === 'branch') {
165
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
166
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
167
- const isRight = draggedCenterX >= closestCenterX;
168
- const handle = isRight ? 'no' : 'yes';
169
- return {
170
- id: `${closestNode.node.id}-${node.id}-${handle}`,
171
- source: closestNode.node.id,
172
- sourceHandle: handle,
173
- target: node.id,
174
- targetHandle: 'target',
175
- };
176
- }
160
+ const isSourceHandleFree = (sourceId: string, handle: string) =>
161
+ !nonTempEdges.some((e) => e.source === sourceId && e.sourceHandle === handle);
162
+
163
+ const isTargetFree = (targetId: string) =>
164
+ !nonTempEdges.some((e) => e.target === targetId);
165
+
166
+ const buildEdge = (
167
+ sourceId: string,
168
+ sourceHandle: string,
169
+ targetId: string
170
+ ) => {
171
+ const suffix = sourceHandle !== 'source' ? `-${sourceHandle}` : '';
177
172
  return {
178
- id: `${closestNode.node.id}-${node.id}`,
179
- source: closestNode.node.id,
180
- sourceHandle: 'source',
181
- target: node.id,
173
+ id: `${sourceId}-${targetId}${suffix}`,
174
+ source: sourceId,
175
+ sourceHandle,
176
+ target: targetId,
182
177
  targetHandle: 'target',
183
178
  };
184
- } else {
185
- if (draggedData.stepType === 'entry') {
186
- return null;
187
- }
188
- if (closestData.stepType === 'entry') {
189
- return null;
190
- }
191
- if (draggedData.stepType === 'branch') {
192
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
193
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
194
- const isRight = closestCenterX >= draggedCenterX;
179
+ };
180
+
181
+ const trySourceToTarget = (
182
+ srcId: string,
183
+ srcData: FlowNodeData,
184
+ tgtId: string,
185
+ tgtData: FlowNodeData
186
+ ) => {
187
+ if (srcData.stepType === 'exit') return null;
188
+ if (tgtData.stepType === 'entry') return null;
189
+ if (!isTargetFree(tgtId)) return null;
190
+
191
+ if (srcData.stepType === 'branch') {
192
+ const srcPos = srcId === node.id ? draggedPos : closestPos;
193
+ const tgtPos = srcId === node.id ? closestPos : draggedPos;
194
+ const srcCenterX = srcPos.x + NODE_DIMENSIONS.width / 2;
195
+ const tgtCenterX = tgtPos.x + NODE_DIMENSIONS.width / 2;
196
+ const isRight = tgtCenterX >= srcCenterX;
195
197
  const handle = isRight ? 'no' : 'yes';
196
- return {
197
- id: `${node.id}-${closestNode.node.id}-${handle}`,
198
- source: node.id,
199
- sourceHandle: handle,
200
- target: closestNode.node.id,
201
- targetHandle: 'target',
202
- };
198
+ if (!isSourceHandleFree(srcId, handle)) return null;
199
+ return buildEdge(srcId, handle, tgtId);
203
200
  }
204
- return {
205
- id: `${node.id}-${closestNode.node.id}`,
206
- source: node.id,
207
- sourceHandle: 'source',
208
- target: closestNode.node.id,
209
- targetHandle: 'target',
210
- };
201
+
202
+ if (!isSourceHandleFree(srcId, 'source')) return null;
203
+ return buildEdge(srcId, 'source', tgtId);
204
+ };
205
+
206
+ const draggedIsBelow = draggedPos.y > closestPos.y;
207
+ const closestId = closestNode.node.id;
208
+
209
+ if (draggedIsBelow) {
210
+ return (
211
+ trySourceToTarget(closestId, closestData, node.id, draggedData) ??
212
+ trySourceToTarget(node.id, draggedData, closestId, closestData)
213
+ );
211
214
  }
215
+ return (
216
+ trySourceToTarget(node.id, draggedData, closestId, closestData) ??
217
+ trySourceToTarget(closestId, closestData, node.id, draggedData)
218
+ );
212
219
  },
213
220
  [store]
214
221
  );
@@ -239,7 +246,10 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
239
246
  ne.source === closeEdge.source &&
240
247
  ne.sourceHandle === closeEdge.sourceHandle
241
248
  );
242
- if (!sourceHandleAlreadyUsed) {
249
+ const targetAlreadyHasInput = nextEdges.find(
250
+ (ne) => ne.target === closeEdge.target
251
+ );
252
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
243
253
  nextEdges.push({
244
254
  ...closeEdge,
245
255
  className: 'temp',
@@ -280,7 +290,10 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
280
290
  ne.source === closeEdge.source &&
281
291
  ne.sourceHandle === closeEdge.sourceHandle
282
292
  );
283
- if (!sourceHandleAlreadyUsed) {
293
+ const targetAlreadyHasInput = nextEdges.find(
294
+ (ne) => ne.target === closeEdge.target
295
+ );
296
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
284
297
  nextEdges.push({
285
298
  ...closeEdge,
286
299
  type: closeEdge.sourceHandle ? 'labeled' : 'default',
@@ -4109,7 +4109,7 @@ const FlowCanvas = ({
4109
4109
  );
4110
4110
  const getClosestEdge = useCallback(
4111
4111
  (node) => {
4112
- const { nodeInternals } = store.getState();
4112
+ const { nodeInternals, edges: currentEdges } = store.getState();
4113
4113
  const internalNode = nodeInternals.get(node.id);
4114
4114
  if (!internalNode) return null;
4115
4115
  const draggedPos = internalNode.positionAbsolute || internalNode.position;
@@ -4134,59 +4134,42 @@ const FlowCanvas = ({
4134
4134
  const closestPos = closestNode.node.positionAbsolute || closestNode.node.position;
4135
4135
  const closestData = closestNode.node.data;
4136
4136
  const draggedData = node.data;
4137
- const draggedIsBelow = draggedPos.y > closestPos.y;
4138
- if (draggedIsBelow) {
4139
- if (closestData.stepType === "exit") {
4140
- return null;
4141
- }
4142
- if (closestData.stepType === "branch") {
4143
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
4144
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
4145
- const isRight = draggedCenterX >= closestCenterX;
4146
- const handle = isRight ? "no" : "yes";
4147
- return {
4148
- id: `${closestNode.node.id}-${node.id}-${handle}`,
4149
- source: closestNode.node.id,
4150
- sourceHandle: handle,
4151
- target: node.id,
4152
- targetHandle: "target"
4153
- };
4154
- }
4137
+ const nonTempEdges = currentEdges.filter((e) => e.className !== "temp");
4138
+ const isSourceHandleFree = (sourceId, handle) => !nonTempEdges.some((e) => e.source === sourceId && e.sourceHandle === handle);
4139
+ const isTargetFree = (targetId) => !nonTempEdges.some((e) => e.target === targetId);
4140
+ const buildEdge = (sourceId, sourceHandle, targetId) => {
4141
+ const suffix = sourceHandle !== "source" ? `-${sourceHandle}` : "";
4155
4142
  return {
4156
- id: `${closestNode.node.id}-${node.id}`,
4157
- source: closestNode.node.id,
4158
- sourceHandle: "source",
4159
- target: node.id,
4143
+ id: `${sourceId}-${targetId}${suffix}`,
4144
+ source: sourceId,
4145
+ sourceHandle,
4146
+ target: targetId,
4160
4147
  targetHandle: "target"
4161
4148
  };
4162
- } else {
4163
- if (draggedData.stepType === "entry") {
4164
- return null;
4165
- }
4166
- if (closestData.stepType === "entry") {
4167
- return null;
4168
- }
4169
- if (draggedData.stepType === "branch") {
4170
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
4171
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
4172
- const isRight = closestCenterX >= draggedCenterX;
4149
+ };
4150
+ const trySourceToTarget = (srcId, srcData, tgtId, tgtData) => {
4151
+ if (srcData.stepType === "exit") return null;
4152
+ if (tgtData.stepType === "entry") return null;
4153
+ if (!isTargetFree(tgtId)) return null;
4154
+ if (srcData.stepType === "branch") {
4155
+ const srcPos = srcId === node.id ? draggedPos : closestPos;
4156
+ const tgtPos = srcId === node.id ? closestPos : draggedPos;
4157
+ const srcCenterX = srcPos.x + NODE_DIMENSIONS.width / 2;
4158
+ const tgtCenterX = tgtPos.x + NODE_DIMENSIONS.width / 2;
4159
+ const isRight = tgtCenterX >= srcCenterX;
4173
4160
  const handle = isRight ? "no" : "yes";
4174
- return {
4175
- id: `${node.id}-${closestNode.node.id}-${handle}`,
4176
- source: node.id,
4177
- sourceHandle: handle,
4178
- target: closestNode.node.id,
4179
- targetHandle: "target"
4180
- };
4161
+ if (!isSourceHandleFree(srcId, handle)) return null;
4162
+ return buildEdge(srcId, handle, tgtId);
4181
4163
  }
4182
- return {
4183
- id: `${node.id}-${closestNode.node.id}`,
4184
- source: node.id,
4185
- sourceHandle: "source",
4186
- target: closestNode.node.id,
4187
- targetHandle: "target"
4188
- };
4164
+ if (!isSourceHandleFree(srcId, "source")) return null;
4165
+ return buildEdge(srcId, "source", tgtId);
4166
+ };
4167
+ const draggedIsBelow = draggedPos.y > closestPos.y;
4168
+ const closestId = closestNode.node.id;
4169
+ if (draggedIsBelow) {
4170
+ return trySourceToTarget(closestId, closestData, node.id, draggedData) ?? trySourceToTarget(node.id, draggedData, closestId, closestData);
4189
4171
  }
4172
+ return trySourceToTarget(node.id, draggedData, closestId, closestData) ?? trySourceToTarget(closestId, closestData, node.id, draggedData);
4190
4173
  },
4191
4174
  [store]
4192
4175
  );
@@ -4202,7 +4185,10 @@ const FlowCanvas = ({
4202
4185
  const sourceHandleAlreadyUsed = nextEdges.find(
4203
4186
  (ne) => ne.source === closeEdge.source && ne.sourceHandle === closeEdge.sourceHandle
4204
4187
  );
4205
- if (!sourceHandleAlreadyUsed) {
4188
+ const targetAlreadyHasInput = nextEdges.find(
4189
+ (ne) => ne.target === closeEdge.target
4190
+ );
4191
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
4206
4192
  nextEdges.push({
4207
4193
  ...closeEdge,
4208
4194
  className: "temp",
@@ -4227,7 +4213,10 @@ const FlowCanvas = ({
4227
4213
  const sourceHandleAlreadyUsed = nextEdges.find(
4228
4214
  (ne) => ne.source === closeEdge.source && ne.sourceHandle === closeEdge.sourceHandle
4229
4215
  );
4230
- if (!sourceHandleAlreadyUsed) {
4216
+ const targetAlreadyHasInput = nextEdges.find(
4217
+ (ne) => ne.target === closeEdge.target
4218
+ );
4219
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
4231
4220
  nextEdges.push({
4232
4221
  ...closeEdge,
4233
4222
  type: closeEdge.sourceHandle ? "labeled" : "default"
@@ -4114,7 +4114,7 @@ const FlowCanvas = ({
4114
4114
  );
4115
4115
  const getClosestEdge = React.useCallback(
4116
4116
  (node) => {
4117
- const { nodeInternals } = store.getState();
4117
+ const { nodeInternals, edges: currentEdges } = store.getState();
4118
4118
  const internalNode = nodeInternals.get(node.id);
4119
4119
  if (!internalNode) return null;
4120
4120
  const draggedPos = internalNode.positionAbsolute || internalNode.position;
@@ -4139,59 +4139,42 @@ const FlowCanvas = ({
4139
4139
  const closestPos = closestNode.node.positionAbsolute || closestNode.node.position;
4140
4140
  const closestData = closestNode.node.data;
4141
4141
  const draggedData = node.data;
4142
- const draggedIsBelow = draggedPos.y > closestPos.y;
4143
- if (draggedIsBelow) {
4144
- if (closestData.stepType === "exit") {
4145
- return null;
4146
- }
4147
- if (closestData.stepType === "branch") {
4148
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
4149
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
4150
- const isRight = draggedCenterX >= closestCenterX;
4151
- const handle = isRight ? "no" : "yes";
4152
- return {
4153
- id: `${closestNode.node.id}-${node.id}-${handle}`,
4154
- source: closestNode.node.id,
4155
- sourceHandle: handle,
4156
- target: node.id,
4157
- targetHandle: "target"
4158
- };
4159
- }
4142
+ const nonTempEdges = currentEdges.filter((e) => e.className !== "temp");
4143
+ const isSourceHandleFree = (sourceId, handle) => !nonTempEdges.some((e) => e.source === sourceId && e.sourceHandle === handle);
4144
+ const isTargetFree = (targetId) => !nonTempEdges.some((e) => e.target === targetId);
4145
+ const buildEdge = (sourceId, sourceHandle, targetId) => {
4146
+ const suffix = sourceHandle !== "source" ? `-${sourceHandle}` : "";
4160
4147
  return {
4161
- id: `${closestNode.node.id}-${node.id}`,
4162
- source: closestNode.node.id,
4163
- sourceHandle: "source",
4164
- target: node.id,
4148
+ id: `${sourceId}-${targetId}${suffix}`,
4149
+ source: sourceId,
4150
+ sourceHandle,
4151
+ target: targetId,
4165
4152
  targetHandle: "target"
4166
4153
  };
4167
- } else {
4168
- if (draggedData.stepType === "entry") {
4169
- return null;
4170
- }
4171
- if (closestData.stepType === "entry") {
4172
- return null;
4173
- }
4174
- if (draggedData.stepType === "branch") {
4175
- const draggedCenterX = draggedPos.x + NODE_DIMENSIONS.width / 2;
4176
- const closestCenterX = closestPos.x + NODE_DIMENSIONS.width / 2;
4177
- const isRight = closestCenterX >= draggedCenterX;
4154
+ };
4155
+ const trySourceToTarget = (srcId, srcData, tgtId, tgtData) => {
4156
+ if (srcData.stepType === "exit") return null;
4157
+ if (tgtData.stepType === "entry") return null;
4158
+ if (!isTargetFree(tgtId)) return null;
4159
+ if (srcData.stepType === "branch") {
4160
+ const srcPos = srcId === node.id ? draggedPos : closestPos;
4161
+ const tgtPos = srcId === node.id ? closestPos : draggedPos;
4162
+ const srcCenterX = srcPos.x + NODE_DIMENSIONS.width / 2;
4163
+ const tgtCenterX = tgtPos.x + NODE_DIMENSIONS.width / 2;
4164
+ const isRight = tgtCenterX >= srcCenterX;
4178
4165
  const handle = isRight ? "no" : "yes";
4179
- return {
4180
- id: `${node.id}-${closestNode.node.id}-${handle}`,
4181
- source: node.id,
4182
- sourceHandle: handle,
4183
- target: closestNode.node.id,
4184
- targetHandle: "target"
4185
- };
4166
+ if (!isSourceHandleFree(srcId, handle)) return null;
4167
+ return buildEdge(srcId, handle, tgtId);
4186
4168
  }
4187
- return {
4188
- id: `${node.id}-${closestNode.node.id}`,
4189
- source: node.id,
4190
- sourceHandle: "source",
4191
- target: closestNode.node.id,
4192
- targetHandle: "target"
4193
- };
4169
+ if (!isSourceHandleFree(srcId, "source")) return null;
4170
+ return buildEdge(srcId, "source", tgtId);
4171
+ };
4172
+ const draggedIsBelow = draggedPos.y > closestPos.y;
4173
+ const closestId = closestNode.node.id;
4174
+ if (draggedIsBelow) {
4175
+ return trySourceToTarget(closestId, closestData, node.id, draggedData) ?? trySourceToTarget(node.id, draggedData, closestId, closestData);
4194
4176
  }
4177
+ return trySourceToTarget(node.id, draggedData, closestId, closestData) ?? trySourceToTarget(closestId, closestData, node.id, draggedData);
4195
4178
  },
4196
4179
  [store]
4197
4180
  );
@@ -4207,7 +4190,10 @@ const FlowCanvas = ({
4207
4190
  const sourceHandleAlreadyUsed = nextEdges.find(
4208
4191
  (ne) => ne.source === closeEdge.source && ne.sourceHandle === closeEdge.sourceHandle
4209
4192
  );
4210
- if (!sourceHandleAlreadyUsed) {
4193
+ const targetAlreadyHasInput = nextEdges.find(
4194
+ (ne) => ne.target === closeEdge.target
4195
+ );
4196
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
4211
4197
  nextEdges.push({
4212
4198
  ...closeEdge,
4213
4199
  className: "temp",
@@ -4232,7 +4218,10 @@ const FlowCanvas = ({
4232
4218
  const sourceHandleAlreadyUsed = nextEdges.find(
4233
4219
  (ne) => ne.source === closeEdge.source && ne.sourceHandle === closeEdge.sourceHandle
4234
4220
  );
4235
- if (!sourceHandleAlreadyUsed) {
4221
+ const targetAlreadyHasInput = nextEdges.find(
4222
+ (ne) => ne.target === closeEdge.target
4223
+ );
4224
+ if (!sourceHandleAlreadyUsed && !targetAlreadyHasInput) {
4236
4225
  nextEdges.push({
4237
4226
  ...closeEdge,
4238
4227
  type: closeEdge.sourceHandle ? "labeled" : "default"
@@ -131,7 +131,7 @@ const index = {
131
131
  components: {
132
132
  Input: async () => Promise.resolve().then(() => require(
133
133
  /* webpackChunkName: "crm-step-flow-builder" */
134
- "../_chunks/index-DThXHml5.js"
134
+ "../_chunks/index-DXq4OgEg.js"
135
135
  ))
136
136
  },
137
137
  options: {
@@ -130,7 +130,7 @@ const index = {
130
130
  components: {
131
131
  Input: async () => import(
132
132
  /* webpackChunkName: "crm-step-flow-builder" */
133
- "../_chunks/index-ruO-ALAX.mjs"
133
+ "../_chunks/index-DPbRPHfu.mjs"
134
134
  )
135
135
  },
136
136
  options: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inspirer-dev/crm-dashboard",
3
- "version": "1.0.71",
3
+ "version": "1.0.72",
4
4
  "description": "CRM Dashboard and Tools",
5
5
  "strapi": {
6
6
  "name": "crm-dashboard",