ngx-vflow 1.4.2 → 1.6.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/connection/connection.component.mjs +4 -3
- package/esm2022/lib/vflow/components/edge/edge.component.mjs +29 -26
- package/esm2022/lib/vflow/components/edge-label/edge-label.component.mjs +2 -1
- package/esm2022/lib/vflow/components/node/node.component.mjs +6 -4
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +15 -3
- package/esm2022/lib/vflow/directives/connection-controller.directive.mjs +55 -37
- package/esm2022/lib/vflow/directives/root-svg-context.directive.mjs +2 -2
- package/esm2022/lib/vflow/directives/selectable.directive.mjs +14 -11
- package/esm2022/lib/vflow/directives/template.directive.mjs +16 -1
- package/esm2022/lib/vflow/interfaces/connection.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/contextable.interface.mjs +2 -0
- package/esm2022/lib/vflow/interfaces/edge.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/template-context.interface.mjs +1 -1
- package/esm2022/lib/vflow/models/edge.model.mjs +50 -23
- package/esm2022/lib/vflow/models/node.model.mjs +22 -1
- package/esm2022/lib/vflow/public-components/custom-template-edge/custom-template-edge.component.mjs +29 -0
- package/esm2022/lib/vflow/services/edge-rendering.service.mjs +28 -0
- package/esm2022/lib/vflow/services/flow-settings.service.mjs +2 -1
- package/esm2022/lib/vflow/services/flow-status.service.mjs +13 -1
- package/esm2022/lib/vflow/testing-utils/component-mocks/vflow-mock.component.mjs +4 -2
- package/esm2022/lib/vflow/testing-utils/directive-mocks/connection-controller-mock.directive.mjs +6 -2
- package/esm2022/lib/vflow/vflow.mjs +3 -1
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ngx-vflow.mjs +358 -193
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/connection/connection.component.d.ts +2 -6
- package/lib/vflow/components/edge/edge.component.d.ts +10 -7
- package/lib/vflow/components/edge-label/edge-label.component.d.ts +2 -6
- package/lib/vflow/components/vflow/vflow.component.d.ts +6 -1
- package/lib/vflow/directives/connection-controller.directive.d.ts +5 -2
- package/lib/vflow/directives/selectable.directive.d.ts +4 -1
- package/lib/vflow/directives/template.directive.d.ts +6 -1
- package/lib/vflow/interfaces/connection.interface.d.ts +5 -0
- package/lib/vflow/interfaces/contextable.interface.d.ts +5 -0
- package/lib/vflow/interfaces/edge.interface.d.ts +1 -0
- package/lib/vflow/interfaces/template-context.interface.d.ts +37 -1
- package/lib/vflow/models/edge.model.d.ts +24 -1
- package/lib/vflow/models/node.model.d.ts +8 -1
- package/lib/vflow/public-components/custom-template-edge/custom-template-edge.component.d.ts +17 -0
- package/lib/vflow/services/edge-rendering.service.d.ts +10 -0
- package/lib/vflow/services/flow-settings.service.d.ts +1 -0
- package/lib/vflow/services/flow-status.service.d.ts +24 -1
- package/lib/vflow/testing-utils/component-mocks/vflow-mock.component.d.ts +2 -1
- package/lib/vflow/testing-utils/directive-mocks/connection-controller-mock.directive.d.ts +4 -2
- package/lib/vflow/vflow.d.ts +2 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, DestroyRef, EventEmitter, OutputEmitterRef, input, NgZone, viewChild, Component, ChangeDetectionStrategy,
|
|
2
|
+
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, DestroyRef, EventEmitter, OutputEmitterRef, input, NgZone, viewChild, Component, ChangeDetectionStrategy, output, HostListener, Injector, runInInjectionContext, contentChild, Input, forwardRef } from '@angular/core';
|
|
3
3
|
import { select } from 'd3-selection';
|
|
4
4
|
import { zoomIdentity, zoom } from 'd3-zoom';
|
|
5
5
|
import { switchMap, merge, fromEvent, tap, Subject, Observable, skip, map, pairwise, filter, distinctUntilChanged, observeOn, asyncScheduler, zip, animationFrameScheduler, share, startWith, of } from 'rxjs';
|
|
@@ -151,6 +151,7 @@ class FlowSettingsService {
|
|
|
151
151
|
constructor() {
|
|
152
152
|
this.entitiesSelectable = signal(true);
|
|
153
153
|
this.elevateNodesOnSelect = signal(true);
|
|
154
|
+
this.elevateEdgesOnSelect = signal(true);
|
|
154
155
|
/**
|
|
155
156
|
* @see {VflowComponent.view}
|
|
156
157
|
*/
|
|
@@ -575,6 +576,9 @@ class EdgeTemplateDirective {
|
|
|
575
576
|
constructor() {
|
|
576
577
|
this.templateRef = inject(TemplateRef);
|
|
577
578
|
}
|
|
579
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
578
582
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
579
583
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeTemplateDirective, isStandalone: true, selector: "ng-template[edge]", ngImport: i0 }); }
|
|
580
584
|
}
|
|
@@ -589,6 +593,9 @@ class ConnectionTemplateDirective {
|
|
|
589
593
|
constructor() {
|
|
590
594
|
this.templateRef = inject(TemplateRef);
|
|
591
595
|
}
|
|
596
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
592
599
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
593
600
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionTemplateDirective, isStandalone: true, selector: "ng-template[connection]", ngImport: i0 }); }
|
|
594
601
|
}
|
|
@@ -603,6 +610,9 @@ class EdgeLabelHtmlTemplateDirective {
|
|
|
603
610
|
constructor() {
|
|
604
611
|
this.templateRef = inject(TemplateRef);
|
|
605
612
|
}
|
|
613
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
614
|
+
return true;
|
|
615
|
+
}
|
|
606
616
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
607
617
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeLabelHtmlTemplateDirective, isStandalone: true, selector: "ng-template[edgeLabelHtml]", ngImport: i0 }); }
|
|
608
618
|
}
|
|
@@ -617,6 +627,9 @@ class NodeHtmlTemplateDirective {
|
|
|
617
627
|
constructor() {
|
|
618
628
|
this.templateRef = inject(TemplateRef);
|
|
619
629
|
}
|
|
630
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
620
633
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
621
634
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NodeHtmlTemplateDirective, isStandalone: true, selector: "ng-template[nodeHtml]", ngImport: i0 }); }
|
|
622
635
|
}
|
|
@@ -631,6 +644,9 @@ class GroupNodeTemplateDirective {
|
|
|
631
644
|
constructor() {
|
|
632
645
|
this.templateRef = inject(TemplateRef);
|
|
633
646
|
}
|
|
647
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
648
|
+
return true;
|
|
649
|
+
}
|
|
634
650
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
635
651
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: GroupNodeTemplateDirective, isStandalone: true, selector: "ng-template[groupNode]", ngImport: i0 }); }
|
|
636
652
|
}
|
|
@@ -677,12 +693,24 @@ class FlowStatusService {
|
|
|
677
693
|
setConnectionStartStatus(source, sourceHandle) {
|
|
678
694
|
this.status.set({ state: 'connection-start', payload: { source, sourceHandle } });
|
|
679
695
|
}
|
|
696
|
+
setReconnectionStartStatus(source, sourceHandle, oldEdge) {
|
|
697
|
+
this.status.set({ state: 'reconnection-start', payload: { source, sourceHandle, oldEdge } });
|
|
698
|
+
}
|
|
680
699
|
setConnectionValidationStatus(valid, source, target, sourceHandle, targetHandle) {
|
|
681
700
|
this.status.set({ state: 'connection-validation', payload: { source, target, sourceHandle, targetHandle, valid } });
|
|
682
701
|
}
|
|
702
|
+
setReconnectionValidationStatus(valid, source, target, sourceHandle, targetHandle, oldEdge) {
|
|
703
|
+
this.status.set({
|
|
704
|
+
state: 'reconnection-validation',
|
|
705
|
+
payload: { source, target, sourceHandle, targetHandle, valid, oldEdge },
|
|
706
|
+
});
|
|
707
|
+
}
|
|
683
708
|
setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
|
|
684
709
|
this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
|
|
685
710
|
}
|
|
711
|
+
setReconnectionEndStatus(source, target, sourceHandle, targetHandle, oldEdge) {
|
|
712
|
+
this.status.set({ state: 'reconnection-end', payload: { source, target, sourceHandle, targetHandle, oldEdge } });
|
|
713
|
+
}
|
|
686
714
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
687
715
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
|
|
688
716
|
}
|
|
@@ -914,6 +942,9 @@ class NodeModel {
|
|
|
914
942
|
this.resizable = signal(false);
|
|
915
943
|
this.resizing = signal(false);
|
|
916
944
|
this.resizerTemplate = signal(null);
|
|
945
|
+
this.context = {
|
|
946
|
+
$implicit: {},
|
|
947
|
+
};
|
|
917
948
|
this.parentId = signal(null);
|
|
918
949
|
if (isDefined(node.draggable)) {
|
|
919
950
|
if (isDynamicNode(node)) {
|
|
@@ -947,6 +978,24 @@ class NodeModel {
|
|
|
947
978
|
this.resizable.set(node.resizable);
|
|
948
979
|
}
|
|
949
980
|
}
|
|
981
|
+
if (node.type === 'html-template') {
|
|
982
|
+
this.context = {
|
|
983
|
+
$implicit: {
|
|
984
|
+
node: node,
|
|
985
|
+
selected: this.selected,
|
|
986
|
+
},
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
else if (node.type === 'template-group') {
|
|
990
|
+
this.context = {
|
|
991
|
+
$implicit: {
|
|
992
|
+
node: node,
|
|
993
|
+
selected: this.selected.asReadonly(),
|
|
994
|
+
width: this.width,
|
|
995
|
+
height: this.height,
|
|
996
|
+
},
|
|
997
|
+
};
|
|
998
|
+
}
|
|
950
999
|
}
|
|
951
1000
|
setPoint(point) {
|
|
952
1001
|
this.point.set(point);
|
|
@@ -1254,6 +1303,7 @@ class EdgeModel {
|
|
|
1254
1303
|
this.target = signal(undefined);
|
|
1255
1304
|
this.selected = signal(false);
|
|
1256
1305
|
this.selected$ = toObservable(this.selected);
|
|
1306
|
+
this.renderOrder = signal(0);
|
|
1257
1307
|
this.detached = computed(() => {
|
|
1258
1308
|
const source = this.source();
|
|
1259
1309
|
const target = this.target();
|
|
@@ -1278,28 +1328,8 @@ class EdgeModel {
|
|
|
1278
1328
|
});
|
|
1279
1329
|
this.detached$ = toObservable(this.detached);
|
|
1280
1330
|
this.path = computed(() => {
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
source = this.source()
|
|
1284
|
-
?.handles()
|
|
1285
|
-
.find((handle) => handle.rawHandle.id === this.edge.sourceHandle);
|
|
1286
|
-
}
|
|
1287
|
-
else {
|
|
1288
|
-
source = this.source()
|
|
1289
|
-
?.handles()
|
|
1290
|
-
.find((handle) => handle.rawHandle.type === 'source');
|
|
1291
|
-
}
|
|
1292
|
-
let target;
|
|
1293
|
-
if (this.edge.targetHandle) {
|
|
1294
|
-
target = this.target()
|
|
1295
|
-
?.handles()
|
|
1296
|
-
.find((handle) => handle.rawHandle.id === this.edge.targetHandle);
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
target = this.target()
|
|
1300
|
-
?.handles()
|
|
1301
|
-
.find((handle) => handle.rawHandle.type === 'target');
|
|
1302
|
-
}
|
|
1331
|
+
const source = this.sourceHandle();
|
|
1332
|
+
const target = this.targetHandle();
|
|
1303
1333
|
// TODO: don't like this
|
|
1304
1334
|
if (!source || !target) {
|
|
1305
1335
|
return {
|
|
@@ -1322,9 +1352,54 @@ class EdgeModel {
|
|
|
1322
1352
|
return smoothStepPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position, 0);
|
|
1323
1353
|
}
|
|
1324
1354
|
});
|
|
1355
|
+
this.sourceHandle = computed(() => {
|
|
1356
|
+
if (this.edge.sourceHandle) {
|
|
1357
|
+
return (this.source()
|
|
1358
|
+
?.handles()
|
|
1359
|
+
.find((handle) => handle.rawHandle.id === this.edge.sourceHandle) ?? null);
|
|
1360
|
+
}
|
|
1361
|
+
return (this.source()
|
|
1362
|
+
?.handles()
|
|
1363
|
+
.find((handle) => handle.rawHandle.type === 'source') ?? null);
|
|
1364
|
+
});
|
|
1365
|
+
this.targetHandle = computed(() => {
|
|
1366
|
+
if (this.edge.targetHandle) {
|
|
1367
|
+
return (this.target()
|
|
1368
|
+
?.handles()
|
|
1369
|
+
.find((handle) => handle.rawHandle.id === this.edge.targetHandle) ?? null);
|
|
1370
|
+
}
|
|
1371
|
+
return (this.target()
|
|
1372
|
+
?.handles()
|
|
1373
|
+
.find((handle) => handle.rawHandle.type === 'target') ?? null);
|
|
1374
|
+
});
|
|
1375
|
+
/**
|
|
1376
|
+
* TODO: not reactive
|
|
1377
|
+
*/
|
|
1378
|
+
this.markerStartUrl = computed(() => {
|
|
1379
|
+
const marker = this.edge.markers?.start;
|
|
1380
|
+
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1381
|
+
});
|
|
1382
|
+
/**
|
|
1383
|
+
* TODO: not reactive
|
|
1384
|
+
*/
|
|
1385
|
+
this.markerEndUrl = computed(() => {
|
|
1386
|
+
const marker = this.edge.markers?.end;
|
|
1387
|
+
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1388
|
+
});
|
|
1389
|
+
this.context = {
|
|
1390
|
+
$implicit: {
|
|
1391
|
+
// TODO: check if edge could change
|
|
1392
|
+
edge: this.edge,
|
|
1393
|
+
path: computed(() => this.path().path),
|
|
1394
|
+
markerStart: this.markerStartUrl,
|
|
1395
|
+
markerEnd: this.markerEndUrl,
|
|
1396
|
+
selected: this.selected.asReadonly(),
|
|
1397
|
+
},
|
|
1398
|
+
};
|
|
1325
1399
|
this.edgeLabels = {};
|
|
1326
1400
|
this.type = edge.type ?? 'default';
|
|
1327
1401
|
this.curve = edge.curve ?? 'bezier';
|
|
1402
|
+
this.reconnectable = edge.reconnectable ?? false;
|
|
1328
1403
|
if (edge.edgeLabels?.start)
|
|
1329
1404
|
this.edgeLabels.start = new EdgeLabelModel(edge.edgeLabels.start);
|
|
1330
1405
|
if (edge.edgeLabels?.center)
|
|
@@ -1829,6 +1904,7 @@ class EdgeLabelComponent {
|
|
|
1829
1904
|
}), takeUntilDestroyed(this.destroyRef))
|
|
1830
1905
|
.subscribe();
|
|
1831
1906
|
}
|
|
1907
|
+
// TODO: move to model with Contextable interface
|
|
1832
1908
|
getLabelContext() {
|
|
1833
1909
|
return {
|
|
1834
1910
|
$implicit: {
|
|
@@ -1845,76 +1921,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1845
1921
|
args: [{ standalone: true, selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "@if (model(); as model) {\n @if (model.edgeLabel.type === 'html-template' && htmlTemplate()) {\n @if (htmlTemplate(); as htmlTemplate) {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\">\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\" />\n </div>\n </svg:foreignObject>\n }\n }\n\n @if (model.edgeLabel.type === 'default') {\n <svg:foreignObject\n [attr.x]=\"edgeLabelPoint().x\"\n [attr.y]=\"edgeLabelPoint().y\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\">\n <div #edgeLabelWrapper class=\"edge-label-wrapper\" [style]=\"edgeLabelStyle()\">\n {{ model.edgeLabel.text }}\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
|
|
1846
1922
|
}] });
|
|
1847
1923
|
|
|
1848
|
-
class EdgeComponent {
|
|
1849
|
-
constructor() {
|
|
1850
|
-
this.injector = inject(Injector);
|
|
1851
|
-
this.selectionService = inject(SelectionService);
|
|
1852
|
-
this.flowSettingsService = inject(FlowSettingsService);
|
|
1853
|
-
this.model = input.required();
|
|
1854
|
-
this.edgeTemplate = input();
|
|
1855
|
-
this.edgeLabelHtmlTemplate = input();
|
|
1856
|
-
this.markerStartUrl = computed(() => {
|
|
1857
|
-
const marker = this.model().edge.markers?.start;
|
|
1858
|
-
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1859
|
-
});
|
|
1860
|
-
this.markerEndUrl = computed(() => {
|
|
1861
|
-
const marker = this.model().edge.markers?.end;
|
|
1862
|
-
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1863
|
-
});
|
|
1864
|
-
}
|
|
1865
|
-
ngOnInit() {
|
|
1866
|
-
this.edgeContext = {
|
|
1867
|
-
$implicit: {
|
|
1868
|
-
// TODO: check if edge could change
|
|
1869
|
-
edge: this.model().edge,
|
|
1870
|
-
path: computed(() => this.model().path().path),
|
|
1871
|
-
markerStart: this.markerStartUrl,
|
|
1872
|
-
markerEnd: this.markerEndUrl,
|
|
1873
|
-
selected: this.model().selected.asReadonly(),
|
|
1874
|
-
},
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
onEdgeMouseDown() {
|
|
1878
|
-
if (this.flowSettingsService.entitiesSelectable()) {
|
|
1879
|
-
this.selectionService.select(this.model());
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1883
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\"\n (mousedown)=\"onEdgeMouseDown()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1884
|
-
}
|
|
1885
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
|
|
1886
|
-
type: Component,
|
|
1887
|
-
args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1888
|
-
class: 'selectable',
|
|
1889
|
-
}, imports: [NgTemplateOutlet, EdgeLabelComponent], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\"\n (mousedown)=\"onEdgeMouseDown()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
|
|
1890
|
-
}] });
|
|
1891
|
-
|
|
1892
|
-
class HandleService {
|
|
1893
|
-
constructor() {
|
|
1894
|
-
this.node = signal(null);
|
|
1895
|
-
}
|
|
1896
|
-
createHandle(newHandle) {
|
|
1897
|
-
const node = this.node();
|
|
1898
|
-
if (node) {
|
|
1899
|
-
node.handles.update((handles) => [...handles, newHandle]);
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
destroyHandle(handleToDestoy) {
|
|
1903
|
-
const node = this.node();
|
|
1904
|
-
if (node) {
|
|
1905
|
-
node.handles.update((handles) => handles.filter((handle) => handle !== handleToDestoy));
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1909
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService }); }
|
|
1910
|
-
}
|
|
1911
|
-
__decorate([
|
|
1912
|
-
Microtask // TODO fixes rendering of handle for group node
|
|
1913
|
-
], HandleService.prototype, "createHandle", null);
|
|
1914
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, decorators: [{
|
|
1915
|
-
type: Injectable
|
|
1916
|
-
}], propDecorators: { createHandle: [] } });
|
|
1917
|
-
|
|
1918
1924
|
/**
|
|
1919
1925
|
* This function contains a hack-y behavior.
|
|
1920
1926
|
* If the handles are of the same type (source-source or target-target),
|
|
@@ -1960,42 +1966,24 @@ class ConnectionControllerDirective {
|
|
|
1960
1966
|
* @todo add connect event and deprecate onConnect
|
|
1961
1967
|
*/
|
|
1962
1968
|
// eslint-disable-next-line @angular-eslint/no-output-on-prefix
|
|
1963
|
-
this.onConnect = outputFromObservable(toObservable(this.statusService.status).pipe(filter((status) => status.state === 'connection-end'), map((status) =>
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
const adjusted = adjustDirection({
|
|
1970
|
-
source: status.payload.source,
|
|
1971
|
-
sourceHandle: status.payload.sourceHandle,
|
|
1972
|
-
target: status.payload.target,
|
|
1973
|
-
targetHandle: status.payload.targetHandle,
|
|
1974
|
-
});
|
|
1975
|
-
source = adjusted.source;
|
|
1976
|
-
target = adjusted.target;
|
|
1977
|
-
sourceHandle = adjusted.sourceHandle;
|
|
1978
|
-
targetHandle = adjusted.targetHandle;
|
|
1979
|
-
}
|
|
1980
|
-
const sourceId = source.node.id;
|
|
1981
|
-
const targetId = target.node.id;
|
|
1982
|
-
const sourceHandleId = sourceHandle.rawHandle.id;
|
|
1983
|
-
const targetHandleId = targetHandle.rawHandle.id;
|
|
1984
|
-
return {
|
|
1985
|
-
source: sourceId,
|
|
1986
|
-
target: targetId,
|
|
1987
|
-
sourceHandle: sourceHandleId,
|
|
1988
|
-
targetHandle: targetHandleId,
|
|
1989
|
-
};
|
|
1990
|
-
}), tap(() => this.statusService.setIdleStatus()), filter((connection) => this.flowEntitiesService.connection().validator(connection))));
|
|
1969
|
+
this.onConnect = outputFromObservable(toObservable(this.statusService.status).pipe(filter((status) => status.state === 'connection-end'), map((status) => statusToConnection(status, this.isStrictMode())), tap(() => this.statusService.setIdleStatus()), filter((connection) => this.flowEntitiesService.connection().validator(connection))));
|
|
1970
|
+
this.onReconnect = outputFromObservable(toObservable(this.statusService.status).pipe(filter((status) => status.state === 'reconnection-end'), map((status) => {
|
|
1971
|
+
const connection = statusToConnection(status, this.isStrictMode());
|
|
1972
|
+
const oldEdge = status.payload.oldEdge.edge;
|
|
1973
|
+
return { connection, oldEdge };
|
|
1974
|
+
}), tap(() => this.statusService.setIdleStatus()), filter(({ connection }) => this.flowEntitiesService.connection().validator(connection))));
|
|
1991
1975
|
this.isStrictMode = computed(() => this.flowEntitiesService.connection().mode === 'strict');
|
|
1992
1976
|
}
|
|
1993
1977
|
startConnection(handle) {
|
|
1994
1978
|
this.statusService.setConnectionStartStatus(handle.parentNode, handle);
|
|
1995
1979
|
}
|
|
1980
|
+
startReconnection(handle, oldEdge) {
|
|
1981
|
+
this.statusService.setReconnectionStartStatus(handle.parentNode, handle, oldEdge);
|
|
1982
|
+
}
|
|
1996
1983
|
validateConnection(handle) {
|
|
1997
1984
|
const status = this.statusService.status();
|
|
1998
|
-
if (status.state === 'connection-start') {
|
|
1985
|
+
if (status.state === 'connection-start' || status.state === 'reconnection-start') {
|
|
1986
|
+
const isReconnection = status.state === 'reconnection-start';
|
|
1999
1987
|
let source = status.payload.source;
|
|
2000
1988
|
let target = handle.parentNode;
|
|
2001
1989
|
let sourceHandle = status.payload.sourceHandle;
|
|
@@ -2024,89 +2012,97 @@ class ConnectionControllerDirective {
|
|
|
2024
2012
|
handle.state.set(valid ? 'valid' : 'invalid');
|
|
2025
2013
|
// status is about how we draw connection, so we don't need
|
|
2026
2014
|
// swapped diretion here
|
|
2027
|
-
|
|
2015
|
+
isReconnection
|
|
2016
|
+
? this.statusService.setReconnectionValidationStatus(valid, status.payload.source, handle.parentNode, status.payload.sourceHandle, handle, status.payload.oldEdge)
|
|
2017
|
+
: this.statusService.setConnectionValidationStatus(valid, status.payload.source, handle.parentNode, status.payload.sourceHandle, handle);
|
|
2028
2018
|
}
|
|
2029
2019
|
}
|
|
2030
2020
|
resetValidateConnection(targetHandle) {
|
|
2031
2021
|
targetHandle.state.set('idle');
|
|
2032
2022
|
// drop back to start status
|
|
2033
2023
|
const status = this.statusService.status();
|
|
2034
|
-
if (status.state === 'connection-validation') {
|
|
2035
|
-
|
|
2024
|
+
if (status.state === 'connection-validation' || status.state === 'reconnection-validation') {
|
|
2025
|
+
const isReconnection = status.state === 'reconnection-validation';
|
|
2026
|
+
isReconnection
|
|
2027
|
+
? this.statusService.setReconnectionStartStatus(status.payload.source, status.payload.sourceHandle, status.payload.oldEdge)
|
|
2028
|
+
: this.statusService.setConnectionStartStatus(status.payload.source, status.payload.sourceHandle);
|
|
2036
2029
|
}
|
|
2037
2030
|
}
|
|
2038
2031
|
endConnection() {
|
|
2039
2032
|
const status = this.statusService.status();
|
|
2040
|
-
if (status.state === 'connection-validation') {
|
|
2033
|
+
if (status.state === 'connection-validation' || status.state === 'reconnection-validation') {
|
|
2034
|
+
const isReconnection = status.state === 'reconnection-validation';
|
|
2041
2035
|
const source = status.payload.source;
|
|
2042
2036
|
const sourceHandle = status.payload.sourceHandle;
|
|
2043
2037
|
const target = status.payload.target;
|
|
2044
2038
|
const targetHandle = status.payload.targetHandle;
|
|
2045
|
-
|
|
2039
|
+
isReconnection
|
|
2040
|
+
? this.statusService.setReconnectionEndStatus(source, target, sourceHandle, targetHandle, status.payload.oldEdge)
|
|
2041
|
+
: this.statusService.setConnectionEndStatus(source, target, sourceHandle, targetHandle);
|
|
2046
2042
|
}
|
|
2047
2043
|
}
|
|
2048
2044
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2049
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerDirective, isStandalone: true, selector: "[onConnect]", outputs: { onConnect: "onConnect" }, ngImport: i0 }); }
|
|
2045
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerDirective, isStandalone: true, selector: "[onConnect], [onReconnect]", outputs: { onConnect: "onConnect", onReconnect: "onReconnect" }, ngImport: i0 }); }
|
|
2050
2046
|
}
|
|
2051
2047
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, decorators: [{
|
|
2052
2048
|
type: Directive,
|
|
2053
2049
|
args: [{
|
|
2054
|
-
selector: '[onConnect]',
|
|
2050
|
+
selector: '[onConnect], [onReconnect]',
|
|
2055
2051
|
standalone: true,
|
|
2056
2052
|
}]
|
|
2057
2053
|
}] });
|
|
2054
|
+
function statusToConnection(status, isStrictMode) {
|
|
2055
|
+
let source = status.payload.source;
|
|
2056
|
+
let target = status.payload.target;
|
|
2057
|
+
let sourceHandle = status.payload.sourceHandle;
|
|
2058
|
+
let targetHandle = status.payload.targetHandle;
|
|
2059
|
+
if (isStrictMode) {
|
|
2060
|
+
const adjusted = adjustDirection({
|
|
2061
|
+
source: status.payload.source,
|
|
2062
|
+
sourceHandle: status.payload.sourceHandle,
|
|
2063
|
+
target: status.payload.target,
|
|
2064
|
+
targetHandle: status.payload.targetHandle,
|
|
2065
|
+
});
|
|
2066
|
+
source = adjusted.source;
|
|
2067
|
+
target = adjusted.target;
|
|
2068
|
+
sourceHandle = adjusted.sourceHandle;
|
|
2069
|
+
targetHandle = adjusted.targetHandle;
|
|
2070
|
+
}
|
|
2071
|
+
const sourceId = source.node.id;
|
|
2072
|
+
const targetId = target.node.id;
|
|
2073
|
+
const sourceHandleId = sourceHandle.rawHandle.id;
|
|
2074
|
+
const targetHandleId = targetHandle.rawHandle.id;
|
|
2075
|
+
return {
|
|
2076
|
+
source: sourceId,
|
|
2077
|
+
target: targetId,
|
|
2078
|
+
sourceHandle: sourceHandleId,
|
|
2079
|
+
targetHandle: targetHandleId,
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2058
2082
|
|
|
2059
|
-
class
|
|
2083
|
+
class EdgeRenderingService {
|
|
2060
2084
|
constructor() {
|
|
2061
|
-
this.
|
|
2062
|
-
|
|
2085
|
+
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
2086
|
+
this.edges = computed(() => {
|
|
2087
|
+
return this.flowEntitiesService.validEdges().sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
2063
2088
|
});
|
|
2064
|
-
this.
|
|
2065
|
-
|
|
2066
|
-
ngAfterViewInit() {
|
|
2067
|
-
const element = this.handleWrapper.nativeElement;
|
|
2068
|
-
const rect = element.getBBox();
|
|
2069
|
-
const stroke = getChildStrokeWidth(element);
|
|
2070
|
-
this.handleModel().size.set({
|
|
2071
|
-
width: rect.width + stroke,
|
|
2072
|
-
height: rect.height + stroke,
|
|
2089
|
+
this.maxOrder = computed(() => {
|
|
2090
|
+
return Math.max(...this.flowEntitiesService.validEdges().map((n) => n.renderOrder()));
|
|
2073
2091
|
});
|
|
2074
2092
|
}
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
type: Directive,
|
|
2080
|
-
args: [{
|
|
2081
|
-
standalone: true,
|
|
2082
|
-
selector: '[handleSizeController]',
|
|
2083
|
-
}]
|
|
2084
|
-
}] });
|
|
2085
|
-
function getChildStrokeWidth(element) {
|
|
2086
|
-
const child = element.firstElementChild;
|
|
2087
|
-
if (child) {
|
|
2088
|
-
const stroke = getComputedStyle(child).strokeWidth;
|
|
2089
|
-
const strokeAsNumber = Number(stroke.replace('px', ''));
|
|
2090
|
-
if (isNaN(strokeAsNumber)) {
|
|
2091
|
-
return 0;
|
|
2093
|
+
pull(edge) {
|
|
2094
|
+
const isAlreadyOnTop = edge.renderOrder() !== 0 && this.maxOrder() === edge.renderOrder();
|
|
2095
|
+
if (isAlreadyOnTop) {
|
|
2096
|
+
return;
|
|
2092
2097
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
return 0;
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
class DefaultNodeComponent {
|
|
2099
|
-
constructor() {
|
|
2100
|
-
this.selected = input(false);
|
|
2098
|
+
// pull node
|
|
2099
|
+
edge.renderOrder.set(this.maxOrder() + 1);
|
|
2101
2100
|
}
|
|
2102
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
2103
|
-
static { this.ɵ
|
|
2101
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2102
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeRenderingService }); }
|
|
2104
2103
|
}
|
|
2105
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type:
|
|
2106
|
-
type:
|
|
2107
|
-
args: [{ standalone: true, selector: 'default-node', host: {
|
|
2108
|
-
'[class.selected]': 'selected()',
|
|
2109
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
|
|
2104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeRenderingService, decorators: [{
|
|
2105
|
+
type: Injectable
|
|
2110
2106
|
}] });
|
|
2111
2107
|
|
|
2112
2108
|
function isTouchEvent(event) {
|
|
@@ -2191,6 +2187,129 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2191
2187
|
args: ['mouseout', ['$event']]
|
|
2192
2188
|
}] } });
|
|
2193
2189
|
|
|
2190
|
+
class EdgeComponent {
|
|
2191
|
+
constructor() {
|
|
2192
|
+
this.injector = inject(Injector);
|
|
2193
|
+
this.selectionService = inject(SelectionService);
|
|
2194
|
+
this.flowSettingsService = inject(FlowSettingsService);
|
|
2195
|
+
this.flowStatusService = inject(FlowStatusService);
|
|
2196
|
+
this.edgeRenderingService = inject(EdgeRenderingService);
|
|
2197
|
+
// TODO remove dependency from this directive
|
|
2198
|
+
this.connectionController = inject(ConnectionControllerDirective, { optional: true });
|
|
2199
|
+
this.model = input.required();
|
|
2200
|
+
this.edgeTemplate = input();
|
|
2201
|
+
this.edgeLabelHtmlTemplate = input();
|
|
2202
|
+
this.isReconnecting = computed(() => {
|
|
2203
|
+
const status = this.flowStatusService.status();
|
|
2204
|
+
const isReconnecting = status.state === 'reconnection-start' || status.state === 'reconnection-validation';
|
|
2205
|
+
return isReconnecting && status.payload.oldEdge === this.model();
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
select() {
|
|
2209
|
+
if (this.flowSettingsService.entitiesSelectable()) {
|
|
2210
|
+
this.selectionService.select(this.model());
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
pull() {
|
|
2214
|
+
if (this.flowSettingsService.elevateEdgesOnSelect()) {
|
|
2215
|
+
this.edgeRenderingService.pull(this.model());
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
startReconnection(event, handle) {
|
|
2219
|
+
// ignore drag by stopping propagation
|
|
2220
|
+
event.stopPropagation();
|
|
2221
|
+
this.connectionController?.startReconnection(handle, this.model());
|
|
2222
|
+
}
|
|
2223
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2224
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.visibility": "isReconnecting() ? \"hidden\" : \"visible\"" }, classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerStartUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2225
|
+
}
|
|
2226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
|
|
2227
|
+
type: Component,
|
|
2228
|
+
args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2229
|
+
class: 'selectable',
|
|
2230
|
+
'[style.visibility]': 'isReconnecting() ? "hidden" : "visible"',
|
|
2231
|
+
}, imports: [NgTemplateOutlet, EdgeLabelComponent, PointerDirective], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerStartUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"] }]
|
|
2232
|
+
}] });
|
|
2233
|
+
|
|
2234
|
+
class HandleService {
|
|
2235
|
+
constructor() {
|
|
2236
|
+
this.node = signal(null);
|
|
2237
|
+
}
|
|
2238
|
+
createHandle(newHandle) {
|
|
2239
|
+
const node = this.node();
|
|
2240
|
+
if (node) {
|
|
2241
|
+
node.handles.update((handles) => [...handles, newHandle]);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
destroyHandle(handleToDestoy) {
|
|
2245
|
+
const node = this.node();
|
|
2246
|
+
if (node) {
|
|
2247
|
+
node.handles.update((handles) => handles.filter((handle) => handle !== handleToDestoy));
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2251
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService }); }
|
|
2252
|
+
}
|
|
2253
|
+
__decorate([
|
|
2254
|
+
Microtask // TODO fixes rendering of handle for group node
|
|
2255
|
+
], HandleService.prototype, "createHandle", null);
|
|
2256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, decorators: [{
|
|
2257
|
+
type: Injectable
|
|
2258
|
+
}], propDecorators: { createHandle: [] } });
|
|
2259
|
+
|
|
2260
|
+
class HandleSizeControllerDirective {
|
|
2261
|
+
constructor() {
|
|
2262
|
+
this.handleModel = input.required({
|
|
2263
|
+
alias: 'handleSizeController',
|
|
2264
|
+
});
|
|
2265
|
+
this.handleWrapper = inject(ElementRef);
|
|
2266
|
+
}
|
|
2267
|
+
ngAfterViewInit() {
|
|
2268
|
+
const element = this.handleWrapper.nativeElement;
|
|
2269
|
+
const rect = element.getBBox();
|
|
2270
|
+
const stroke = getChildStrokeWidth(element);
|
|
2271
|
+
this.handleModel().size.set({
|
|
2272
|
+
width: rect.width + stroke,
|
|
2273
|
+
height: rect.height + stroke,
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2277
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: HandleSizeControllerDirective, isStandalone: true, selector: "[handleSizeController]", inputs: { handleModel: { classPropertyName: "handleModel", publicName: "handleSizeController", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
2278
|
+
}
|
|
2279
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
|
|
2280
|
+
type: Directive,
|
|
2281
|
+
args: [{
|
|
2282
|
+
standalone: true,
|
|
2283
|
+
selector: '[handleSizeController]',
|
|
2284
|
+
}]
|
|
2285
|
+
}] });
|
|
2286
|
+
function getChildStrokeWidth(element) {
|
|
2287
|
+
const child = element.firstElementChild;
|
|
2288
|
+
if (child) {
|
|
2289
|
+
const stroke = getComputedStyle(child).strokeWidth;
|
|
2290
|
+
const strokeAsNumber = Number(stroke.replace('px', ''));
|
|
2291
|
+
if (isNaN(strokeAsNumber)) {
|
|
2292
|
+
return 0;
|
|
2293
|
+
}
|
|
2294
|
+
return strokeAsNumber;
|
|
2295
|
+
}
|
|
2296
|
+
return 0;
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
class DefaultNodeComponent {
|
|
2300
|
+
constructor() {
|
|
2301
|
+
this.selected = input(false);
|
|
2302
|
+
}
|
|
2303
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2304
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: DefaultNodeComponent, isStandalone: true, selector: "default-node", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.selected": "selected()" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2305
|
+
}
|
|
2306
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
|
|
2307
|
+
type: Component,
|
|
2308
|
+
args: [{ standalone: true, selector: 'default-node', host: {
|
|
2309
|
+
'[class.selected]': 'selected()',
|
|
2310
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: [":host{border:1.5px solid #1b262c;border-radius:5px;display:flex;align-items:center;justify-content:center;color:#000;background-color:#fff}:host(.selected){border-width:2px}\n"] }]
|
|
2311
|
+
}] });
|
|
2312
|
+
|
|
2194
2313
|
class ResizableComponent {
|
|
2195
2314
|
get model() {
|
|
2196
2315
|
return this.nodeAccessor.model();
|
|
@@ -2589,7 +2708,9 @@ class NodeComponent {
|
|
|
2589
2708
|
this.nodeTemplate = input();
|
|
2590
2709
|
this.groupNodeTemplate = input();
|
|
2591
2710
|
this.showMagnet = computed(() => this.flowStatusService.status().state === 'connection-start' ||
|
|
2592
|
-
this.flowStatusService.status().state === 'connection-validation'
|
|
2711
|
+
this.flowStatusService.status().state === 'connection-validation' ||
|
|
2712
|
+
this.flowStatusService.status().state === 'reconnection-start' ||
|
|
2713
|
+
this.flowStatusService.status().state === 'reconnection-validation');
|
|
2593
2714
|
this.toolbar = computed(() => this.overlaysService.nodeToolbars().get(this.model()));
|
|
2594
2715
|
}
|
|
2595
2716
|
ngOnInit() {
|
|
@@ -2632,7 +2753,7 @@ class NodeComponent {
|
|
|
2632
2753
|
}
|
|
2633
2754
|
}
|
|
2634
2755
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2635
|
-
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 }, 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().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Template node -->\n@if (model().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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]=\"
|
|
2756
|
+
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 }, 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().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Template node -->\n@if (model().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Component node -->\n@if (model().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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(model().node.type)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (model().node.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 (pointerStart)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().node.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (pointerStart)=\"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) {\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) {\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@if (toolbar(); as 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"] }, { 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]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2636
2757
|
}
|
|
2637
2758
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, decorators: [{
|
|
2638
2759
|
type: Component,
|
|
@@ -2648,7 +2769,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2648
2769
|
HandleSizeControllerDirective,
|
|
2649
2770
|
NodeHandlesControllerDirective,
|
|
2650
2771
|
NodeResizeControllerDirective,
|
|
2651
|
-
], template: "<!-- Default node -->\n@if (model().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Template node -->\n@if (model().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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]=\"
|
|
2772
|
+
], template: "<!-- Default node -->\n@if (model().node.type === 'default') {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Template node -->\n@if (model().node.type === 'html-template' && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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<!-- Component node -->\n@if (model().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"model().foWidth()\"\n [attr.height]=\"model().foHeight()\"\n (pointerStart)=\"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(model().node.type)\"\n [ngComponentOutletInputs]=\"model().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\" />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (model().node.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 (pointerStart)=\"pullNode(); selectNode()\" />\n}\n\n<!-- Template group node -->\n@if (model().node.type === 'template-group' && groupNodeTemplate()) {\n <svg:g class=\"selectable\" nodeHandlesController (pointerStart)=\"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) {\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) {\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@if (toolbar(); as 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"] }]
|
|
2652
2773
|
}] });
|
|
2653
2774
|
|
|
2654
2775
|
class ConnectionComponent {
|
|
@@ -2659,7 +2780,7 @@ class ConnectionComponent {
|
|
|
2659
2780
|
this.spacePointContext = inject(SpacePointContextDirective);
|
|
2660
2781
|
this.path = computed(() => {
|
|
2661
2782
|
const status = this.flowStatusService.status();
|
|
2662
|
-
if (status.state === 'connection-start') {
|
|
2783
|
+
if (status.state === 'connection-start' || status.state === 'reconnection-start') {
|
|
2663
2784
|
const sourceHandle = status.payload.sourceHandle;
|
|
2664
2785
|
const sourcePoint = sourceHandle.pointAbsolute();
|
|
2665
2786
|
const sourcePosition = sourceHandle.rawHandle.position;
|
|
@@ -2676,7 +2797,7 @@ class ConnectionComponent {
|
|
|
2676
2797
|
return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
|
|
2677
2798
|
}
|
|
2678
2799
|
}
|
|
2679
|
-
if (status.state === 'connection-validation') {
|
|
2800
|
+
if (status.state === 'connection-validation' || status.state === 'reconnection-validation') {
|
|
2680
2801
|
const sourceHandle = status.payload.sourceHandle;
|
|
2681
2802
|
const sourcePoint = sourceHandle.pointAbsolute();
|
|
2682
2803
|
const sourcePosition = sourceHandle.rawHandle.position;
|
|
@@ -2710,6 +2831,7 @@ class ConnectionComponent {
|
|
|
2710
2831
|
});
|
|
2711
2832
|
this.defaultColor = 'rgb(177, 177, 183)';
|
|
2712
2833
|
}
|
|
2834
|
+
// TODO: move context to model
|
|
2713
2835
|
getContext() {
|
|
2714
2836
|
return {
|
|
2715
2837
|
$implicit: {
|
|
@@ -2950,7 +3072,7 @@ class RootSvgContextDirective {
|
|
|
2950
3072
|
// TODO: check for multiple instances on page
|
|
2951
3073
|
resetConnection() {
|
|
2952
3074
|
const status = this.flowStatusService.status();
|
|
2953
|
-
if (status.state === 'connection-start') {
|
|
3075
|
+
if (status.state === 'connection-start' || status.state === 'reconnection-start') {
|
|
2954
3076
|
this.flowStatusService.setIdleStatus();
|
|
2955
3077
|
}
|
|
2956
3078
|
}
|
|
@@ -3016,6 +3138,7 @@ class VflowComponent {
|
|
|
3016
3138
|
this.nodesChangeService = inject(NodesChangeService);
|
|
3017
3139
|
this.edgesChangeService = inject(EdgeChangesService);
|
|
3018
3140
|
this.nodeRenderingService = inject(NodeRenderingService);
|
|
3141
|
+
this.edgeRenderingService = inject(EdgeRenderingService);
|
|
3019
3142
|
this.flowSettingsService = inject(FlowSettingsService);
|
|
3020
3143
|
this.componentEventBusService = inject(ComponentEventBusService);
|
|
3021
3144
|
this.keyboardService = inject(KeyboardService);
|
|
@@ -3026,7 +3149,7 @@ class VflowComponent {
|
|
|
3026
3149
|
this.nodeModels = computed(() => this.nodeRenderingService.nodes());
|
|
3027
3150
|
this.groups = computed(() => this.nodeRenderingService.groups());
|
|
3028
3151
|
this.nonGroups = computed(() => this.nodeRenderingService.nonGroups());
|
|
3029
|
-
this.edgeModels = computed(() => this.
|
|
3152
|
+
this.edgeModels = computed(() => this.edgeRenderingService.edges());
|
|
3030
3153
|
// #endregion
|
|
3031
3154
|
// #region OUTPUTS
|
|
3032
3155
|
/**
|
|
@@ -3144,6 +3267,12 @@ class VflowComponent {
|
|
|
3144
3267
|
set elevateNodesOnSelect(value) {
|
|
3145
3268
|
this.flowSettingsService.elevateNodesOnSelect.set(value);
|
|
3146
3269
|
}
|
|
3270
|
+
/**
|
|
3271
|
+
* Raizing z-index for selected edge
|
|
3272
|
+
*/
|
|
3273
|
+
set elevateEdgesOnSelect(value) {
|
|
3274
|
+
this.flowSettingsService.elevateEdgesOnSelect.set(value);
|
|
3275
|
+
}
|
|
3147
3276
|
// #endregion
|
|
3148
3277
|
// #region MAIN_INPUTS
|
|
3149
3278
|
/**
|
|
@@ -3245,7 +3374,7 @@ class VflowComponent {
|
|
|
3245
3374
|
});
|
|
3246
3375
|
}
|
|
3247
3376
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3248
|
-
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: true, 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 }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
3377
|
+
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: true, 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 }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
3249
3378
|
DraggableService,
|
|
3250
3379
|
ViewportService,
|
|
3251
3380
|
FlowStatusService,
|
|
@@ -3253,6 +3382,7 @@ class VflowComponent {
|
|
|
3253
3382
|
NodesChangeService,
|
|
3254
3383
|
EdgeChangesService,
|
|
3255
3384
|
NodeRenderingService,
|
|
3385
|
+
EdgeRenderingService,
|
|
3256
3386
|
SelectionService,
|
|
3257
3387
|
FlowSettingsService,
|
|
3258
3388
|
ComponentEventBusService,
|
|
@@ -3270,6 +3400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3270
3400
|
NodesChangeService,
|
|
3271
3401
|
EdgeChangesService,
|
|
3272
3402
|
NodeRenderingService,
|
|
3403
|
+
EdgeRenderingService,
|
|
3273
3404
|
SelectionService,
|
|
3274
3405
|
FlowSettingsService,
|
|
3275
3406
|
ComponentEventBusService,
|
|
@@ -3310,6 +3441,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3310
3441
|
type: Input
|
|
3311
3442
|
}], elevateNodesOnSelect: [{
|
|
3312
3443
|
type: Input
|
|
3444
|
+
}], elevateEdgesOnSelect: [{
|
|
3445
|
+
type: Input
|
|
3313
3446
|
}], nodes: [{
|
|
3314
3447
|
type: Input,
|
|
3315
3448
|
args: [{ required: true }]
|
|
@@ -3348,8 +3481,12 @@ class SelectableDirective {
|
|
|
3348
3481
|
this.selectionService = inject(SelectionService);
|
|
3349
3482
|
this.parentEdge = inject(EdgeComponent, { optional: true });
|
|
3350
3483
|
this.parentNode = inject(NodeComponent, { optional: true });
|
|
3484
|
+
this.host = inject(ElementRef);
|
|
3485
|
+
this.selectOnEvent = this.getEvent$()
|
|
3486
|
+
.pipe(tap(() => this.select()), takeUntilDestroyed())
|
|
3487
|
+
.subscribe();
|
|
3351
3488
|
}
|
|
3352
|
-
|
|
3489
|
+
select() {
|
|
3353
3490
|
const entity = this.entity();
|
|
3354
3491
|
if (entity && this.flowSettingsService.entitiesSelectable()) {
|
|
3355
3492
|
this.selectionService.select(entity);
|
|
@@ -3364,8 +3501,11 @@ class SelectableDirective {
|
|
|
3364
3501
|
}
|
|
3365
3502
|
return null;
|
|
3366
3503
|
}
|
|
3504
|
+
getEvent$() {
|
|
3505
|
+
return merge(fromEvent(this.host.nativeElement, 'mousedown'), fromEvent(this.host.nativeElement, 'touchstart'));
|
|
3506
|
+
}
|
|
3367
3507
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3368
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SelectableDirective, isStandalone: true, selector: "[selectable]",
|
|
3508
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SelectableDirective, isStandalone: true, selector: "[selectable]", ngImport: i0 }); }
|
|
3369
3509
|
}
|
|
3370
3510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, decorators: [{
|
|
3371
3511
|
type: Directive,
|
|
@@ -3373,13 +3513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3373
3513
|
standalone: true,
|
|
3374
3514
|
selector: '[selectable]',
|
|
3375
3515
|
}]
|
|
3376
|
-
}]
|
|
3377
|
-
type: HostListener,
|
|
3378
|
-
args: ['mousedown']
|
|
3379
|
-
}, {
|
|
3380
|
-
type: HostListener,
|
|
3381
|
-
args: ['touchstart']
|
|
3382
|
-
}] } });
|
|
3516
|
+
}] });
|
|
3383
3517
|
|
|
3384
3518
|
class MinimapModel {
|
|
3385
3519
|
constructor() {
|
|
@@ -3585,6 +3719,7 @@ const Vflow = [
|
|
|
3585
3719
|
SelectableDirective,
|
|
3586
3720
|
MiniMapComponent,
|
|
3587
3721
|
NodeToolbarComponent,
|
|
3722
|
+
CustomTemplateEdgeComponent,
|
|
3588
3723
|
DragHandleDirective,
|
|
3589
3724
|
ConnectionControllerDirective,
|
|
3590
3725
|
NodeHtmlTemplateDirective,
|
|
@@ -3595,6 +3730,30 @@ const Vflow = [
|
|
|
3595
3730
|
HandleTemplateDirective,
|
|
3596
3731
|
];
|
|
3597
3732
|
|
|
3733
|
+
class CustomTemplateEdgeComponent {
|
|
3734
|
+
constructor() {
|
|
3735
|
+
this.edge = inject(EdgeComponent);
|
|
3736
|
+
this.flowSettingsService = inject(FlowSettingsService);
|
|
3737
|
+
this.edgeRenderingService = inject(EdgeRenderingService);
|
|
3738
|
+
this.model = this.edge.model();
|
|
3739
|
+
this.context = this.model.context.$implicit;
|
|
3740
|
+
}
|
|
3741
|
+
pull() {
|
|
3742
|
+
if (this.flowSettingsService.elevateEdgesOnSelect()) {
|
|
3743
|
+
this.edgeRenderingService.pull(this.model);
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomTemplateEdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3747
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CustomTemplateEdgeComponent, isStandalone: true, selector: "g[customTemplateEdge]", host: { listeners: { "mousedown": "pull()", "touchstart": "pull()" } }, ngImport: i0, template: "<ng-content />\n\n<svg:path #interactiveEdge class=\"interactive-edge\" [attr.d]=\"context.path()\" />\n", styles: [".interactive-edge{fill:none;stroke-width:20;stroke:transparent}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3748
|
+
}
|
|
3749
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomTemplateEdgeComponent, decorators: [{
|
|
3750
|
+
type: Component,
|
|
3751
|
+
args: [{ selector: 'g[customTemplateEdge]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, host: {
|
|
3752
|
+
'(mousedown)': 'pull()',
|
|
3753
|
+
'(touchstart)': 'pull()',
|
|
3754
|
+
}, template: "<ng-content />\n\n<svg:path #interactiveEdge class=\"interactive-edge\" [attr.d]=\"context.path()\" />\n", styles: [".interactive-edge{fill:none;stroke-width:20;stroke:transparent}\n"] }]
|
|
3755
|
+
}] });
|
|
3756
|
+
|
|
3598
3757
|
const mockModel = () => new NodeModel({ id: 'mock', type: 'default', point: { x: 0, y: 0 } });
|
|
3599
3758
|
function provideCustomNodeMocks() {
|
|
3600
3759
|
return [
|
|
@@ -3794,7 +3953,7 @@ class VflowMockComponent {
|
|
|
3794
3953
|
return signal(value);
|
|
3795
3954
|
}
|
|
3796
3955
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowMockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3797
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowMockComponent, isStandalone: true, selector: "vflow", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null }, 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: true, 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 } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateMockDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3956
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowMockComponent, isStandalone: true, selector: "vflow", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null }, 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: true, 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 } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateMockDirective, descendants: true, isSignal: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateMockDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3798
3957
|
<ng-content />
|
|
3799
3958
|
|
|
3800
3959
|
@for (node of nodes; track $index) {
|
|
@@ -4005,6 +4164,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
4005
4164
|
type: Input
|
|
4006
4165
|
}], elevateNodesOnSelect: [{
|
|
4007
4166
|
type: Input
|
|
4167
|
+
}], elevateEdgesOnSelect: [{
|
|
4168
|
+
type: Input
|
|
4008
4169
|
}] } });
|
|
4009
4170
|
|
|
4010
4171
|
class HandleMockComponent {
|
|
@@ -4099,17 +4260,21 @@ class ConnectionControllerMockDirective {
|
|
|
4099
4260
|
constructor() {
|
|
4100
4261
|
// eslint-disable-next-line @angular-eslint/no-output-on-prefix
|
|
4101
4262
|
this.onConnect = output();
|
|
4263
|
+
// eslint-disable-next-line @angular-eslint/no-output-on-prefix
|
|
4264
|
+
this.onReconnect = output();
|
|
4102
4265
|
}
|
|
4103
4266
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4104
4267
|
startConnection(handle) { }
|
|
4105
4268
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4269
|
+
startReconnection(handle) { }
|
|
4270
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4106
4271
|
validateConnection(handle) { }
|
|
4107
4272
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4108
4273
|
resetValidateConnection(targetHandle) { }
|
|
4109
4274
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4110
4275
|
endConnection() { }
|
|
4111
4276
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerMockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4112
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerMockDirective, isStandalone: true, selector: "[onConnect]", outputs: { onConnect: "onConnect" }, ngImport: i0 }); }
|
|
4277
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerMockDirective, isStandalone: true, selector: "[onConnect]", outputs: { onConnect: "onConnect", onReconnect: "onReconnect" }, ngImport: i0 }); }
|
|
4113
4278
|
}
|
|
4114
4279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerMockDirective, decorators: [{
|
|
4115
4280
|
type: Directive,
|
|
@@ -4160,5 +4325,5 @@ const VflowMocks = [
|
|
|
4160
4325
|
* Generated bundle index. Do not edit.
|
|
4161
4326
|
*/
|
|
4162
4327
|
|
|
4163
|
-
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionControllerMockDirective, ConnectionTemplateDirective, ConnectionTemplateMockDirective, CustomDynamicNodeComponent, CustomNodeComponent, DragHandleDirective, DragHandleMockDirective, EdgeLabelHtmlTemplateDirective, EdgeLabelHtmlTemplateMockDirective, EdgeTemplateDirective, EdgeTemplateMockDirective, GroupNodeTemplateDirective, GroupNodeTemplateMockDirective, HandleComponent, HandleMockComponent, HandleTemplateDirective, HandleTemplateMockDirective, MiniMapComponent, MiniMapMockComponent, NodeHtmlTemplateDirective, NodeHtmlTemplateMockDirective, NodeToolbarComponent, NodeToolbarMockComponent, NodeToolbarWrapperDirective, ResizableComponent, ResizableMockComponent, SelectableDirective, SelectableMockDirective, Vflow, VflowComponent, VflowMockComponent, VflowMocks, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
|
|
4328
|
+
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionControllerMockDirective, ConnectionTemplateDirective, ConnectionTemplateMockDirective, CustomDynamicNodeComponent, CustomNodeComponent, CustomTemplateEdgeComponent, DragHandleDirective, DragHandleMockDirective, EdgeLabelHtmlTemplateDirective, EdgeLabelHtmlTemplateMockDirective, EdgeTemplateDirective, EdgeTemplateMockDirective, GroupNodeTemplateDirective, GroupNodeTemplateMockDirective, HandleComponent, HandleMockComponent, HandleTemplateDirective, HandleTemplateMockDirective, MiniMapComponent, MiniMapMockComponent, NodeHtmlTemplateDirective, NodeHtmlTemplateMockDirective, NodeToolbarComponent, NodeToolbarMockComponent, NodeToolbarWrapperDirective, ResizableComponent, ResizableMockComponent, SelectableDirective, SelectableMockDirective, Vflow, VflowComponent, VflowMockComponent, VflowMocks, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
|
|
4164
4329
|
//# sourceMappingURL=ngx-vflow.mjs.map
|