ngx-vflow 1.14.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.
- package/esm2022/lib/vflow/components/alignment-helper/alignment-helper.component.mjs +103 -0
- package/esm2022/lib/vflow/components/node/node.component.mjs +5 -4
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +8 -5
- package/esm2022/lib/vflow/interfaces/alignment-helper-settings.interface.mjs +2 -0
- package/esm2022/lib/vflow/interfaces/flow-entity.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/node.interface.mjs +13 -5
- package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +2 -1
- package/esm2022/lib/vflow/interfaces/rect.mjs +10 -2
- package/esm2022/lib/vflow/interfaces/template-context.interface.mjs +1 -1
- package/esm2022/lib/vflow/models/edge.model.mjs +4 -9
- package/esm2022/lib/vflow/models/node.model.mjs +51 -7
- package/esm2022/lib/vflow/services/draggable.service.mjs +7 -1
- package/esm2022/lib/vflow/services/edge-rendering.service.mjs +1 -1
- package/esm2022/lib/vflow/services/flow-rendering.service.mjs +9 -1
- package/esm2022/lib/vflow/services/flow-status.service.mjs +13 -1
- package/esm2022/lib/vflow/utils/is-callable.mjs +10 -0
- package/esm2022/lib/vflow/utils/is-vflow-component.mjs +9 -0
- package/esm2022/public-api.mjs +3 -1
- package/esm2022/testing/component-mocks/vflow-mock.component.mjs +4 -3
- package/esm2022/testing/provide-custom-node-mocks.mjs +3 -2
- package/fesm2022/ngx-vflow-testing.mjs +5 -3
- package/fesm2022/ngx-vflow-testing.mjs.map +1 -1
- package/fesm2022/ngx-vflow.mjs +387 -201
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/alignment-helper/alignment-helper.component.d.ts +21 -0
- package/lib/vflow/components/vflow/vflow.component.d.ts +3 -1
- package/lib/vflow/interfaces/alignment-helper-settings.interface.d.ts +4 -0
- package/lib/vflow/interfaces/flow-entity.interface.d.ts +2 -1
- package/lib/vflow/interfaces/node.interface.d.ts +2 -2
- package/lib/vflow/interfaces/optimization.interface.d.ts +4 -0
- package/lib/vflow/interfaces/rect.d.ts +7 -0
- package/lib/vflow/interfaces/template-context.interface.d.ts +4 -0
- package/lib/vflow/models/edge.model.d.ts +2 -0
- package/lib/vflow/models/node.model.d.ts +4 -0
- package/lib/vflow/public-components/custom-template-edge/custom-template-edge.component.d.ts +1 -0
- package/lib/vflow/services/draggable.service.d.ts +1 -0
- package/lib/vflow/services/edge-rendering.service.d.ts +1 -1
- package/lib/vflow/services/flow-rendering.service.d.ts +4 -0
- package/lib/vflow/services/flow-status.service.d.ts +17 -1
- package/lib/vflow/utils/is-callable.d.ts +1 -0
- package/lib/vflow/utils/is-vflow-component.d.ts +4 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/testing/component-mocks/vflow-mock.component.d.ts +3 -2
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -2,11 +2,11 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { signal, computed, Injectable, inject, ElementRef, Directive, NgZone, effect, untracked, TemplateRef, DestroyRef, EventEmitter, OutputEmitterRef, input, assertInInjectionContext, Injector, runInInjectionContext, viewChild, Component, ChangeDetectionStrategy, output, HostListener, Renderer2, contentChild, Input, forwardRef } from '@angular/core';
|
|
3
3
|
import { select } from 'd3-selection';
|
|
4
4
|
import { zoomIdentity, zoom } from 'd3-zoom';
|
|
5
|
-
import { Subject, switchMap, merge, fromEvent, tap, Observable,
|
|
6
|
-
import { toObservable, takeUntilDestroyed,
|
|
5
|
+
import { Subject, switchMap, merge, fromEvent, tap, Observable, observeOn, asyncScheduler, filter, debounceTime, map, catchError, of, shareReplay, skip, pairwise, distinctUntilChanged, zip, animationFrameScheduler, share, startWith } from 'rxjs';
|
|
6
|
+
import { toObservable, takeUntilDestroyed, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
7
7
|
import { drag } from 'd3-drag';
|
|
8
8
|
import { __decorate } from 'tslib';
|
|
9
|
-
import { NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
|
|
9
|
+
import { NgTemplateOutlet, NgComponentOutlet, AsyncPipe, KeyValuePipe } from '@angular/common';
|
|
10
10
|
|
|
11
11
|
const getOverlappingArea = (rectA, rectB) => {
|
|
12
12
|
const xOverlap = Math.max(0, Math.min(rectA.x + rectA.width, rectB.x + rectB.width) - Math.max(rectA.x, rectB.x));
|
|
@@ -218,6 +218,7 @@ const DEFAULT_OPTIMIZATION = {
|
|
|
218
218
|
detachedGroupsLayer: false,
|
|
219
219
|
virtualization: false,
|
|
220
220
|
virtualizationZoomThreshold: 0.5,
|
|
221
|
+
lazyLoadTrigger: 'immediate',
|
|
221
222
|
};
|
|
222
223
|
|
|
223
224
|
class FlowSettingsService {
|
|
@@ -553,10 +554,58 @@ function align(num, constant) {
|
|
|
553
554
|
return Math.ceil(num / constant) * constant;
|
|
554
555
|
}
|
|
555
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
|
+
|
|
556
604
|
class DraggableService {
|
|
557
605
|
constructor() {
|
|
558
606
|
this.entitiesService = inject(FlowEntitiesService);
|
|
559
607
|
this.settingsService = inject(FlowSettingsService);
|
|
608
|
+
this.flowStatusService = inject(FlowStatusService);
|
|
560
609
|
}
|
|
561
610
|
/**
|
|
562
611
|
* Enable draggable behavior for element.
|
|
@@ -604,6 +653,7 @@ class DraggableService {
|
|
|
604
653
|
.filter(filterCondition)
|
|
605
654
|
.on('start', (event) => {
|
|
606
655
|
dragNodes = this.getDragNodes(model);
|
|
656
|
+
this.flowStatusService.setNodeDragStartStatus(model);
|
|
607
657
|
initialPositions = dragNodes.map((node) => ({
|
|
608
658
|
x: node.point().x - event.x,
|
|
609
659
|
y: node.point().y - event.y,
|
|
@@ -617,6 +667,9 @@ class DraggableService {
|
|
|
617
667
|
};
|
|
618
668
|
this.moveNode(model, point);
|
|
619
669
|
});
|
|
670
|
+
})
|
|
671
|
+
.on('end', () => {
|
|
672
|
+
this.flowStatusService.setNodeDragEndStatus(model);
|
|
620
673
|
});
|
|
621
674
|
}
|
|
622
675
|
getDragNodes(model) {
|
|
@@ -791,40 +844,15 @@ function addNodesToEdges(nodes, edges) {
|
|
|
791
844
|
});
|
|
792
845
|
}
|
|
793
846
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
setIdleStatus() {
|
|
799
|
-
this.status.set({ state: 'idle', payload: null });
|
|
800
|
-
}
|
|
801
|
-
setConnectionStartStatus(source, sourceHandle) {
|
|
802
|
-
this.status.set({ state: 'connection-start', payload: { source, sourceHandle } });
|
|
803
|
-
}
|
|
804
|
-
setReconnectionStartStatus(source, sourceHandle, oldEdge) {
|
|
805
|
-
this.status.set({ state: 'reconnection-start', payload: { source, sourceHandle, oldEdge } });
|
|
806
|
-
}
|
|
807
|
-
setConnectionValidationStatus(valid, source, target, sourceHandle, targetHandle) {
|
|
808
|
-
this.status.set({ state: 'connection-validation', payload: { source, target, sourceHandle, targetHandle, valid } });
|
|
809
|
-
}
|
|
810
|
-
setReconnectionValidationStatus(valid, source, target, sourceHandle, targetHandle, oldEdge) {
|
|
811
|
-
this.status.set({
|
|
812
|
-
state: 'reconnection-validation',
|
|
813
|
-
payload: { source, target, sourceHandle, targetHandle, valid, oldEdge },
|
|
814
|
-
});
|
|
815
|
-
}
|
|
816
|
-
setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
|
|
817
|
-
this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
|
|
847
|
+
function isCallable(fn) {
|
|
848
|
+
try {
|
|
849
|
+
new Proxy(fn, { apply: () => undefined })();
|
|
850
|
+
return true;
|
|
818
851
|
}
|
|
819
|
-
|
|
820
|
-
|
|
852
|
+
catch (err) {
|
|
853
|
+
return false;
|
|
821
854
|
}
|
|
822
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
823
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
|
|
824
855
|
}
|
|
825
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, decorators: [{
|
|
826
|
-
type: Injectable
|
|
827
|
-
}] });
|
|
828
856
|
|
|
829
857
|
class ComponentEventBusService {
|
|
830
858
|
constructor() {
|
|
@@ -906,7 +934,7 @@ function outputRefToObservable(ref) {
|
|
|
906
934
|
});
|
|
907
935
|
}
|
|
908
936
|
|
|
909
|
-
class
|
|
937
|
+
class CustomDynamicNodeComponent extends CustomNodeBaseComponent {
|
|
910
938
|
constructor() {
|
|
911
939
|
super(...arguments);
|
|
912
940
|
/**
|
|
@@ -915,19 +943,20 @@ class CustomNodeComponent extends CustomNodeBaseComponent {
|
|
|
915
943
|
this.node = input.required();
|
|
916
944
|
}
|
|
917
945
|
ngOnInit() {
|
|
918
|
-
|
|
919
|
-
|
|
946
|
+
const data = this.node().data;
|
|
947
|
+
if (data) {
|
|
948
|
+
this.data = data;
|
|
920
949
|
}
|
|
921
950
|
super.ngOnInit();
|
|
922
951
|
}
|
|
923
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
924
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type:
|
|
952
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
953
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: CustomDynamicNodeComponent, inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
|
|
925
954
|
}
|
|
926
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, decorators: [{
|
|
927
956
|
type: Directive
|
|
928
957
|
}] });
|
|
929
958
|
|
|
930
|
-
class
|
|
959
|
+
class CustomNodeComponent extends CustomNodeBaseComponent {
|
|
931
960
|
constructor() {
|
|
932
961
|
super(...arguments);
|
|
933
962
|
/**
|
|
@@ -936,19 +965,25 @@ class CustomDynamicNodeComponent extends CustomNodeBaseComponent {
|
|
|
936
965
|
this.node = input.required();
|
|
937
966
|
}
|
|
938
967
|
ngOnInit() {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
this.data = data;
|
|
968
|
+
if (this.node().data) {
|
|
969
|
+
this.data.set(this.node().data);
|
|
942
970
|
}
|
|
943
971
|
super.ngOnInit();
|
|
944
972
|
}
|
|
945
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
946
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type:
|
|
973
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
974
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: CustomNodeComponent, inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
|
|
947
975
|
}
|
|
948
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, decorators: [{
|
|
949
977
|
type: Directive
|
|
950
978
|
}] });
|
|
951
979
|
|
|
980
|
+
function isCustomNodeComponent(type) {
|
|
981
|
+
return Object.prototype.isPrototypeOf.call(CustomNodeComponent, type);
|
|
982
|
+
}
|
|
983
|
+
function isCustomDynamicNodeComponent(type) {
|
|
984
|
+
return Object.prototype.isPrototypeOf.call(CustomDynamicNodeComponent, type);
|
|
985
|
+
}
|
|
986
|
+
|
|
952
987
|
function isStaticNode(node) {
|
|
953
988
|
return typeof node.point !== 'function';
|
|
954
989
|
}
|
|
@@ -956,10 +991,18 @@ function isDynamicNode(node) {
|
|
|
956
991
|
return typeof node.point === 'function';
|
|
957
992
|
}
|
|
958
993
|
function isComponentStaticNode(node) {
|
|
959
|
-
|
|
994
|
+
if (isCustomNodeComponent(node.type)) {
|
|
995
|
+
return true;
|
|
996
|
+
}
|
|
997
|
+
// Check if the type is a function with dynamic import
|
|
998
|
+
return isCallable(node.type) && !isCallable(node.point);
|
|
960
999
|
}
|
|
961
1000
|
function isComponentDynamicNode(node) {
|
|
962
|
-
|
|
1001
|
+
if (isCustomDynamicNodeComponent(node.type)) {
|
|
1002
|
+
return true;
|
|
1003
|
+
}
|
|
1004
|
+
// Check if the type is a function with dynamic import
|
|
1005
|
+
return isCallable(node.type) && isCallable(node.point);
|
|
963
1006
|
}
|
|
964
1007
|
function isTemplateStaticNode(node) {
|
|
965
1008
|
return node.type === 'html-template';
|
|
@@ -1018,6 +1061,138 @@ function toSignalProperties(obj) {
|
|
|
1018
1061
|
return newObj;
|
|
1019
1062
|
}
|
|
1020
1063
|
|
|
1064
|
+
function isGroupNode(node) {
|
|
1065
|
+
return node.rawNode.type === 'default-group' || node.rawNode.type === 'template-group';
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// MIT License
|
|
1069
|
+
// Copyright (c) 2023 Chau Tran
|
|
1070
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1071
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
1072
|
+
// in the Software without restriction, including without limitation the rights
|
|
1073
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1074
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
1075
|
+
// furnished to do so, subject to the following conditions:
|
|
1076
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
1077
|
+
// copies or substantial portions of the Software.
|
|
1078
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1079
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1080
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1081
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1082
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1083
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1084
|
+
// SOFTWARE.
|
|
1085
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
1086
|
+
function assertInjector(fn, injector, runner) {
|
|
1087
|
+
!injector && assertInInjectionContext(fn);
|
|
1088
|
+
const assertedInjector = injector ?? inject(Injector);
|
|
1089
|
+
if (!runner)
|
|
1090
|
+
return assertedInjector;
|
|
1091
|
+
return runInInjectionContext(assertedInjector, runner);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
// MIT License
|
|
1095
|
+
// Copyright (c) 2023 Chau Tran
|
|
1096
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1097
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
1098
|
+
// in the Software without restriction, including without limitation the rights
|
|
1099
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1100
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
1101
|
+
// furnished to do so, subject to the following conditions:
|
|
1102
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
1103
|
+
// copies or substantial portions of the Software.
|
|
1104
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1105
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1106
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1107
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1108
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1109
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1110
|
+
// SOFTWARE.
|
|
1111
|
+
/**
|
|
1112
|
+
* Function `toLazySignal()` is a proxy function that will call the original
|
|
1113
|
+
* `toSignal()` function when the returned signal is read for the first time.
|
|
1114
|
+
*/
|
|
1115
|
+
function toLazySignal(source, options) {
|
|
1116
|
+
const injector = assertInjector(toLazySignal, options?.injector);
|
|
1117
|
+
let s;
|
|
1118
|
+
return computed(() => {
|
|
1119
|
+
if (!s) {
|
|
1120
|
+
s = untracked(() => toSignal(source, { ...options, injector }));
|
|
1121
|
+
}
|
|
1122
|
+
return s();
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
class NodeRenderingService {
|
|
1127
|
+
constructor() {
|
|
1128
|
+
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
1129
|
+
this.flowSettingsService = inject(FlowSettingsService);
|
|
1130
|
+
this.viewportService = inject(ViewportService);
|
|
1131
|
+
this.nodes = computed(() => {
|
|
1132
|
+
if (!this.flowSettingsService.optimization().virtualization) {
|
|
1133
|
+
return [...this.flowEntitiesService.nodes()].sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
1134
|
+
}
|
|
1135
|
+
return this.viewportNodesAfterInteraction().sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
1136
|
+
});
|
|
1137
|
+
this.groups = computed(() => {
|
|
1138
|
+
return this.nodes().filter((n) => isGroupNode(n));
|
|
1139
|
+
});
|
|
1140
|
+
this.nonGroups = computed(() => {
|
|
1141
|
+
return this.nodes().filter((n) => !isGroupNode(n));
|
|
1142
|
+
});
|
|
1143
|
+
this.viewportNodes = computed(() => {
|
|
1144
|
+
const nodes = this.flowEntitiesService.nodes();
|
|
1145
|
+
const viewport = this.viewportService.readableViewport();
|
|
1146
|
+
const flowWidth = this.flowSettingsService.computedFlowWidth();
|
|
1147
|
+
const flowHeight = this.flowSettingsService.computedFlowHeight();
|
|
1148
|
+
return nodes.filter((n) => {
|
|
1149
|
+
const { x, y } = n.globalPoint();
|
|
1150
|
+
const width = n.width();
|
|
1151
|
+
const height = n.height();
|
|
1152
|
+
return isRectInViewport({ x, y, width, height }, viewport, flowWidth, flowHeight);
|
|
1153
|
+
});
|
|
1154
|
+
});
|
|
1155
|
+
this.viewportNodesAfterInteraction = toLazySignal(merge(
|
|
1156
|
+
// TODO: maybe there is a better way wait when viewport is ready?
|
|
1157
|
+
// (to correctly calculate viewport nodes on first render)
|
|
1158
|
+
toObservable(this.flowEntitiesService.nodes).pipe(observeOn(asyncScheduler), filter((nodes) => !!nodes.length)), this.viewportService.viewportChangeEnd$.pipe(debounceTime(300))).pipe(map(() => {
|
|
1159
|
+
const viewport = this.viewportService.readableViewport();
|
|
1160
|
+
const zoomThreshold = this.flowSettingsService.optimization().virtualizationZoomThreshold;
|
|
1161
|
+
return viewport.zoom < zoomThreshold ? [] : this.viewportNodes();
|
|
1162
|
+
})), {
|
|
1163
|
+
initialValue: [],
|
|
1164
|
+
});
|
|
1165
|
+
this.maxOrder = computed(() => {
|
|
1166
|
+
return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
pullNode(node) {
|
|
1170
|
+
// pull node
|
|
1171
|
+
node.renderOrder.set(this.maxOrder() + 1);
|
|
1172
|
+
// pull children
|
|
1173
|
+
node.children().forEach((n) => this.pullNode(n));
|
|
1174
|
+
}
|
|
1175
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1176
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService }); }
|
|
1177
|
+
}
|
|
1178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, decorators: [{
|
|
1179
|
+
type: Injectable
|
|
1180
|
+
}] });
|
|
1181
|
+
|
|
1182
|
+
// MIT License
|
|
1183
|
+
/**
|
|
1184
|
+
* @todo Use `linkedSignal` after Angular update
|
|
1185
|
+
*/
|
|
1186
|
+
function extendedComputed(computedCallback, options) {
|
|
1187
|
+
if (!options) {
|
|
1188
|
+
options = { equal: Object.is };
|
|
1189
|
+
}
|
|
1190
|
+
let currentValue = undefined;
|
|
1191
|
+
return computed(() => {
|
|
1192
|
+
return (currentValue = computedCallback(currentValue));
|
|
1193
|
+
}, options);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1021
1196
|
class NodeModel {
|
|
1022
1197
|
static { this.defaultWidth = 100; }
|
|
1023
1198
|
static { this.defaultHeight = 50; }
|
|
@@ -1025,6 +1200,8 @@ class NodeModel {
|
|
|
1025
1200
|
constructor(rawNode) {
|
|
1026
1201
|
this.rawNode = rawNode;
|
|
1027
1202
|
this.entitiesService = inject(FlowEntitiesService);
|
|
1203
|
+
this.settingsService = inject(FlowSettingsService);
|
|
1204
|
+
this.nodeRenderingService = inject(NodeRenderingService);
|
|
1028
1205
|
this.isVisible = signal(false);
|
|
1029
1206
|
this.point = signal({ x: 0, y: 0 });
|
|
1030
1207
|
this.width = signal(NodeModel.defaultWidth);
|
|
@@ -1063,6 +1240,39 @@ class NodeModel {
|
|
|
1063
1240
|
this.magnetRadius = 20;
|
|
1064
1241
|
// TODO: not sure if we need to statically store it
|
|
1065
1242
|
this.isComponentType = isComponentStaticNode(this.rawNode) || isComponentDynamicNode(this.rawNode);
|
|
1243
|
+
this.shouldLoad = extendedComputed((previousShouldLoad) => {
|
|
1244
|
+
if (previousShouldLoad) {
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
if (this.settingsService.optimization().lazyLoadTrigger === 'immediate') {
|
|
1248
|
+
return true;
|
|
1249
|
+
}
|
|
1250
|
+
else if (this.settingsService.optimization().lazyLoadTrigger === 'viewport') {
|
|
1251
|
+
// Immediately load component if it's a plain class
|
|
1252
|
+
if (isCustomNodeComponent(this.rawNode.type)) {
|
|
1253
|
+
return true;
|
|
1254
|
+
}
|
|
1255
|
+
// Immediately load component if it's a plain class
|
|
1256
|
+
if (isCustomDynamicNodeComponent(this.rawNode.type)) {
|
|
1257
|
+
return true;
|
|
1258
|
+
}
|
|
1259
|
+
// For cases
|
|
1260
|
+
// - if it's a factory with dynamic import
|
|
1261
|
+
// - if it's a template (html, svg, group)
|
|
1262
|
+
// check if it's in the viewport
|
|
1263
|
+
if (isCallable(this.rawNode.type) ||
|
|
1264
|
+
this.rawNode.type === 'html-template' ||
|
|
1265
|
+
this.rawNode.type === 'svg-template' ||
|
|
1266
|
+
this.rawNode.type === 'template-group') {
|
|
1267
|
+
return this.nodeRenderingService.viewportNodes().includes(this);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
// For each other case, we want to load the component immediately
|
|
1271
|
+
return true;
|
|
1272
|
+
});
|
|
1273
|
+
this.componentInstance$ = toObservable(this.shouldLoad).pipe(filter(Boolean),
|
|
1274
|
+
// @ts-expect-error we assume it's a function with dynamic import
|
|
1275
|
+
switchMap(() => this.rawNode.type()), catchError(() => of(this.rawNode.type)), shareReplay(1));
|
|
1066
1276
|
// Default node specific thing
|
|
1067
1277
|
this.text = signal('');
|
|
1068
1278
|
// Component node specific thing
|
|
@@ -1112,7 +1322,8 @@ class NodeModel {
|
|
|
1112
1322
|
this.context = {
|
|
1113
1323
|
$implicit: {
|
|
1114
1324
|
node: rawNode,
|
|
1115
|
-
selected: this.selected,
|
|
1325
|
+
selected: this.selected.asReadonly(),
|
|
1326
|
+
shouldLoad: this.shouldLoad,
|
|
1116
1327
|
},
|
|
1117
1328
|
};
|
|
1118
1329
|
}
|
|
@@ -1120,9 +1331,10 @@ class NodeModel {
|
|
|
1120
1331
|
this.context = {
|
|
1121
1332
|
$implicit: {
|
|
1122
1333
|
node: rawNode,
|
|
1123
|
-
selected: this.selected,
|
|
1124
|
-
width: this.width,
|
|
1125
|
-
height: this.height,
|
|
1334
|
+
selected: this.selected.asReadonly(),
|
|
1335
|
+
width: this.width.asReadonly(),
|
|
1336
|
+
height: this.height.asReadonly(),
|
|
1337
|
+
shouldLoad: this.shouldLoad,
|
|
1126
1338
|
},
|
|
1127
1339
|
};
|
|
1128
1340
|
}
|
|
@@ -1131,8 +1343,9 @@ class NodeModel {
|
|
|
1131
1343
|
$implicit: {
|
|
1132
1344
|
node: rawNode,
|
|
1133
1345
|
selected: this.selected.asReadonly(),
|
|
1134
|
-
width: this.width,
|
|
1135
|
-
height: this.height,
|
|
1346
|
+
width: this.width.asReadonly(),
|
|
1347
|
+
height: this.height.asReadonly(),
|
|
1348
|
+
shouldLoad: this.shouldLoad,
|
|
1136
1349
|
},
|
|
1137
1350
|
};
|
|
1138
1351
|
}
|
|
@@ -1470,20 +1683,6 @@ function smoothStepPath({ sourcePoint, targetPoint, sourcePosition, targetPositi
|
|
|
1470
1683
|
};
|
|
1471
1684
|
}
|
|
1472
1685
|
|
|
1473
|
-
// MIT License
|
|
1474
|
-
/**
|
|
1475
|
-
* @todo Use `linkedSignal` after Angular update
|
|
1476
|
-
*/
|
|
1477
|
-
function extendedComputed(computedCallback, options) {
|
|
1478
|
-
if (!options) {
|
|
1479
|
-
options = { equal: Object.is };
|
|
1480
|
-
}
|
|
1481
|
-
let currentValue = undefined;
|
|
1482
|
-
return computed(() => {
|
|
1483
|
-
return (currentValue = computedCallback(currentValue));
|
|
1484
|
-
}, options);
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
1686
|
class EdgeModel {
|
|
1488
1687
|
constructor(edge) {
|
|
1489
1688
|
this.edge = edge;
|
|
@@ -1492,6 +1691,7 @@ class EdgeModel {
|
|
|
1492
1691
|
this.target = signal(undefined);
|
|
1493
1692
|
this.selected = signal(false);
|
|
1494
1693
|
this.selected$ = toObservable(this.selected);
|
|
1694
|
+
this.shouldLoad = computed(() => (this.source()?.shouldLoad() ?? false) && (this.target()?.shouldLoad() ?? false));
|
|
1495
1695
|
this.renderOrder = signal(0);
|
|
1496
1696
|
this.detached = computed(() => {
|
|
1497
1697
|
const source = this.source();
|
|
@@ -1521,14 +1721,7 @@ class EdgeModel {
|
|
|
1521
1721
|
const target = this.targetHandle();
|
|
1522
1722
|
// TODO: don't like this
|
|
1523
1723
|
if (!source || !target) {
|
|
1524
|
-
return {
|
|
1525
|
-
path: '',
|
|
1526
|
-
labelPoints: {
|
|
1527
|
-
start: { x: 0, y: 0 },
|
|
1528
|
-
center: { x: 0, y: 0 },
|
|
1529
|
-
end: { x: 0, y: 0 },
|
|
1530
|
-
},
|
|
1531
|
-
};
|
|
1724
|
+
return { path: '' };
|
|
1532
1725
|
}
|
|
1533
1726
|
const params = this.getPathFactoryParams(source, target);
|
|
1534
1727
|
switch (this.curve) {
|
|
@@ -1660,6 +1853,7 @@ class EdgeModel {
|
|
|
1660
1853
|
markerStart: this.markerStartUrl,
|
|
1661
1854
|
markerEnd: this.markerEndUrl,
|
|
1662
1855
|
selected: this.selected.asReadonly(),
|
|
1856
|
+
shouldLoad: this.shouldLoad,
|
|
1663
1857
|
},
|
|
1664
1858
|
};
|
|
1665
1859
|
this.edgeLabels = {};
|
|
@@ -1947,124 +2141,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1947
2141
|
}]
|
|
1948
2142
|
}] });
|
|
1949
2143
|
|
|
1950
|
-
function isGroupNode(node) {
|
|
1951
|
-
return node.rawNode.type === 'default-group' || node.rawNode.type === 'template-group';
|
|
1952
|
-
}
|
|
1953
|
-
|
|
1954
|
-
// MIT License
|
|
1955
|
-
// Copyright (c) 2023 Chau Tran
|
|
1956
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1957
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
1958
|
-
// in the Software without restriction, including without limitation the rights
|
|
1959
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1960
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
1961
|
-
// furnished to do so, subject to the following conditions:
|
|
1962
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
1963
|
-
// copies or substantial portions of the Software.
|
|
1964
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1965
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1966
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1967
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1968
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1969
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1970
|
-
// SOFTWARE.
|
|
1971
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
1972
|
-
function assertInjector(fn, injector, runner) {
|
|
1973
|
-
!injector && assertInInjectionContext(fn);
|
|
1974
|
-
const assertedInjector = injector ?? inject(Injector);
|
|
1975
|
-
if (!runner)
|
|
1976
|
-
return assertedInjector;
|
|
1977
|
-
return runInInjectionContext(assertedInjector, runner);
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
// MIT License
|
|
1981
|
-
// Copyright (c) 2023 Chau Tran
|
|
1982
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1983
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
1984
|
-
// in the Software without restriction, including without limitation the rights
|
|
1985
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1986
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
1987
|
-
// furnished to do so, subject to the following conditions:
|
|
1988
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
1989
|
-
// copies or substantial portions of the Software.
|
|
1990
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1991
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1992
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1993
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1994
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1995
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1996
|
-
// SOFTWARE.
|
|
1997
|
-
/**
|
|
1998
|
-
* Function `toLazySignal()` is a proxy function that will call the original
|
|
1999
|
-
* `toSignal()` function when the returned signal is read for the first time.
|
|
2000
|
-
*/
|
|
2001
|
-
function toLazySignal(source, options) {
|
|
2002
|
-
const injector = assertInjector(toLazySignal, options?.injector);
|
|
2003
|
-
let s;
|
|
2004
|
-
return computed(() => {
|
|
2005
|
-
if (!s) {
|
|
2006
|
-
s = untracked(() => toSignal(source, { ...options, injector }));
|
|
2007
|
-
}
|
|
2008
|
-
return s();
|
|
2009
|
-
});
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
class NodeRenderingService {
|
|
2013
|
-
constructor() {
|
|
2014
|
-
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
2015
|
-
this.flowSettingsService = inject(FlowSettingsService);
|
|
2016
|
-
this.viewportService = inject(ViewportService);
|
|
2017
|
-
this.nodes = computed(() => {
|
|
2018
|
-
if (!this.flowSettingsService.optimization().virtualization) {
|
|
2019
|
-
return [...this.flowEntitiesService.nodes()].sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
2020
|
-
}
|
|
2021
|
-
return this.viewportNodesAfterInteraction().sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
2022
|
-
});
|
|
2023
|
-
this.groups = computed(() => {
|
|
2024
|
-
return this.nodes().filter((n) => isGroupNode(n));
|
|
2025
|
-
});
|
|
2026
|
-
this.nonGroups = computed(() => {
|
|
2027
|
-
return this.nodes().filter((n) => !isGroupNode(n));
|
|
2028
|
-
});
|
|
2029
|
-
this.viewportNodes = computed(() => {
|
|
2030
|
-
const nodes = this.flowEntitiesService.nodes();
|
|
2031
|
-
const viewport = this.viewportService.readableViewport();
|
|
2032
|
-
const flowWidth = this.flowSettingsService.computedFlowWidth();
|
|
2033
|
-
const flowHeight = this.flowSettingsService.computedFlowHeight();
|
|
2034
|
-
return nodes.filter((n) => {
|
|
2035
|
-
const { x, y } = n.globalPoint();
|
|
2036
|
-
const width = n.width();
|
|
2037
|
-
const height = n.height();
|
|
2038
|
-
return isRectInViewport({ x, y, width, height }, viewport, flowWidth, flowHeight);
|
|
2039
|
-
});
|
|
2040
|
-
});
|
|
2041
|
-
this.viewportNodesAfterInteraction = toLazySignal(merge(
|
|
2042
|
-
// TODO: maybe there is a better way wait when viewport is ready?
|
|
2043
|
-
// (to correctly calculate viewport nodes on first render)
|
|
2044
|
-
toObservable(this.flowEntitiesService.nodes).pipe(observeOn(asyncScheduler), filter((nodes) => !!nodes.length)), this.viewportService.viewportChangeEnd$.pipe(debounceTime(300))).pipe(map(() => {
|
|
2045
|
-
const viewport = this.viewportService.readableViewport();
|
|
2046
|
-
const zoomThreshold = this.flowSettingsService.optimization().virtualizationZoomThreshold;
|
|
2047
|
-
return viewport.zoom < zoomThreshold ? [] : this.viewportNodes();
|
|
2048
|
-
})), {
|
|
2049
|
-
initialValue: [],
|
|
2050
|
-
});
|
|
2051
|
-
this.maxOrder = computed(() => {
|
|
2052
|
-
return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
|
|
2053
|
-
});
|
|
2054
|
-
}
|
|
2055
|
-
pullNode(node) {
|
|
2056
|
-
// pull node
|
|
2057
|
-
node.renderOrder.set(this.maxOrder() + 1);
|
|
2058
|
-
// pull children
|
|
2059
|
-
node.children().forEach((n) => this.pullNode(n));
|
|
2060
|
-
}
|
|
2061
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2062
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService }); }
|
|
2063
|
-
}
|
|
2064
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, decorators: [{
|
|
2065
|
-
type: Injectable
|
|
2066
|
-
}] });
|
|
2067
|
-
|
|
2068
2144
|
class RootPointerDirective {
|
|
2069
2145
|
constructor() {
|
|
2070
2146
|
this.host = inject(ElementRef).nativeElement;
|
|
@@ -3206,7 +3282,7 @@ class NodeComponent {
|
|
|
3206
3282
|
}
|
|
3207
3283
|
}
|
|
3208
3284
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3209
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeSvgTemplate: { classPropertyName: "nodeSvgTemplate", publicName: "nodeSvgTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], ngImport: i0, template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n <svg:foreignObject\n
|
|
3285
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeSvgTemplate: { classPropertyName: "nodeSvgTemplate", publicName: "nodeSvgTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupNodeTemplate: { classPropertyName: "groupNodeTemplate", publicName: "groupNodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "vflow-node" }, providers: [HandleService, NodeAccessorService], ngImport: i0, template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n @if (model().componentInstance$ | async; as component) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(component)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n }\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\n [class.default-group-node_selected]=\"model().selected()\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n [style.stroke]=\"model().color()\"\n [style.fill]=\"model().color()\"\n (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\">\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\">\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }, { kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }, { kind: "component", type: HandleComponent, selector: "handle", inputs: ["position", "type", "id", "template", "offsetX", "offsetY"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: ResizableComponent, selector: "[resizable]", inputs: ["resizable", "resizerColor", "gap"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }, { kind: "directive", type: NodeHandlesControllerDirective, selector: "[nodeHandlesController]" }, { kind: "directive", type: NodeResizeControllerDirective, selector: "[nodeResizeController]" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3210
3286
|
}
|
|
3211
3287
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, decorators: [{
|
|
3212
3288
|
type: Component,
|
|
@@ -3222,7 +3298,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3222
3298
|
HandleSizeControllerDirective,
|
|
3223
3299
|
NodeHandlesControllerDirective,
|
|
3224
3300
|
NodeResizeControllerDirective,
|
|
3225
|
-
|
|
3301
|
+
AsyncPipe,
|
|
3302
|
+
], template: "<!-- Default node -->\n@if (model().rawNode.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode(); selectNode()\">\n <default-node\n nodeHandlesController\n [selected]=\"model().selected()\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\"\n [style.max-width]=\"model().styleWidth()\"\n [style.max-height]=\"model().styleHeight()\">\n <div [outerHTML]=\"model().text()\"></div>\n\n <handle type=\"source\" position=\"right\" />\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n}\n\n<!-- HTML Template node -->\n@if (model().rawNode.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- SVG Template node -->\n@if (model().rawNode.type === 'svg-template' && nodeSvgTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"nodeSvgTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Component node -->\n@if (model().isComponentType) {\n @if (model().componentInstance$ | async; as component) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (click)=\"pullNode()\">\n <div\n nodeHandlesController\n nodeResizeController\n class=\"wrapper\"\n [style.width]=\"model().styleWidth()\"\n [style.height]=\"model().styleHeight()\">\n <ng-container\n [ngComponentOutlet]=\"$any(component)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n }\n}\n\n<!-- Default group node -->\n@if (model().rawNode.type === 'default-group') {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [resizable]=\"model().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"model().color()\"\n [class.default-group-node_selected]=\"model().selected()\"\n [attr.width]=\"model().size().width\"\n [attr.height]=\"model().size().height\"\n [style.stroke]=\"model().color()\"\n [style.fill]=\"model().color()\"\n (click)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().rawNode.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (click)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (model().resizerTemplate(); as template) {\n @if (model().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of model().handles(); track handle) {\n @if (handle.template === undefined) {\n <svg:circle\n class=\"default-handle\"\n r=\"5\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template === null) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\" />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection()\">\n <ng-container *ngTemplateOutlet=\"handle.template; context: handle.templateContext\" />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"model().magnetRadius\"\n [attr.cx]=\"handle.hostOffset().x\"\n [attr.cy]=\"handle.hostOffset().y\"\n (pointerEnd)=\"endConnection(); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\" />\n }\n}\n\n<!-- Toolbar -->\n@for (toolbar of toolbars(); track toolbar) {\n <svg:foreignObject\n [attr.width]=\"toolbar.size().width\"\n [attr.height]=\"toolbar.size().height\"\n [attr.transform]=\"toolbar.transform()\">\n <ng-container [ngTemplateOutlet]=\"toolbar.template()\" />\n </svg:foreignObject>\n}\n", styles: [".magnet{opacity:0}.wrapper{display:table-cell}.default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}.default-handle{stroke:#fff;fill:#1b262c}\n"] }]
|
|
3226
3303
|
}] });
|
|
3227
3304
|
|
|
3228
3305
|
class ConnectionComponent {
|
|
@@ -3770,6 +3847,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3770
3847
|
|
|
3771
3848
|
class FlowRenderingService {
|
|
3772
3849
|
constructor() {
|
|
3850
|
+
this.nodeRenderingService = inject(NodeRenderingService);
|
|
3851
|
+
this.edgeRenderingService = inject(EdgeRenderingService);
|
|
3852
|
+
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
3853
|
+
this.settingsService = inject(FlowSettingsService);
|
|
3773
3854
|
this.flowInitialized = signal(false);
|
|
3774
3855
|
inject(NgZone).runOutsideAngular(async () => {
|
|
3775
3856
|
await skipFrames(2);
|
|
@@ -3799,6 +3880,109 @@ function skipFrames(count) {
|
|
|
3799
3880
|
});
|
|
3800
3881
|
}
|
|
3801
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
|
+
|
|
3802
3986
|
const changesControllerHostDirective = {
|
|
3803
3987
|
directive: ChangesControllerDirective,
|
|
3804
3988
|
outputs: [
|
|
@@ -3847,6 +4031,7 @@ class VflowComponent {
|
|
|
3847
4031
|
this.keyboardService = inject(KeyboardService);
|
|
3848
4032
|
this.injector = inject(Injector);
|
|
3849
4033
|
this.flowRenderingService = inject(FlowRenderingService);
|
|
4034
|
+
this.alignmentHelper = input(false);
|
|
3850
4035
|
this.nodeModels = this.nodeRenderingService.nodes;
|
|
3851
4036
|
this.groups = this.nodeRenderingService.groups;
|
|
3852
4037
|
this.nonGroups = this.nodeRenderingService.nonGroups;
|
|
@@ -4108,7 +4293,7 @@ class VflowComponent {
|
|
|
4108
4293
|
return edge;
|
|
4109
4294
|
}
|
|
4110
4295
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4111
|
-
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:
|
|
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: [
|
|
4112
4297
|
DraggableService,
|
|
4113
4298
|
ViewportService,
|
|
4114
4299
|
FlowStatusService,
|
|
@@ -4124,7 +4309,7 @@ class VflowComponent {
|
|
|
4124
4309
|
OverlaysService,
|
|
4125
4310
|
{ provide: PreviewFlowRenderStrategyService, useClass: ViewportPreviewFlowRenderStrategyService },
|
|
4126
4311
|
FlowRenderingService,
|
|
4127
|
-
], 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 }); }
|
|
4128
4313
|
}
|
|
4129
4314
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
|
|
4130
4315
|
type: Component,
|
|
@@ -4158,7 +4343,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
4158
4343
|
EdgeComponent,
|
|
4159
4344
|
NgTemplateOutlet,
|
|
4160
4345
|
PreviewFlowComponent,
|
|
4161
|
-
|
|
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"] }]
|
|
4162
4348
|
}], propDecorators: { view: [{
|
|
4163
4349
|
type: Input
|
|
4164
4350
|
}], minZoom: [{
|
|
@@ -4509,5 +4695,5 @@ const Vflow = [
|
|
|
4509
4695
|
* Generated bundle index. Do not edit.
|
|
4510
4696
|
*/
|
|
4511
4697
|
|
|
4512
|
-
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, CustomTemplateEdgeComponent, DEFAULT_OPTIMIZATION, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeSvgTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, Vflow, VflowComponent, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isSvgTemplateDynamicNode, isSvgTemplateStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, ComponentEventBusService as ɵComponentEventBusService, ConnectionModel as ɵConnectionModel, FlowEntitiesService as ɵFlowEntitiesService, FlowSettingsService as ɵFlowSettingsService, HandleModel as ɵHandleModel, HandleService as ɵHandleService, NodeAccessorService as ɵNodeAccessorService, NodeModel as ɵNodeModel, RootPointerDirective as ɵRootPointerDirective, SelectionService as ɵSelectionService, SpacePointContextDirective as ɵSpacePointContextDirective, ViewportService as ɵViewportService };
|
|
4698
|
+
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, CustomTemplateEdgeComponent, DEFAULT_OPTIMIZATION, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeSvgTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, Vflow, VflowComponent, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isSvgTemplateDynamicNode, isSvgTemplateStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, ComponentEventBusService as ɵComponentEventBusService, ConnectionModel as ɵConnectionModel, FlowEntitiesService as ɵFlowEntitiesService, FlowSettingsService as ɵFlowSettingsService, HandleModel as ɵHandleModel, HandleService as ɵHandleService, NodeAccessorService as ɵNodeAccessorService, NodeModel as ɵNodeModel, NodeRenderingService as ɵNodeRenderingService, RootPointerDirective as ɵRootPointerDirective, SelectionService as ɵSelectionService, SpacePointContextDirective as ɵSpacePointContextDirective, ViewportService as ɵViewportService };
|
|
4513
4699
|
//# sourceMappingURL=ngx-vflow.mjs.map
|