@foblex/flow 12.7.0 → 12.7.1

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
- <a href="https://flow.foblex.com">
3
- <img style="margin: auto" src="https://github.com/user-attachments/assets/0557914d-a43d-43c1-8346-760d3627da14" alt="Foblex Flow Logo"/>
2
+ <a href="https://flow.foblex.com/">
3
+ <img style="margin: auto" src="https://github.com/user-attachments/assets/ee1d39f6-0a89-4cb9-8dee-1652aba82e69" alt="Foblex Flow Logo"/>
4
4
  </a>
5
5
  </p>
6
6
 
@@ -15,40 +15,45 @@
15
15
 
16
16
  ## Welcome to Foblex Flow
17
17
 
18
- Foblex Flow is an [Angular](https://angular.dev/) library designed to simplify the creation and manipulation of
19
- dynamic flows. It provides components for flows, nodes, and connections, automating node
20
- manipulation and inter-node connections.
18
+ Foblex Flow is an [Angular](https://angular.dev/) library built to simplify the creation and management of dynamic, interactive flows.
19
+ Whether you're developing complex systems or lightweight visualizations, Foblex Flow provides a robust set of tools to help automate node manipulation and inter-node connections with ease. It's fully compatible with Angular 12+, Server-Side Rendering (SSR), and the Composition API.
21
20
 
22
21
  ### Examples
23
22
 
24
- - [Call Center](https://github.com/Foblex/f-flow-example) - A simple example of a call center flow.
23
+ Explore practical use cases to see Foblex Flow in action:
25
24
 
26
- - [Scheme Editor](https://github.com/Foblex/f-scheme-editor) - A more complex example of a scheme editor.
25
+ - [Call Center](https://github.com/Foblex/f-flow-example) - A streamlined flow example simulating a call flow.
26
+
27
+ - [Scheme Editor](https://github.com/Foblex/f-scheme-editor) - A more advanced example of a fully interactive scheme editor.
28
+
29
+ - [Visual Programming](https://flow.foblex.com/examples/f-visual-programming-flow/) - An example of a visual programming flow.
30
+
31
+ - [DB Management](https://flow.foblex.com/examples/f-db-management-flow/) - An example of a database management flow.
27
32
 
28
33
  ### Features
29
34
 
30
- 1. Node and Connection creation and manipulation.
31
- 2. Connection and Node events.
32
- 3. Reassigning Nodes and Connections.
33
- 4. Customizable Node and Connection templates.
34
- 5. Drag-and-drop support.
35
- 6. Zoom and pan support.
35
+ 1. **Node and Connection Creation:** Dynamically generate and manipulate nodes and their connections.
36
+ 2. **Event-Driven Architecture:** Built-in events for nodes and connections to allow seamless interaction handling.
37
+ 3. **Reassign Connections:** Easily reassign connections between nodes, allowing for flexible flow adjustments.
38
+ 4. **Custom Templates:** Fully customizable node and connection templates for tailored visual representation.
39
+ 5. **Drag-and-Drop:** Simplified drag-and-drop functionality for intuitive flow manipulation.
40
+ 6. **Zoom and Pan Support:** Explore large flows with smooth zooming and panning controls.
36
41
 
37
42
  ### Getting Started and Documentation
38
43
 
39
- Visit our [Documentation](https://flow.foblex.com/docs/get-started) to learn how to install and use the library in your Angular project.
44
+ For a comprehensive guide on how to install, configure, and use Foblex Flow in your Angular project, visit our [Documentation](https://flow.foblex.com/docs/get-started).
40
45
 
41
46
  ### Installation
42
47
 
43
- To add Foblex Flow to your project, run the following command:
48
+ To add Foblex Flow to your project, use the following npm command:
44
49
 
45
50
  ```bash
46
51
  npm install @foblex/flow
47
52
  ```
48
53
 
49
- ### Usage
54
+ ### Usage Example
50
55
 
51
- Example:
56
+ Here’s a simple example of how you can use Foblex Flow to create draggable nodes and connections:
52
57
 
53
58
  ```html
54
59
 
@@ -61,7 +66,7 @@ Example:
61
66
  </f-flow>
62
67
  ```
63
68
 
64
- ### Support and Community
69
+ ### Community and Support
65
70
 
66
71
  For questions, feedback, and support, visit the [Foblex Portal](https://flow.foblex.com) to connect with the community and the development team.
67
72
  You can also report [issues](https://github.com/Foblex/flow/issues) and request [features](https://github.com/Foblex/flow/discussions) on the [GitHub repository](https://github.com/Foblex/flow).
@@ -3605,7 +3605,7 @@
3605
3605
  FConnectionTextPathDirective.prototype.getSymbolWidth = function (name) {
3606
3606
  var text = name || 'connection';
3607
3607
  var _a = this.getFontStyles(this.hostElement), fontFamily = _a.fontFamily, fontSize = _a.fontSize;
3608
- this.fontSize = fontSize;
3608
+ this.fontSize = fontSize || '12px';
3609
3609
  var canvas = this.fBrowser.document.createElement('canvas');
3610
3610
  var context;
3611
3611
  try {
@@ -5049,11 +5049,22 @@
5049
5049
  };
5050
5050
  ConnectionBaseDragHandler.prototype.getOutput = function () {
5051
5051
  var _this = this;
5052
- return this.fComponentsStore.fOutputs.find(function (x) { return x.id === _this.connection.fOutputId; });
5052
+ var result = this.fComponentsStore.fOutputs.find(function (x) { return x.id === _this.connection.fOutputId; });
5053
+ if (!result) {
5054
+ throw new Error(this.connectorNotFoundPrefix("fOutput with id " + this.connection.fOutputId + " not found"));
5055
+ }
5056
+ return result;
5053
5057
  };
5054
5058
  ConnectionBaseDragHandler.prototype.getInput = function () {
5055
5059
  var _this = this;
5056
- return this.fComponentsStore.fInputs.find(function (x) { return x.id === _this.connection.fInputId; });
5060
+ var result = this.fComponentsStore.fInputs.find(function (x) { return x.id === _this.connection.fInputId; });
5061
+ if (!result) {
5062
+ throw new Error(this.connectorNotFoundPrefix("fInput with id " + this.connection.fInputId + " not found"));
5063
+ }
5064
+ return result;
5065
+ };
5066
+ ConnectionBaseDragHandler.prototype.connectorNotFoundPrefix = function (message) {
5067
+ return "ConnectionDragHandler Error: Connection From (fOutput)" + this.connection.fOutputId + " To (fInput)" + this.connection.fInputId + ". " + message + ". Please ensure that all f-connections are associated with existing connectors";
5057
5068
  };
5058
5069
  ConnectionBaseDragHandler.prototype.getDifference = function (difference, restrictions) {
5059
5070
  return {
@@ -5313,7 +5324,8 @@
5313
5324
  };
5314
5325
 
5315
5326
  var CreateMoveNodesDragModelFromSelectionRequest = /** @class */ (function () {
5316
- function CreateMoveNodesDragModelFromSelectionRequest() {
5327
+ function CreateMoveNodesDragModelFromSelectionRequest(nodeWithDisabledSelection) {
5328
+ this.nodeWithDisabledSelection = nodeWithDisabledSelection;
5317
5329
  }
5318
5330
  return CreateMoveNodesDragModelFromSelectionRequest;
5319
5331
  }());
@@ -5372,14 +5384,18 @@
5372
5384
  this.fMediator = fMediator;
5373
5385
  }
5374
5386
  CreateMoveNodesDragModelFromSelectionExecution.prototype.handle = function (request) {
5375
- var itemsToDrag = this.getNodesWithRestrictions(this.getSelectedNodes());
5387
+ var itemsToDrag = this.getNodesWithRestrictions(this.getSelectedNodes(request.nodeWithDisabledSelection));
5376
5388
  return this.getDragHandlersWithConnections(this.getDragHandlersFromNodes(itemsToDrag), this.getAllOutputIds(itemsToDrag), this.getAllInputIds(itemsToDrag));
5377
5389
  };
5378
- CreateMoveNodesDragModelFromSelectionExecution.prototype.getSelectedNodes = function () {
5390
+ CreateMoveNodesDragModelFromSelectionExecution.prototype.getSelectedNodes = function (nodeWithDisabledSelection) {
5379
5391
  var _this = this;
5380
- return this.fDraggableDataContext.selectedItems
5392
+ var result = this.fDraggableDataContext.selectedItems
5381
5393
  .map(function (x) { return _this.fComponentsStore.findNode(x.hostElement); })
5382
5394
  .filter(function (x) { return !!x; });
5395
+ if (nodeWithDisabledSelection) {
5396
+ result.push(nodeWithDisabledSelection);
5397
+ }
5398
+ return result;
5383
5399
  };
5384
5400
  CreateMoveNodesDragModelFromSelectionExecution.prototype.getNodesWithRestrictions = function (selectedNodes) {
5385
5401
  var _this = this;
@@ -5475,22 +5491,32 @@
5475
5491
  configurable: true
5476
5492
  });
5477
5493
  NodeMovePreparationExecution.prototype.handle = function (request) {
5478
- this.selectAndUpdateNodeLayer(request.event.targetElement);
5479
- var itemsToDrag = this.createDragModelFromSelection();
5494
+ var node = this.getNode(request.event.targetElement);
5495
+ if (!node) {
5496
+ throw new Error('Node not found');
5497
+ }
5498
+ var itemsToDrag = [];
5499
+ if (!node.fSelectionDisabled) {
5500
+ this.selectAndUpdateNodeLayer(node);
5501
+ itemsToDrag = this.createDragModelFromSelection();
5502
+ }
5503
+ else {
5504
+ itemsToDrag = this.createDragModelFromSelection(node);
5505
+ }
5480
5506
  this.initializeLineAlignment(this.filterNodesFromDraggableItems(itemsToDrag));
5481
5507
  this.fDraggableDataContext.onPointerDownScale = this.transform.scale;
5482
5508
  this.fDraggableDataContext.onPointerDownPosition = _2d.Point.fromPoint(request.event.getPosition())
5483
5509
  .elementTransform(this.flowHost).div(this.transform.scale);
5484
5510
  this.fDraggableDataContext.draggableItems = itemsToDrag;
5485
5511
  };
5486
- NodeMovePreparationExecution.prototype.selectAndUpdateNodeLayer = function (targetElement) {
5487
- this.fMediator.send(new SelectAndUpdateNodeLayerRequest(this.getNode(targetElement)));
5512
+ NodeMovePreparationExecution.prototype.selectAndUpdateNodeLayer = function (node) {
5513
+ this.fMediator.send(new SelectAndUpdateNodeLayerRequest(node));
5488
5514
  };
5489
5515
  NodeMovePreparationExecution.prototype.getNode = function (targetElement) {
5490
5516
  return this.fComponentsStore.findNode(targetElement);
5491
5517
  };
5492
- NodeMovePreparationExecution.prototype.createDragModelFromSelection = function () {
5493
- return this.fMediator.send(new CreateMoveNodesDragModelFromSelectionRequest());
5518
+ NodeMovePreparationExecution.prototype.createDragModelFromSelection = function (nodeWithDisabledSelection) {
5519
+ return this.fMediator.send(new CreateMoveNodesDragModelFromSelectionRequest(nodeWithDisabledSelection));
5494
5520
  };
5495
5521
  NodeMovePreparationExecution.prototype.initializeLineAlignment = function (nodesToDrag) {
5496
5522
  var _a;
@@ -6134,6 +6160,9 @@
6134
6160
  this.clearSelection();
6135
6161
  this.selectItem(item);
6136
6162
  }
6163
+ else if (item.fSelectionDisabled) {
6164
+ this.clearSelection();
6165
+ }
6137
6166
  }
6138
6167
  else {
6139
6168
  this.clearSelection();
@@ -9456,9 +9485,44 @@
9456
9485
  var F_ZOOM = new i0.InjectionToken('F_ZOOM');
9457
9486
  var FZoomBase = /** @class */ (function () {
9458
9487
  function FZoomBase(fComponentsStore) {
9488
+ var _this = this;
9459
9489
  this.fComponentsStore = fComponentsStore;
9460
9490
  this.isEnabled = false;
9461
9491
  this.listeners = dragToolkit.EventExtensions.emptyListener();
9492
+ this.onWheel = function (event) {
9493
+ var _a;
9494
+ event.preventDefault();
9495
+ var targetElement = event.target;
9496
+ if (((_a = _this.fComponentsStore.fDraggable) === null || _a === void 0 ? void 0 : _a.isDragStarted) || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.closest('[fLockedContext]'))) {
9497
+ return;
9498
+ }
9499
+ var result = _this.getScale();
9500
+ var direction = event.deltaY > 0 ? -1 : 1;
9501
+ var step = _this.step;
9502
+ result = result + step * direction;
9503
+ result = Math.max(_this.minimum, Math.min(result, _this.maximum));
9504
+ var pointerPositionInFlow = new _2d.Point(event.clientX, event.clientY).elementTransform(_this.flowHost);
9505
+ _this.fCanvas.setZoom(result, pointerPositionInFlow);
9506
+ _this.fCanvas.redraw();
9507
+ _this.fCanvas.emitCanvasChangeEvent();
9508
+ };
9509
+ this.onDoubleClick = function (event) {
9510
+ var _a;
9511
+ event.preventDefault();
9512
+ var targetElement = event.target;
9513
+ if (((_a = _this.fComponentsStore.fDraggable) === null || _a === void 0 ? void 0 : _a.isDragStarted) || isNode(targetElement) || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.closest('[fLockedContext]'))) {
9514
+ return;
9515
+ }
9516
+ var result = _this.getScale();
9517
+ var direction = 1;
9518
+ var step = _this.dblClickStep;
9519
+ result = result + step * direction;
9520
+ result = Math.max(_this.minimum, Math.min(result, _this.maximum));
9521
+ var pointerPositionInFlow = new _2d.Point(event.clientX, event.clientY).elementTransform(_this.flowHost);
9522
+ _this.fCanvas.setZoom(result, pointerPositionInFlow);
9523
+ _this.fCanvas.redrawWithAnimation();
9524
+ _this.fCanvas.emitCanvasChangeEvent();
9525
+ };
9462
9526
  }
9463
9527
  Object.defineProperty(FZoomBase.prototype, "flowHost", {
9464
9528
  get: function () {
@@ -9488,50 +9552,16 @@
9488
9552
  if (!this.flowHost) {
9489
9553
  return;
9490
9554
  }
9491
- this.flowHost.addEventListener('wheel', this.onWheel.bind(this));
9492
- this.flowHost.addEventListener('dblclick', this.onDoubleClick.bind(this));
9555
+ this.flowHost.addEventListener('wheel', this.onWheel);
9556
+ this.flowHost.addEventListener('dblclick', this.onDoubleClick);
9493
9557
  this.listeners = function () {
9494
- _this.flowHost.removeEventListener('wheel', _this.onWheel.bind(_this));
9495
- _this.flowHost.removeEventListener('dblclick', _this.onDoubleClick.bind(_this));
9558
+ _this.flowHost.removeEventListener('wheel', _this.onWheel);
9559
+ _this.flowHost.removeEventListener('dblclick', _this.onDoubleClick);
9496
9560
  };
9497
9561
  };
9498
9562
  FZoomBase.prototype.getScale = function () {
9499
9563
  return this.fCanvas.transform.scale || 1;
9500
9564
  };
9501
- FZoomBase.prototype.onWheel = function (event) {
9502
- var _a;
9503
- event.preventDefault();
9504
- var targetElement = event.target;
9505
- if (((_a = this.fComponentsStore.fDraggable) === null || _a === void 0 ? void 0 : _a.isDragStarted) || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.closest('[fLockedContext]'))) {
9506
- return;
9507
- }
9508
- var result = this.getScale();
9509
- var direction = event.deltaY > 0 ? -1 : 1;
9510
- var step = this.step;
9511
- result = result + step * direction;
9512
- result = Math.max(this.minimum, Math.min(result, this.maximum));
9513
- var pointerPositionInFlow = new _2d.Point(event.clientX, event.clientY).elementTransform(this.flowHost);
9514
- this.fCanvas.setZoom(result, pointerPositionInFlow);
9515
- this.fCanvas.redraw();
9516
- this.fCanvas.emitCanvasChangeEvent();
9517
- };
9518
- FZoomBase.prototype.onDoubleClick = function (event) {
9519
- var _a;
9520
- event.preventDefault();
9521
- var targetElement = event.target;
9522
- if (((_a = this.fComponentsStore.fDraggable) === null || _a === void 0 ? void 0 : _a.isDragStarted) || isNode(targetElement) || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.closest('[fLockedContext]'))) {
9523
- return;
9524
- }
9525
- var result = this.getScale();
9526
- var direction = 1;
9527
- var step = this.dblClickStep;
9528
- result = result + step * direction;
9529
- result = Math.max(this.minimum, Math.min(result, this.maximum));
9530
- var pointerPositionInFlow = new _2d.Point(event.clientX, event.clientY).elementTransform(this.flowHost);
9531
- this.fCanvas.setZoom(result, pointerPositionInFlow);
9532
- this.fCanvas.redrawWithAnimation();
9533
- this.fCanvas.emitCanvasChangeEvent();
9534
- };
9535
9565
  FZoomBase.prototype.onZoomToCenter = function (deltaY, position) {
9536
9566
  var preventDefault = function () {
9537
9567
  };