ngx-vflow 1.15.0 → 1.16.0

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.
@@ -554,10 +554,58 @@ function align(num, constant) {
554
554
  return Math.ceil(num / constant) * constant;
555
555
  }
556
556
 
557
+ class FlowStatusService {
558
+ constructor() {
559
+ this.status = signal({ state: 'idle', payload: null });
560
+ }
561
+ setIdleStatus() {
562
+ this.status.set({ state: 'idle', payload: null });
563
+ }
564
+ setConnectionStartStatus(source, sourceHandle) {
565
+ this.status.set({ state: 'connection-start', payload: { source, sourceHandle } });
566
+ }
567
+ setReconnectionStartStatus(source, sourceHandle, oldEdge) {
568
+ this.status.set({ state: 'reconnection-start', payload: { source, sourceHandle, oldEdge } });
569
+ }
570
+ setConnectionValidationStatus(valid, source, target, sourceHandle, targetHandle) {
571
+ this.status.set({ state: 'connection-validation', payload: { source, target, sourceHandle, targetHandle, valid } });
572
+ }
573
+ setReconnectionValidationStatus(valid, source, target, sourceHandle, targetHandle, oldEdge) {
574
+ this.status.set({
575
+ state: 'reconnection-validation',
576
+ payload: { source, target, sourceHandle, targetHandle, valid, oldEdge },
577
+ });
578
+ }
579
+ setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
580
+ this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
581
+ }
582
+ setReconnectionEndStatus(source, target, sourceHandle, targetHandle, oldEdge) {
583
+ this.status.set({ state: 'reconnection-end', payload: { source, target, sourceHandle, targetHandle, oldEdge } });
584
+ }
585
+ setNodeDragStartStatus(node) {
586
+ this.status.set({ state: 'node-drag-start', payload: { node } });
587
+ }
588
+ setNodeDragEndStatus(node) {
589
+ this.status.set({ state: 'node-drag-end', payload: { node } });
590
+ }
591
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
592
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
593
+ }
594
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, decorators: [{
595
+ type: Injectable
596
+ }] });
597
+ function isNodeDragStartStatus(params) {
598
+ return params.state === 'node-drag-start';
599
+ }
600
+ function isNodeDragEndStatus(params) {
601
+ return params.state === 'node-drag-end';
602
+ }
603
+
557
604
  class DraggableService {
558
605
  constructor() {
559
606
  this.entitiesService = inject(FlowEntitiesService);
560
607
  this.settingsService = inject(FlowSettingsService);
608
+ this.flowStatusService = inject(FlowStatusService);
561
609
  }
562
610
  /**
563
611
  * Enable draggable behavior for element.
@@ -605,6 +653,7 @@ class DraggableService {
605
653
  .filter(filterCondition)
606
654
  .on('start', (event) => {
607
655
  dragNodes = this.getDragNodes(model);
656
+ this.flowStatusService.setNodeDragStartStatus(model);
608
657
  initialPositions = dragNodes.map((node) => ({
609
658
  x: node.point().x - event.x,
610
659
  y: node.point().y - event.y,
@@ -618,6 +667,9 @@ class DraggableService {
618
667
  };
619
668
  this.moveNode(model, point);
620
669
  });
670
+ })
671
+ .on('end', () => {
672
+ this.flowStatusService.setNodeDragEndStatus(model);
621
673
  });
622
674
  }
623
675
  getDragNodes(model) {
@@ -792,41 +844,6 @@ function addNodesToEdges(nodes, edges) {
792
844
  });
793
845
  }
794
846
 
795
- class FlowStatusService {
796
- constructor() {
797
- this.status = signal({ state: 'idle', payload: null });
798
- }
799
- setIdleStatus() {
800
- this.status.set({ state: 'idle', payload: null });
801
- }
802
- setConnectionStartStatus(source, sourceHandle) {
803
- this.status.set({ state: 'connection-start', payload: { source, sourceHandle } });
804
- }
805
- setReconnectionStartStatus(source, sourceHandle, oldEdge) {
806
- this.status.set({ state: 'reconnection-start', payload: { source, sourceHandle, oldEdge } });
807
- }
808
- setConnectionValidationStatus(valid, source, target, sourceHandle, targetHandle) {
809
- this.status.set({ state: 'connection-validation', payload: { source, target, sourceHandle, targetHandle, valid } });
810
- }
811
- setReconnectionValidationStatus(valid, source, target, sourceHandle, targetHandle, oldEdge) {
812
- this.status.set({
813
- state: 'reconnection-validation',
814
- payload: { source, target, sourceHandle, targetHandle, valid, oldEdge },
815
- });
816
- }
817
- setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
818
- this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
819
- }
820
- setReconnectionEndStatus(source, target, sourceHandle, targetHandle, oldEdge) {
821
- this.status.set({ state: 'reconnection-end', payload: { source, target, sourceHandle, targetHandle, oldEdge } });
822
- }
823
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
824
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
825
- }
826
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, decorators: [{
827
- type: Injectable
828
- }] });
829
-
830
847
  function isCallable(fn) {
831
848
  try {
832
849
  new Proxy(fn, { apply: () => undefined })();
@@ -3863,6 +3880,109 @@ function skipFrames(count) {
3863
3880
  });
3864
3881
  }
3865
3882
 
3883
+ function rectToRectWithSides(rect) {
3884
+ return {
3885
+ ...rect,
3886
+ left: rect.x,
3887
+ right: rect.x + rect.width,
3888
+ top: rect.y,
3889
+ bottom: rect.y + rect.height,
3890
+ };
3891
+ }
3892
+
3893
+ class AlignmentHelperComponent {
3894
+ constructor() {
3895
+ this.nodeRenderingService = inject(NodeRenderingService);
3896
+ this.flowStatus = inject(FlowStatusService);
3897
+ this.tolerance = input(10);
3898
+ this.lineColor = input('#1b262c');
3899
+ this.isNodeDragging = computed(() => isNodeDragStartStatus(this.flowStatus.status()));
3900
+ this.intersections = extendedComputed((lastValue) => {
3901
+ const status = this.flowStatus.status();
3902
+ if (isNodeDragStartStatus(status)) {
3903
+ const node = status.payload.node;
3904
+ const d = rectToRectWithSides(nodeToRect(node));
3905
+ const otherRects = this.nodeRenderingService
3906
+ .viewportNodes()
3907
+ .filter((n) => n !== node)
3908
+ // do not check children of the dragged node
3909
+ .filter((n) => !node.children().includes(n))
3910
+ .map((n) => rectToRectWithSides(nodeToRect(n)));
3911
+ const lines = [];
3912
+ let snappedX = d.x;
3913
+ let snappedY = d.y;
3914
+ let closestXDiff = Infinity;
3915
+ let closestYDiff = Infinity;
3916
+ otherRects.forEach((o) => {
3917
+ const dCenterX = d.left + d.width / 2;
3918
+ const oCenterX = o.left + o.width / 2;
3919
+ for (const [dX, oX, snapX, isCenter] of [
3920
+ // center check
3921
+ [dCenterX, oCenterX, oCenterX - d.width / 2, true],
3922
+ [d.left, o.left, o.left, false],
3923
+ [d.left, o.right, o.right, false],
3924
+ [d.right, o.left, o.left - d.width, false],
3925
+ [d.right, o.right, o.right - d.width, false],
3926
+ ]) {
3927
+ const diff = Math.abs(dX - oX);
3928
+ if (diff <= this.tolerance()) {
3929
+ const y = Math.min(d.top, o.top);
3930
+ const y2 = Math.max(d.bottom, o.bottom);
3931
+ lines.push({ x: oX, y, x2: oX, y2, isCenter });
3932
+ if (diff < closestXDiff) {
3933
+ closestXDiff = diff;
3934
+ snappedX = snapX;
3935
+ }
3936
+ if (isCenter)
3937
+ break;
3938
+ }
3939
+ }
3940
+ const dCenterY = d.top + d.height / 2;
3941
+ const oCenterY = o.top + o.height / 2;
3942
+ for (const [dY, oY, snapY, isCenter] of [
3943
+ // center check
3944
+ [dCenterY, oCenterY, oCenterY - d.height / 2, true],
3945
+ [d.top, o.top, o.top, false],
3946
+ [d.top, o.bottom, o.bottom, false],
3947
+ [d.bottom, o.top, o.top - d.height, false],
3948
+ [d.bottom, o.bottom, o.bottom - d.height, false],
3949
+ ]) {
3950
+ const diff = Math.abs(dY - oY);
3951
+ if (diff <= this.tolerance()) {
3952
+ const x = Math.min(d.left, o.left);
3953
+ const x2 = Math.max(d.right, o.right);
3954
+ lines.push({ x, y: oY, x2, y2: oY, isCenter });
3955
+ if (diff < closestYDiff) {
3956
+ closestYDiff = diff;
3957
+ snappedY = snapY;
3958
+ }
3959
+ if (isCenter)
3960
+ break;
3961
+ }
3962
+ }
3963
+ });
3964
+ return { lines, snappedX, snappedY };
3965
+ }
3966
+ return lastValue;
3967
+ });
3968
+ toObservable(this.flowStatus.status)
3969
+ .pipe(filter(isNodeDragEndStatus), map((status) => status.payload.node), map((node) => [node, this.intersections()]), tap(([node, intersections]) => {
3970
+ if (intersections) {
3971
+ const snapped = { x: intersections.snappedX, y: intersections.snappedY };
3972
+ const parentIfExists = node.parent() ? [node.parent()] : [];
3973
+ node.setPoint(getSpacePoints(snapped, parentIfExists)[0]);
3974
+ }
3975
+ }), takeUntilDestroyed())
3976
+ .subscribe();
3977
+ }
3978
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AlignmentHelperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3979
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AlignmentHelperComponent, isStandalone: true, selector: "g[alignmentHelper]", inputs: { tolerance: { classPropertyName: "tolerance", publicName: "tolerance", isSignal: true, isRequired: false, transformFunction: null }, lineColor: { classPropertyName: "lineColor", publicName: "lineColor", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (isNodeDragging()) {\n @if (intersections(); as intersections) {\n @for (intersection of intersections.lines; track $index) {\n <svg:line\n [attr.stroke]=\"lineColor()\"\n [attr.stroke-dasharray]=\"intersection.isCenter ? 4 : null\"\n [attr.x1]=\"intersection.x\"\n [attr.y1]=\"intersection.y\"\n [attr.x2]=\"intersection.x2\"\n [attr.y2]=\"intersection.y2\" />\n }\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3980
+ }
3981
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AlignmentHelperComponent, decorators: [{
3982
+ type: Component,
3983
+ args: [{ selector: 'g[alignmentHelper]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "@if (isNodeDragging()) {\n @if (intersections(); as intersections) {\n @for (intersection of intersections.lines; track $index) {\n <svg:line\n [attr.stroke]=\"lineColor()\"\n [attr.stroke-dasharray]=\"intersection.isCenter ? 4 : null\"\n [attr.x1]=\"intersection.x\"\n [attr.y1]=\"intersection.y\"\n [attr.x2]=\"intersection.x2\"\n [attr.y2]=\"intersection.y2\" />\n }\n }\n}\n" }]
3984
+ }], ctorParameters: () => [] });
3985
+
3866
3986
  const changesControllerHostDirective = {
3867
3987
  directive: ChangesControllerDirective,
3868
3988
  outputs: [
@@ -3911,6 +4031,7 @@ class VflowComponent {
3911
4031
  this.keyboardService = inject(KeyboardService);
3912
4032
  this.injector = inject(Injector);
3913
4033
  this.flowRenderingService = inject(FlowRenderingService);
4034
+ this.alignmentHelper = input(false);
3914
4035
  this.nodeModels = this.nodeRenderingService.nodes;
3915
4036
  this.groups = this.nodeRenderingService.groups;
3916
4037
  this.nonGroups = this.nodeRenderingService.nonGroups;
@@ -4172,7 +4293,7 @@ class VflowComponent {
4172
4293
  return edge;
4173
4294
  }
4174
4295
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4175
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowComponent, isStandalone: true, selector: "vflow", inputs: { view: "view", minZoom: "minZoom", maxZoom: "maxZoom", background: "background", optimization: "optimization", entitiesSelectable: "entitiesSelectable", keyboardShortcuts: "keyboardShortcuts", connection: ["connection", "connection", (settings) => new ConnectionModel(settings)], snapGrid: "snapGrid", elevateNodesOnSelect: "elevateNodesOnSelect", elevateEdgesOnSelect: "elevateEdgesOnSelect", nodes: "nodes", edges: "edges" }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
4296
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowComponent, isStandalone: true, selector: "vflow", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: false, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: false, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: false, isRequired: false, transformFunction: null }, optimization: { classPropertyName: "optimization", publicName: "optimization", isSignal: false, isRequired: false, transformFunction: null }, entitiesSelectable: { classPropertyName: "entitiesSelectable", publicName: "entitiesSelectable", isSignal: false, isRequired: false, transformFunction: null }, keyboardShortcuts: { classPropertyName: "keyboardShortcuts", publicName: "keyboardShortcuts", isSignal: false, isRequired: false, transformFunction: null }, connection: { classPropertyName: "connection", publicName: "connection", isSignal: false, isRequired: false, transformFunction: (settings) => new ConnectionModel(settings) }, snapGrid: { classPropertyName: "snapGrid", publicName: "snapGrid", isSignal: false, isRequired: false, transformFunction: null }, elevateNodesOnSelect: { classPropertyName: "elevateNodesOnSelect", publicName: "elevateNodesOnSelect", isSignal: false, isRequired: false, transformFunction: null }, elevateEdgesOnSelect: { classPropertyName: "elevateEdgesOnSelect", publicName: "elevateEdgesOnSelect", isSignal: false, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, alignmentHelper: { classPropertyName: "alignmentHelper", publicName: "alignmentHelper", isSignal: true, isRequired: false, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
4176
4297
  DraggableService,
4177
4298
  ViewportService,
4178
4299
  FlowStatusService,
@@ -4188,7 +4309,7 @@ class VflowComponent {
4188
4309
  OverlaysService,
4189
4310
  { provide: PreviewFlowRenderStrategyService, useClass: ViewportPreviewFlowRenderStrategyService },
4190
4311
  FlowRenderingService,
4191
- ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "nodeSvgTemplateDirective", first: true, predicate: NodeSvgTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (flowOptimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!flowOptimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n\n@if (flowOptimization().virtualization) {\n <canvas previewFlow class=\"preview-flow\" [width]=\"flowWidth()\" [height]=\"flowHeight()\"></canvas>\n}\n", styles: [":host{display:grid;grid-template-columns:1fr;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}.root-svg{grid-row-start:1;grid-column-start:1}.preview-flow{pointer-events:none;grid-row-start:1;grid-column-start:1}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["model", "nodeTemplate", "nodeSvgTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PreviewFlowComponent, selector: "canvas[previewFlow]", inputs: ["width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4312
+ ], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "nodeSvgTemplateDirective", first: true, predicate: NodeSvgTemplateDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true, isSignal: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: ChangesControllerDirective, outputs: ["onNodesChange", "onNodesChange", "onNodesChange.position", "onNodesChange.position", "onNodesChange.position.single", "onNodesChange.position.single", "onNodesChange.position.many", "onNodesChange.position.many", "onNodesChange.size", "onNodesChange.size", "onNodesChange.size.single", "onNodesChange.size.single", "onNodesChange.size.many", "onNodesChange.size.many", "onNodesChange.add", "onNodesChange.add", "onNodesChange.add.single", "onNodesChange.add.single", "onNodesChange.add.many", "onNodesChange.add.many", "onNodesChange.remove", "onNodesChange.remove", "onNodesChange.remove.single", "onNodesChange.remove.single", "onNodesChange.remove.many", "onNodesChange.remove.many", "onNodesChange.select", "onNodesChange.select", "onNodesChange.select.single", "onNodesChange.select.single", "onNodesChange.select.many", "onNodesChange.select.many", "onEdgesChange", "onEdgesChange", "onEdgesChange.detached", "onEdgesChange.detached", "onEdgesChange.detached.single", "onEdgesChange.detached.single", "onEdgesChange.detached.many", "onEdgesChange.detached.many", "onEdgesChange.add", "onEdgesChange.add", "onEdgesChange.add.single", "onEdgesChange.add.single", "onEdgesChange.add.many", "onEdgesChange.add.many", "onEdgesChange.remove", "onEdgesChange.remove", "onEdgesChange.remove.single", "onEdgesChange.remove.single", "onEdgesChange.remove.many", "onEdgesChange.remove.many", "onEdgesChange.select", "onEdgesChange.select", "onEdgesChange.select.single", "onEdgesChange.select.single", "onEdgesChange.select.many", "onEdgesChange.select.many"] }], ngImport: i0, template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n @if (alignmentHelper(); as alignmentHelper) {\n @if (alignmentHelper === true) {\n <svg:g alignmentHelper />\n } @else {\n <svg:g alignmentHelper [tolerance]=\"alignmentHelper.tolerance\" [lineColor]=\"alignmentHelper.lineColor\" />\n }\n }\n\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (flowOptimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!flowOptimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n\n@if (flowOptimization().virtualization) {\n <canvas previewFlow class=\"preview-flow\" [width]=\"flowWidth()\" [height]=\"flowHeight()\"></canvas>\n}\n", styles: [":host{display:grid;grid-template-columns:1fr;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}.root-svg{grid-row-start:1;grid-column-start:1}.preview-flow{pointer-events:none;grid-row-start:1;grid-column-start:1}\n"], dependencies: [{ kind: "directive", type: RootSvgReferenceDirective, selector: "svg[rootSvgRef]" }, { kind: "directive", type: RootSvgContextDirective, selector: "svg[rootSvgContext]" }, { kind: "directive", type: RootPointerDirective, selector: "svg[rootPointer]" }, { kind: "directive", type: FlowSizeControllerDirective, selector: "svg[flowSizeController]" }, { kind: "component", type: DefsComponent, selector: "defs[flowDefs]", inputs: ["markers"] }, { kind: "component", type: BackgroundComponent, selector: "g[background]" }, { kind: "directive", type: MapContextDirective, selector: "g[mapContext]" }, { kind: "directive", type: SpacePointContextDirective, selector: "g[spacePointContext]" }, { kind: "component", type: ConnectionComponent, selector: "g[connection]", inputs: ["model", "template"] }, { kind: "component", type: NodeComponent, selector: "g[node]", inputs: ["model", "nodeTemplate", "nodeSvgTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PreviewFlowComponent, selector: "canvas[previewFlow]", inputs: ["width", "height"] }, { kind: "component", type: AlignmentHelperComponent, selector: "g[alignmentHelper]", inputs: ["tolerance", "lineColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4192
4313
  }
4193
4314
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
4194
4315
  type: Component,
@@ -4222,7 +4343,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
4222
4343
  EdgeComponent,
4223
4344
  NgTemplateOutlet,
4224
4345
  PreviewFlowComponent,
4225
- ], template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (flowOptimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!flowOptimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n\n@if (flowOptimization().virtualization) {\n <canvas previewFlow class=\"preview-flow\" [width]=\"flowWidth()\" [height]=\"flowHeight()\"></canvas>\n}\n", styles: [":host{display:grid;grid-template-columns:1fr;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}.root-svg{grid-row-start:1;grid-column-start:1}.preview-flow{pointer-events:none;grid-row-start:1;grid-column-start:1}\n"] }]
4346
+ AlignmentHelperComponent,
4347
+ ], template: "<svg:svg #flow rootSvgRef rootSvgContext rootPointer flowSizeController class=\"root-svg\">\n <defs flowDefs [markers]=\"markers()\" />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n @if (alignmentHelper(); as alignmentHelper) {\n @if (alignmentHelper === true) {\n <svg:g alignmentHelper />\n } @else {\n <svg:g alignmentHelper [tolerance]=\"alignmentHelper.tolerance\" [lineColor]=\"alignmentHelper.lineColor\" />\n }\n }\n\n <!-- Connection -->\n <svg:g connection [model]=\"connection\" [template]=\"connectionTemplateDirective()?.templateRef\" />\n\n @if (flowOptimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n\n @if (!flowOptimization().detachedGroupsLayer) {\n <!-- Edges -->\n @for (model of edgeModels(); track trackEdges($index, model)) {\n <svg:g\n edge\n [model]=\"model\"\n [edgeTemplate]=\"edgeTemplateDirective()?.templateRef\"\n [edgeLabelHtmlTemplate]=\"edgeLabelHtmlDirective()?.templateRef\" />\n }\n\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [model]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [nodeSvgTemplate]=\"nodeSvgTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\" />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n\n@if (flowOptimization().virtualization) {\n <canvas previewFlow class=\"preview-flow\" [width]=\"flowWidth()\" [height]=\"flowHeight()\"></canvas>\n}\n", styles: [":host{display:grid;grid-template-columns:1fr;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}.root-svg{grid-row-start:1;grid-column-start:1}.preview-flow{pointer-events:none;grid-row-start:1;grid-column-start:1}\n"] }]
4226
4348
  }], propDecorators: { view: [{
4227
4349
  type: Input
4228
4350
  }], minZoom: [{