@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 +23 -18
- package/bundles/foblex-flow.umd.js +81 -51
- package/bundles/foblex-flow.umd.js.map +1 -1
- package/esm2015/f-connection/common/f-connection-text/f-connection-text-path.directive.js +2 -2
- package/esm2015/f-draggable/node/connection-base-drag-handler.js +14 -3
- package/esm2015/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.execution.js +8 -4
- package/esm2015/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.request.js +4 -1
- package/esm2015/f-draggable/node/node-move-preparation/node-move-preparation.execution.js +17 -7
- package/esm2015/f-draggable/single-select/single-select.execution.js +4 -1
- package/esm2015/f-zoom/f-zoom-base.js +39 -39
- package/f-draggable/node/connection-base-drag-handler.d.ts +1 -0
- package/f-draggable/node/create-move-nodes-drag-model-from-selection/create-move-nodes-drag-model-from-selection.request.d.ts +3 -0
- package/fesm2015/foblex-flow.js +81 -50
- package/fesm2015/foblex-flow.js.map +1 -1
- package/package.json +1 -1
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/
|
|
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
|
|
19
|
-
|
|
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
|
-
|
|
23
|
+
Explore practical use cases to see Foblex Flow in action:
|
|
25
24
|
|
|
26
|
-
- [
|
|
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
|
|
31
|
-
2.
|
|
32
|
-
3.
|
|
33
|
-
4.
|
|
34
|
-
5. Drag-and-drop
|
|
35
|
-
6. Zoom and
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
5479
|
-
|
|
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 (
|
|
5487
|
-
this.fMediator.send(new SelectAndUpdateNodeLayerRequest(
|
|
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
|
|
9492
|
-
this.flowHost.addEventListener('dblclick', this.onDoubleClick
|
|
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
|
|
9495
|
-
_this.flowHost.removeEventListener('dblclick', _this.onDoubleClick
|
|
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
|
};
|