ngx-vflow 0.15.0 → 1.0.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/README.md +8 -1
- package/esm2022/lib/vflow/components/background/background.component.mjs +75 -8
- package/esm2022/lib/vflow/components/connection/connection.component.mjs +67 -49
- package/esm2022/lib/vflow/components/custom-node-base/custom-node-base.component.mjs +32 -25
- package/esm2022/lib/vflow/components/default-node/default-node.component.mjs +9 -11
- package/esm2022/lib/vflow/components/defs/defs.component.mjs +9 -12
- package/esm2022/lib/vflow/components/edge/edge.component.mjs +21 -24
- package/esm2022/lib/vflow/components/edge-label/edge-label.component.mjs +26 -31
- package/esm2022/lib/vflow/components/node/node.component.mjs +54 -50
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +95 -90
- package/esm2022/lib/vflow/decorators/run-in-injection-context.decorator.mjs +1 -1
- package/esm2022/lib/vflow/directives/changes-controller.directive.mjs +41 -125
- package/esm2022/lib/vflow/directives/connection-controller.directive.mjs +16 -16
- package/esm2022/lib/vflow/directives/drag-handle.directive.mjs +7 -6
- package/esm2022/lib/vflow/directives/flow-size-controller.directive.mjs +7 -6
- package/esm2022/lib/vflow/directives/handle-size-controller.directive.mjs +15 -12
- package/esm2022/lib/vflow/directives/map-context.directive.mjs +8 -5
- package/esm2022/lib/vflow/directives/pointer.directive.mjs +18 -19
- package/esm2022/lib/vflow/directives/reference.directive.mjs +6 -5
- package/esm2022/lib/vflow/directives/root-pointer.directive.mjs +8 -5
- package/esm2022/lib/vflow/directives/root-svg-context.directive.mjs +8 -5
- package/esm2022/lib/vflow/directives/selectable.directive.mjs +10 -7
- package/esm2022/lib/vflow/directives/space-point-context.directive.mjs +8 -5
- package/esm2022/lib/vflow/directives/template.directive.mjs +43 -25
- package/esm2022/lib/vflow/interfaces/component-node-event.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/edge.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/node.interface.mjs +1 -1
- package/esm2022/lib/vflow/interfaces/optimization.interface.mjs +1 -1
- package/esm2022/lib/vflow/math/edge-path/bezier-path.mjs +1 -1
- package/esm2022/lib/vflow/math/edge-path/smooth-step-path.mjs +170 -0
- package/esm2022/lib/vflow/models/connection.model.mjs +1 -1
- package/esm2022/lib/vflow/models/edge.model.mjs +6 -1
- package/esm2022/lib/vflow/models/handle.model.mjs +2 -2
- package/esm2022/lib/vflow/models/node.model.mjs +4 -10
- package/esm2022/lib/vflow/models/toolbar.model.mjs +1 -1
- package/esm2022/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.mjs +16 -10
- package/esm2022/lib/vflow/public-components/custom-node/custom-node.component.mjs +15 -10
- package/esm2022/lib/vflow/public-components/handle/handle.component.mjs +52 -0
- package/esm2022/lib/vflow/public-components/minimap/minimap.component.mjs +42 -45
- package/esm2022/lib/vflow/public-components/node-toolbar/node-toolbar.component.mjs +24 -27
- package/esm2022/lib/vflow/public-components/resizable/resizable.component.mjs +60 -45
- package/esm2022/lib/vflow/services/component-event-bus.service.mjs +3 -3
- package/esm2022/lib/vflow/services/draggable.service.mjs +4 -4
- package/esm2022/lib/vflow/services/edge-changes.service.mjs +3 -3
- package/esm2022/lib/vflow/services/flow-entities.service.mjs +4 -4
- package/esm2022/lib/vflow/services/flow-settings.service.mjs +4 -10
- package/esm2022/lib/vflow/services/flow-status.service.mjs +4 -4
- package/esm2022/lib/vflow/services/handle.service.mjs +4 -4
- package/esm2022/lib/vflow/services/keyboard.service.mjs +5 -5
- package/esm2022/lib/vflow/services/node-accessor.service.mjs +3 -3
- package/esm2022/lib/vflow/services/node-changes.service.mjs +3 -3
- package/esm2022/lib/vflow/services/node-rendering.service.mjs +11 -4
- package/esm2022/lib/vflow/services/overlays.service.mjs +3 -3
- package/esm2022/lib/vflow/services/selection.service.mjs +4 -4
- package/esm2022/lib/vflow/services/viewport.service.mjs +3 -3
- package/esm2022/lib/vflow/types/background.type.mjs +1 -1
- package/esm2022/lib/vflow/utils/adjust-direction.mjs +1 -1
- package/esm2022/lib/vflow/utils/get-os.mjs +1 -1
- package/esm2022/lib/vflow/utils/is-group-node.mjs +4 -0
- package/esm2022/lib/vflow/utils/nodes.mjs +1 -1
- package/esm2022/lib/vflow/vflow.mjs +24 -0
- package/esm2022/public-api.mjs +4 -5
- package/fesm2022/ngx-vflow.mjs +1160 -1005
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/background/background.component.d.ts +14 -1
- package/lib/vflow/components/connection/connection.component.d.ts +3 -3
- package/lib/vflow/components/custom-node-base/custom-node-base.component.d.ts +4 -9
- package/lib/vflow/components/default-node/default-node.component.d.ts +2 -2
- package/lib/vflow/components/defs/defs.component.d.ts +2 -2
- package/lib/vflow/components/edge/edge.component.d.ts +7 -7
- package/lib/vflow/components/edge-label/edge-label.component.d.ts +9 -8
- package/lib/vflow/components/node/node.component.d.ts +5 -6
- package/lib/vflow/components/vflow/vflow.component.d.ts +19 -27
- package/lib/vflow/directives/changes-controller.directive.d.ts +29 -30
- package/lib/vflow/directives/connection-controller.directive.d.ts +1 -2
- package/lib/vflow/directives/drag-handle.directive.d.ts +1 -1
- package/lib/vflow/directives/flow-size-controller.directive.d.ts +1 -1
- package/lib/vflow/directives/handle-size-controller.directive.d.ts +2 -2
- package/lib/vflow/directives/map-context.directive.d.ts +1 -1
- package/lib/vflow/directives/pointer.directive.d.ts +9 -6
- package/lib/vflow/directives/reference.directive.d.ts +1 -1
- package/lib/vflow/directives/root-pointer.directive.d.ts +1 -1
- package/lib/vflow/directives/root-svg-context.directive.d.ts +1 -1
- package/lib/vflow/directives/selectable.directive.d.ts +1 -1
- package/lib/vflow/directives/space-point-context.directive.d.ts +1 -1
- package/lib/vflow/directives/template.directive.d.ts +6 -6
- package/lib/vflow/interfaces/component-node-event.interface.d.ts +3 -3
- package/lib/vflow/interfaces/edge.interface.d.ts +1 -1
- package/lib/vflow/interfaces/node.interface.d.ts +14 -14
- package/lib/vflow/interfaces/optimization.interface.d.ts +7 -1
- package/lib/vflow/math/edge-path/smooth-step-path.d.ts +5 -0
- package/lib/vflow/models/edge.model.d.ts +1 -17
- package/lib/vflow/models/handle.model.d.ts +4 -4
- package/lib/vflow/models/node.model.d.ts +2 -5
- package/lib/vflow/public-components/custom-dynamic-node/custom-dynamic-node.component.d.ts +3 -3
- package/lib/vflow/public-components/custom-node/custom-node.component.d.ts +3 -3
- package/lib/vflow/{components → public-components}/handle/handle.component.d.ts +5 -5
- package/lib/vflow/public-components/minimap/minimap.component.d.ts +8 -10
- package/lib/vflow/public-components/node-toolbar/node-toolbar.component.d.ts +6 -5
- package/lib/vflow/public-components/resizable/resizable.component.d.ts +5 -4
- package/lib/vflow/services/flow-settings.service.d.ts +0 -7
- package/lib/vflow/services/node-rendering.service.d.ts +2 -0
- package/lib/vflow/types/background.type.d.ts +24 -1
- package/lib/vflow/utils/is-group-node.d.ts +2 -0
- package/lib/vflow/utils/reference-keeper.d.ts +1 -1
- package/lib/vflow/vflow.d.ts +9 -0
- package/package.json +3 -3
- package/public-api.d.ts +2 -3
- package/esm2022/lib/vflow/components/handle/handle.component.mjs +0 -49
- package/esm2022/lib/vflow/interfaces/handle-positions.interface.mjs +0 -2
- package/esm2022/lib/vflow/vflow.module.mjs +0 -121
- package/lib/vflow/interfaces/handle-positions.interface.d.ts +0 -5
- package/lib/vflow/vflow.module.d.ts +0 -30
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import * as i1 from '@angular/common';
|
|
2
|
-
import { NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
|
|
3
1
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef,
|
|
2
|
+
import { signal, computed, Injectable, inject, ElementRef, Directive, effect, untracked, TemplateRef, output, DestroyRef, EventEmitter, OutputEmitterRef, input, viewChild, Component, ChangeDetectionStrategy, Injector, runInInjectionContext, HostListener, NgZone, contentChild, Input, forwardRef } from '@angular/core';
|
|
5
3
|
import { select } from 'd3-selection';
|
|
6
4
|
import { zoomIdentity, zoom } from 'd3-zoom';
|
|
7
|
-
import { switchMap, merge, fromEvent, tap, Subject, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share,
|
|
8
|
-
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { switchMap, merge, fromEvent, tap, Subject, Observable, observeOn, animationFrameScheduler, skip, map, pairwise, filter, distinctUntilChanged, asyncScheduler, zip, share, startWith, of } from 'rxjs';
|
|
6
|
+
import { toObservable, takeUntilDestroyed, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
9
7
|
import { drag } from 'd3-drag';
|
|
10
8
|
import { __decorate } from 'tslib';
|
|
9
|
+
import { NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
|
|
11
10
|
|
|
12
11
|
function getNodesBounds(nodes) {
|
|
13
12
|
if (nodes.length === 0) {
|
|
@@ -129,10 +128,10 @@ class FlowEntitiesService {
|
|
|
129
128
|
getDetachedEdges() {
|
|
130
129
|
return this.edges().filter(e => e.detached());
|
|
131
130
|
}
|
|
132
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
133
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
131
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
132
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService }); }
|
|
134
133
|
}
|
|
135
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
134
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowEntitiesService, decorators: [{
|
|
136
135
|
type: Injectable
|
|
137
136
|
}] });
|
|
138
137
|
|
|
@@ -154,12 +153,6 @@ function clamp(value, min = 0, max = 1) {
|
|
|
154
153
|
class FlowSettingsService {
|
|
155
154
|
constructor() {
|
|
156
155
|
this.entitiesSelectable = signal(true);
|
|
157
|
-
/**
|
|
158
|
-
* Global setting with handle positions. Nodes derive this value
|
|
159
|
-
*
|
|
160
|
-
* @deprecated
|
|
161
|
-
*/
|
|
162
|
-
this.handlePositions = signal({ source: 'right', target: 'left' });
|
|
163
156
|
/**
|
|
164
157
|
* @see {VflowComponent.view}
|
|
165
158
|
*/
|
|
@@ -176,10 +169,10 @@ class FlowSettingsService {
|
|
|
176
169
|
this.maxZoom = signal(3);
|
|
177
170
|
this.background = signal({ type: 'solid', color: '#fff' });
|
|
178
171
|
}
|
|
179
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
180
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
172
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
173
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService }); }
|
|
181
174
|
}
|
|
182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSettingsService, decorators: [{
|
|
183
176
|
type: Injectable
|
|
184
177
|
}] });
|
|
185
178
|
|
|
@@ -225,10 +218,10 @@ class ViewportService {
|
|
|
225
218
|
.map(nodeId => this.entitiesService.nodes().find(({ node }) => node.id === nodeId))
|
|
226
219
|
.filter((node) => !!node);
|
|
227
220
|
}
|
|
228
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
229
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
221
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
222
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService }); }
|
|
230
223
|
}
|
|
231
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
224
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewportService, decorators: [{
|
|
232
225
|
type: Injectable
|
|
233
226
|
}] });
|
|
234
227
|
|
|
@@ -240,13 +233,14 @@ class RootSvgReferenceDirective {
|
|
|
240
233
|
constructor() {
|
|
241
234
|
this.element = inject(ElementRef).nativeElement;
|
|
242
235
|
}
|
|
243
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
244
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
236
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgReferenceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
237
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootSvgReferenceDirective, isStandalone: true, selector: "svg[rootSvgRef]", ngImport: i0 }); }
|
|
245
238
|
}
|
|
246
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
239
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgReferenceDirective, decorators: [{
|
|
247
240
|
type: Directive,
|
|
248
241
|
args: [{
|
|
249
|
-
|
|
242
|
+
standalone: true,
|
|
243
|
+
selector: 'svg[rootSvgRef]',
|
|
250
244
|
}]
|
|
251
245
|
}] });
|
|
252
246
|
|
|
@@ -307,12 +301,12 @@ class KeyboardService {
|
|
|
307
301
|
isActiveAction(action) {
|
|
308
302
|
return this.actionsActive[action];
|
|
309
303
|
}
|
|
310
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
311
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
304
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
305
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService }); }
|
|
312
306
|
}
|
|
313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, decorators: [{
|
|
314
308
|
type: Injectable
|
|
315
|
-
}], ctorParameters:
|
|
309
|
+
}], ctorParameters: () => [] });
|
|
316
310
|
|
|
317
311
|
class SelectionService {
|
|
318
312
|
constructor() {
|
|
@@ -353,10 +347,10 @@ class SelectionService {
|
|
|
353
347
|
entity.selected.set(true);
|
|
354
348
|
}
|
|
355
349
|
}
|
|
356
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
357
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
350
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
351
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService }); }
|
|
358
352
|
}
|
|
359
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionService, decorators: [{
|
|
360
354
|
type: Injectable
|
|
361
355
|
}] });
|
|
362
356
|
|
|
@@ -437,12 +431,15 @@ class MapContextDirective {
|
|
|
437
431
|
.call(this.zoomBehavior)
|
|
438
432
|
.on('dblclick.zoom', null);
|
|
439
433
|
}
|
|
440
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
441
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
435
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: MapContextDirective, isStandalone: true, selector: "g[mapContext]", ngImport: i0 }); }
|
|
442
436
|
}
|
|
443
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapContextDirective, decorators: [{
|
|
444
438
|
type: Directive,
|
|
445
|
-
args: [{
|
|
439
|
+
args: [{
|
|
440
|
+
standalone: true,
|
|
441
|
+
selector: 'g[mapContext]',
|
|
442
|
+
}]
|
|
446
443
|
}] });
|
|
447
444
|
const mapTransformToViewportState = (transform) => ({ zoom: transform.k, x: transform.x, y: transform.y });
|
|
448
445
|
const evTarget = (anyEvent) => {
|
|
@@ -530,10 +527,10 @@ class DraggableService {
|
|
|
530
527
|
// we only can move current node if it's not selected
|
|
531
528
|
: [model];
|
|
532
529
|
}
|
|
533
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
534
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
530
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
531
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService }); }
|
|
535
532
|
}
|
|
536
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
533
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableService, decorators: [{
|
|
537
534
|
type: Injectable
|
|
538
535
|
}] });
|
|
539
536
|
function moveNode(model, point) {
|
|
@@ -552,67 +549,85 @@ class EdgeTemplateDirective {
|
|
|
552
549
|
constructor() {
|
|
553
550
|
this.templateRef = inject(TemplateRef);
|
|
554
551
|
}
|
|
555
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
556
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
552
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
553
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeTemplateDirective, isStandalone: true, selector: "ng-template[edge]", ngImport: i0 }); }
|
|
557
554
|
}
|
|
558
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
555
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeTemplateDirective, decorators: [{
|
|
559
556
|
type: Directive,
|
|
560
|
-
args: [{
|
|
557
|
+
args: [{
|
|
558
|
+
standalone: true,
|
|
559
|
+
selector: 'ng-template[edge]',
|
|
560
|
+
}]
|
|
561
561
|
}] });
|
|
562
562
|
class ConnectionTemplateDirective {
|
|
563
563
|
constructor() {
|
|
564
564
|
this.templateRef = inject(TemplateRef);
|
|
565
565
|
}
|
|
566
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
567
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
566
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
567
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionTemplateDirective, isStandalone: true, selector: "ng-template[connection]", ngImport: i0 }); }
|
|
568
568
|
}
|
|
569
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionTemplateDirective, decorators: [{
|
|
570
570
|
type: Directive,
|
|
571
|
-
args: [{
|
|
571
|
+
args: [{
|
|
572
|
+
standalone: true,
|
|
573
|
+
selector: 'ng-template[connection]'
|
|
574
|
+
}]
|
|
572
575
|
}] });
|
|
573
576
|
class EdgeLabelHtmlTemplateDirective {
|
|
574
577
|
constructor() {
|
|
575
578
|
this.templateRef = inject(TemplateRef);
|
|
576
579
|
}
|
|
577
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
578
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
580
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
581
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: EdgeLabelHtmlTemplateDirective, isStandalone: true, selector: "ng-template[edgeLabelHtml]", ngImport: i0 }); }
|
|
579
582
|
}
|
|
580
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
583
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelHtmlTemplateDirective, decorators: [{
|
|
581
584
|
type: Directive,
|
|
582
|
-
args: [{
|
|
585
|
+
args: [{
|
|
586
|
+
standalone: true,
|
|
587
|
+
selector: 'ng-template[edgeLabelHtml]'
|
|
588
|
+
}]
|
|
583
589
|
}] });
|
|
584
590
|
class NodeHtmlTemplateDirective {
|
|
585
591
|
constructor() {
|
|
586
592
|
this.templateRef = inject(TemplateRef);
|
|
587
593
|
}
|
|
588
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
589
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
594
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
595
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NodeHtmlTemplateDirective, isStandalone: true, selector: "ng-template[nodeHtml]", ngImport: i0 }); }
|
|
590
596
|
}
|
|
591
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
597
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeHtmlTemplateDirective, decorators: [{
|
|
592
598
|
type: Directive,
|
|
593
|
-
args: [{
|
|
599
|
+
args: [{
|
|
600
|
+
standalone: true,
|
|
601
|
+
selector: 'ng-template[nodeHtml]'
|
|
602
|
+
}]
|
|
594
603
|
}] });
|
|
595
604
|
class GroupNodeTemplateDirective {
|
|
596
605
|
constructor() {
|
|
597
606
|
this.templateRef = inject(TemplateRef);
|
|
598
607
|
}
|
|
599
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
600
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
608
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
609
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: GroupNodeTemplateDirective, isStandalone: true, selector: "ng-template[groupNode]", ngImport: i0 }); }
|
|
601
610
|
}
|
|
602
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
611
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupNodeTemplateDirective, decorators: [{
|
|
603
612
|
type: Directive,
|
|
604
|
-
args: [{
|
|
613
|
+
args: [{
|
|
614
|
+
standalone: true,
|
|
615
|
+
selector: 'ng-template[groupNode]'
|
|
616
|
+
}]
|
|
605
617
|
}] });
|
|
606
618
|
class HandleTemplateDirective {
|
|
607
619
|
constructor() {
|
|
608
620
|
this.templateRef = inject(TemplateRef);
|
|
609
621
|
}
|
|
610
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
611
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
622
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
623
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: HandleTemplateDirective, isStandalone: true, selector: "ng-template[handle]", ngImport: i0 }); }
|
|
612
624
|
}
|
|
613
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
625
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleTemplateDirective, decorators: [{
|
|
614
626
|
type: Directive,
|
|
615
|
-
args: [{
|
|
627
|
+
args: [{
|
|
628
|
+
standalone: true,
|
|
629
|
+
selector: 'ng-template[handle]'
|
|
630
|
+
}]
|
|
616
631
|
}] });
|
|
617
632
|
|
|
618
633
|
function addNodesToEdges(nodes, edges) {
|
|
@@ -642,10 +657,10 @@ class FlowStatusService {
|
|
|
642
657
|
setConnectionEndStatus(source, target, sourceHandle, targetHandle) {
|
|
643
658
|
this.status.set({ state: 'connection-end', payload: { source, target, sourceHandle, targetHandle } });
|
|
644
659
|
}
|
|
645
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
646
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
660
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
661
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService }); }
|
|
647
662
|
}
|
|
648
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
663
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowStatusService, decorators: [{
|
|
649
664
|
type: Injectable
|
|
650
665
|
}] });
|
|
651
666
|
/**
|
|
@@ -703,7 +718,7 @@ class ConnectionControllerDirective {
|
|
|
703
718
|
* Also it's important to note, that this event only fires when connection is valid by validator function in `ConnectionSettings`,
|
|
704
719
|
* by default without passing the validator every connection concidered valid.
|
|
705
720
|
*/
|
|
706
|
-
this.onConnect =
|
|
721
|
+
this.onConnect = output();
|
|
707
722
|
this.statusService = inject(FlowStatusService);
|
|
708
723
|
this.flowEntitiesService = inject(FlowEntitiesService);
|
|
709
724
|
this.connectEffect = effect(() => {
|
|
@@ -718,7 +733,7 @@ class ConnectionControllerDirective {
|
|
|
718
733
|
source: status.payload.source,
|
|
719
734
|
sourceHandle: status.payload.sourceHandle,
|
|
720
735
|
target: status.payload.target,
|
|
721
|
-
targetHandle: status.payload.targetHandle
|
|
736
|
+
targetHandle: status.payload.targetHandle,
|
|
722
737
|
});
|
|
723
738
|
source = adjusted.source;
|
|
724
739
|
target = adjusted.target;
|
|
@@ -731,8 +746,10 @@ class ConnectionControllerDirective {
|
|
|
731
746
|
const targetHandleId = targetHandle.rawHandle.id;
|
|
732
747
|
const connectionModel = this.flowEntitiesService.connection();
|
|
733
748
|
const connection = {
|
|
734
|
-
source: sourceId,
|
|
735
|
-
|
|
749
|
+
source: sourceId,
|
|
750
|
+
target: targetId,
|
|
751
|
+
sourceHandle: sourceHandleId,
|
|
752
|
+
targetHandle: targetHandleId,
|
|
736
753
|
};
|
|
737
754
|
if (connectionModel.validator(connection)) {
|
|
738
755
|
this.onConnect.emit(connection);
|
|
@@ -757,7 +774,7 @@ class ConnectionControllerDirective {
|
|
|
757
774
|
source: status.payload.source,
|
|
758
775
|
sourceHandle: status.payload.sourceHandle,
|
|
759
776
|
target: handle.parentNode,
|
|
760
|
-
targetHandle: handle
|
|
777
|
+
targetHandle: handle,
|
|
761
778
|
});
|
|
762
779
|
source = adjusted.source;
|
|
763
780
|
target = adjusted.target;
|
|
@@ -768,7 +785,7 @@ class ConnectionControllerDirective {
|
|
|
768
785
|
source: source.node.id,
|
|
769
786
|
target: target.node.id,
|
|
770
787
|
sourceHandle: sourceHandle.rawHandle.id,
|
|
771
|
-
targetHandle: targetHandle.rawHandle.id
|
|
788
|
+
targetHandle: targetHandle.rawHandle.id,
|
|
772
789
|
});
|
|
773
790
|
// TODO: check how react flow handles highlight of handle
|
|
774
791
|
// if direction changes
|
|
@@ -800,18 +817,16 @@ class ConnectionControllerDirective {
|
|
|
800
817
|
() => this.statusService.setIdleStatus());
|
|
801
818
|
}
|
|
802
819
|
}
|
|
803
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
804
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
820
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
821
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ConnectionControllerDirective, isStandalone: true, selector: "[connectionController]", outputs: { onConnect: "onConnect" }, ngImport: i0 }); }
|
|
805
822
|
}
|
|
806
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
823
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionControllerDirective, decorators: [{
|
|
807
824
|
type: Directive,
|
|
808
825
|
args: [{
|
|
809
826
|
selector: '[connectionController]',
|
|
810
|
-
standalone: true
|
|
827
|
+
standalone: true,
|
|
811
828
|
}]
|
|
812
|
-
}]
|
|
813
|
-
type: Output
|
|
814
|
-
}] } });
|
|
829
|
+
}] });
|
|
815
830
|
|
|
816
831
|
class ComponentEventBusService {
|
|
817
832
|
constructor() {
|
|
@@ -821,89 +836,120 @@ class ComponentEventBusService {
|
|
|
821
836
|
pushEvent(event) {
|
|
822
837
|
this._event$.next(event);
|
|
823
838
|
}
|
|
824
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
825
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
839
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
840
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService }); }
|
|
841
|
+
}
|
|
842
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentEventBusService, decorators: [{
|
|
843
|
+
type: Injectable
|
|
844
|
+
}] });
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Service to fix cyclic dependency between node and resizable component
|
|
848
|
+
*/
|
|
849
|
+
class NodeAccessorService {
|
|
850
|
+
constructor() {
|
|
851
|
+
this.model = signal(null);
|
|
852
|
+
}
|
|
853
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
854
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService }); }
|
|
826
855
|
}
|
|
827
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
856
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeAccessorService, decorators: [{
|
|
828
857
|
type: Injectable
|
|
829
858
|
}] });
|
|
830
859
|
|
|
831
860
|
class CustomNodeBaseComponent {
|
|
832
861
|
constructor() {
|
|
833
862
|
this.eventBus = inject(ComponentEventBusService);
|
|
863
|
+
this.nodeService = inject(NodeAccessorService);
|
|
834
864
|
this.destroyRef = inject(DestroyRef);
|
|
835
865
|
/**
|
|
836
866
|
* Signal with selected state of node
|
|
837
867
|
*/
|
|
838
|
-
this.selected =
|
|
868
|
+
this.selected = this.nodeService.model().selected;
|
|
839
869
|
this.data = signal(undefined);
|
|
840
870
|
}
|
|
841
|
-
set _selected(value) {
|
|
842
|
-
this.selected.set(value);
|
|
843
|
-
}
|
|
844
871
|
ngOnInit() {
|
|
845
|
-
this.trackEvents()
|
|
846
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
847
|
-
.subscribe();
|
|
872
|
+
this.trackEvents().pipe(takeUntilDestroyed(this.destroyRef)).subscribe();
|
|
848
873
|
}
|
|
849
874
|
trackEvents() {
|
|
850
875
|
const props = Object.getOwnPropertyNames(this);
|
|
851
|
-
const
|
|
876
|
+
const emittersOrRefs = new Map();
|
|
852
877
|
for (const prop of props) {
|
|
853
878
|
const field = this[prop];
|
|
854
879
|
if (field instanceof EventEmitter) {
|
|
855
|
-
|
|
880
|
+
emittersOrRefs.set(field, prop);
|
|
881
|
+
}
|
|
882
|
+
if (field instanceof OutputEmitterRef) {
|
|
883
|
+
emittersOrRefs.set(outputRefToObservable(field), prop);
|
|
856
884
|
}
|
|
857
885
|
}
|
|
858
|
-
return merge(...Array.from(
|
|
886
|
+
return merge(...Array.from(emittersOrRefs.keys()).map((emitter) => emitter.pipe(tap((event) => {
|
|
859
887
|
this.eventBus.pushEvent({
|
|
860
|
-
nodeId: this.node.id,
|
|
861
|
-
eventName:
|
|
862
|
-
eventPayload: event
|
|
888
|
+
nodeId: this.nodeService.model()?.node.id ?? '',
|
|
889
|
+
eventName: emittersOrRefs.get(emitter),
|
|
890
|
+
eventPayload: event,
|
|
863
891
|
});
|
|
864
892
|
}))));
|
|
865
893
|
}
|
|
866
|
-
;
|
|
867
|
-
static { this.ɵ
|
|
868
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CustomNodeBaseComponent, inputs: { _selected: "_selected" }, ngImport: i0 }); }
|
|
894
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
895
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CustomNodeBaseComponent, ngImport: i0 }); }
|
|
869
896
|
}
|
|
870
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
897
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeBaseComponent, decorators: [{
|
|
871
898
|
type: Directive
|
|
872
|
-
}]
|
|
873
|
-
|
|
874
|
-
|
|
899
|
+
}] });
|
|
900
|
+
function outputRefToObservable(ref) {
|
|
901
|
+
return new Observable((subscriber) => {
|
|
902
|
+
const subscription = ref.subscribe((value) => {
|
|
903
|
+
subscriber.next(value);
|
|
904
|
+
});
|
|
905
|
+
return () => {
|
|
906
|
+
subscription.unsubscribe();
|
|
907
|
+
};
|
|
908
|
+
});
|
|
909
|
+
}
|
|
875
910
|
|
|
876
911
|
class CustomNodeComponent extends CustomNodeBaseComponent {
|
|
912
|
+
constructor() {
|
|
913
|
+
super(...arguments);
|
|
914
|
+
/**
|
|
915
|
+
* Reference to node bound to this component
|
|
916
|
+
*/
|
|
917
|
+
this.node = input.required();
|
|
918
|
+
}
|
|
877
919
|
ngOnInit() {
|
|
878
|
-
if (this.node.data) {
|
|
879
|
-
this.data.set(this.node.data);
|
|
920
|
+
if (this.node().data) {
|
|
921
|
+
this.data.set(this.node().data);
|
|
880
922
|
}
|
|
881
923
|
super.ngOnInit();
|
|
882
924
|
}
|
|
883
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
884
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
925
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
926
|
+
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 }); }
|
|
885
927
|
}
|
|
886
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
928
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomNodeComponent, decorators: [{
|
|
887
929
|
type: Directive
|
|
888
|
-
}]
|
|
889
|
-
type: Input
|
|
890
|
-
}] } });
|
|
930
|
+
}] });
|
|
891
931
|
|
|
892
932
|
class CustomDynamicNodeComponent extends CustomNodeBaseComponent {
|
|
933
|
+
constructor() {
|
|
934
|
+
super(...arguments);
|
|
935
|
+
/**
|
|
936
|
+
* Reference to node bound to this component
|
|
937
|
+
*/
|
|
938
|
+
this.node = input.required();
|
|
939
|
+
}
|
|
893
940
|
ngOnInit() {
|
|
894
|
-
|
|
895
|
-
|
|
941
|
+
const data = this.node().data;
|
|
942
|
+
if (data) {
|
|
943
|
+
this.data = data;
|
|
896
944
|
}
|
|
897
945
|
super.ngOnInit();
|
|
898
946
|
}
|
|
899
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
900
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
947
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
948
|
+
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 }); }
|
|
901
949
|
}
|
|
902
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
950
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDynamicNodeComponent, decorators: [{
|
|
903
951
|
type: Directive
|
|
904
|
-
}]
|
|
905
|
-
type: Input
|
|
906
|
-
}] } });
|
|
952
|
+
}] });
|
|
907
953
|
|
|
908
954
|
function isStaticNode(node) {
|
|
909
955
|
return typeof node.point !== 'function';
|
|
@@ -977,9 +1023,6 @@ class NodeModel {
|
|
|
977
1023
|
return { x, y };
|
|
978
1024
|
});
|
|
979
1025
|
this.pointTransform = computed(() => `translate(${this.globalPoint().x}, ${this.globalPoint().y})`);
|
|
980
|
-
// Now source and handle positions derived from parent flow
|
|
981
|
-
this.sourcePosition = computed(() => this.flowSettingsService.handlePositions().source);
|
|
982
|
-
this.targetPosition = computed(() => this.flowSettingsService.handlePositions().target);
|
|
983
1026
|
this.handles = signal([]);
|
|
984
1027
|
this.handles$ = toObservable(this.handles);
|
|
985
1028
|
this.draggable = signal(true);
|
|
@@ -992,12 +1035,9 @@ class NodeModel {
|
|
|
992
1035
|
// Default node specific thing
|
|
993
1036
|
this.text = this.createTextSignal();
|
|
994
1037
|
// Component node specific thing
|
|
995
|
-
this.componentTypeInputs =
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
_selected: this.selected()
|
|
999
|
-
};
|
|
1000
|
-
});
|
|
1038
|
+
this.componentTypeInputs = {
|
|
1039
|
+
node: this.node,
|
|
1040
|
+
};
|
|
1001
1041
|
this.parent = computed(() => this.entitiesService.nodes().find(n => n.node.id === this.parentId()) ?? null);
|
|
1002
1042
|
this.children = computed(() => this.entitiesService.nodes().filter(n => n.parentId() === this.node.id));
|
|
1003
1043
|
this.color = signal(NodeModel.defaultColor);
|
|
@@ -1213,6 +1253,176 @@ function getPointOnBezier(sourcePoint, targetPoint, sourceControl, targetControl
|
|
|
1213
1253
|
return getPointOnLineByRatio(getPointOnLineByRatio(fromSourceToFirstControl, fromFirstControlToSecond, ratio), getPointOnLineByRatio(fromFirstControlToSecond, fromSecondControlToTarget, ratio), ratio);
|
|
1214
1254
|
}
|
|
1215
1255
|
|
|
1256
|
+
const handleDirections = {
|
|
1257
|
+
left: { x: -1, y: 0 },
|
|
1258
|
+
right: { x: 1, y: 0 },
|
|
1259
|
+
top: { x: 0, y: -1 },
|
|
1260
|
+
bottom: { x: 0, y: 1 },
|
|
1261
|
+
};
|
|
1262
|
+
function getEdgeCenter(source, target) {
|
|
1263
|
+
const xOffset = Math.abs(target.x - source.x) / 2;
|
|
1264
|
+
const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;
|
|
1265
|
+
const yOffset = Math.abs(target.y - source.y) / 2;
|
|
1266
|
+
const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;
|
|
1267
|
+
return [centerX, centerY, xOffset, yOffset];
|
|
1268
|
+
}
|
|
1269
|
+
const getDirection = ({ source, sourcePosition = 'bottom', target, }) => {
|
|
1270
|
+
if (sourcePosition === 'left' || sourcePosition === 'right') {
|
|
1271
|
+
return source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };
|
|
1272
|
+
}
|
|
1273
|
+
return source.y < target.y ? { x: 0, y: 1 } : { x: 0, y: -1 };
|
|
1274
|
+
};
|
|
1275
|
+
const distance = (a, b) => Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));
|
|
1276
|
+
// ith this function we try to mimic a orthogonal edge routing behaviour
|
|
1277
|
+
// It's not as good as a real orthogonal edge routing but it's faster and good enough as a default for step and smooth step edges
|
|
1278
|
+
function getPoints({ source, sourcePosition = 'bottom', target, targetPosition = 'top', offset, }) {
|
|
1279
|
+
const sourceDir = handleDirections[sourcePosition];
|
|
1280
|
+
const targetDir = handleDirections[targetPosition];
|
|
1281
|
+
const sourceGapped = { x: source.x + sourceDir.x * offset, y: source.y + sourceDir.y * offset };
|
|
1282
|
+
const targetGapped = { x: target.x + targetDir.x * offset, y: target.y + targetDir.y * offset };
|
|
1283
|
+
const dir = getDirection({
|
|
1284
|
+
source: sourceGapped,
|
|
1285
|
+
sourcePosition,
|
|
1286
|
+
target: targetGapped,
|
|
1287
|
+
});
|
|
1288
|
+
const dirAccessor = dir.x !== 0 ? 'x' : 'y';
|
|
1289
|
+
const currDir = dir[dirAccessor];
|
|
1290
|
+
let points = [];
|
|
1291
|
+
let centerX, centerY;
|
|
1292
|
+
const sourceGapOffset = { x: 0, y: 0 };
|
|
1293
|
+
const targetGapOffset = { x: 0, y: 0 };
|
|
1294
|
+
const [defaultCenterX, defaultCenterY] = getEdgeCenter(source, target);
|
|
1295
|
+
// opposite handle positions, default case
|
|
1296
|
+
if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {
|
|
1297
|
+
centerX = defaultCenterX;
|
|
1298
|
+
centerY = defaultCenterY;
|
|
1299
|
+
// --->
|
|
1300
|
+
// |
|
|
1301
|
+
// >---
|
|
1302
|
+
const verticalSplit = [
|
|
1303
|
+
{ x: centerX, y: sourceGapped.y },
|
|
1304
|
+
{ x: centerX, y: targetGapped.y },
|
|
1305
|
+
];
|
|
1306
|
+
// |
|
|
1307
|
+
// ---
|
|
1308
|
+
// |
|
|
1309
|
+
const horizontalSplit = [
|
|
1310
|
+
{ x: sourceGapped.x, y: centerY },
|
|
1311
|
+
{ x: targetGapped.x, y: centerY },
|
|
1312
|
+
];
|
|
1313
|
+
if (sourceDir[dirAccessor] === currDir) {
|
|
1314
|
+
points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;
|
|
1315
|
+
}
|
|
1316
|
+
else {
|
|
1317
|
+
points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
// sourceTarget means we take x from source and y from target, targetSource is the opposite
|
|
1322
|
+
const sourceTarget = [{ x: sourceGapped.x, y: targetGapped.y }];
|
|
1323
|
+
const targetSource = [{ x: targetGapped.x, y: sourceGapped.y }];
|
|
1324
|
+
// this handles edges with same handle positions
|
|
1325
|
+
if (dirAccessor === 'x') {
|
|
1326
|
+
points = sourceDir.x === currDir ? targetSource : sourceTarget;
|
|
1327
|
+
}
|
|
1328
|
+
else {
|
|
1329
|
+
points = sourceDir.y === currDir ? sourceTarget : targetSource;
|
|
1330
|
+
}
|
|
1331
|
+
if (sourcePosition === targetPosition) {
|
|
1332
|
+
const diff = Math.abs(source[dirAccessor] - target[dirAccessor]);
|
|
1333
|
+
// if an edge goes from right to right for example (sourcePosition === targetPosition) and the distance between source.x and target.x is less than the offset, the added point and the gapped source/target will overlap. This leads to a weird edge path. To avoid this we add a gapOffset to the source/target
|
|
1334
|
+
if (diff <= offset) {
|
|
1335
|
+
const gapOffset = Math.min(offset - 1, offset - diff);
|
|
1336
|
+
if (sourceDir[dirAccessor] === currDir) {
|
|
1337
|
+
sourceGapOffset[dirAccessor] = (sourceGapped[dirAccessor] > source[dirAccessor] ? -1 : 1) * gapOffset;
|
|
1338
|
+
}
|
|
1339
|
+
else {
|
|
1340
|
+
targetGapOffset[dirAccessor] = (targetGapped[dirAccessor] > target[dirAccessor] ? -1 : 1) * gapOffset;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
// these are conditions for handling mixed handle positions like Right -> Bottom for example
|
|
1345
|
+
if (sourcePosition !== targetPosition) {
|
|
1346
|
+
const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';
|
|
1347
|
+
const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];
|
|
1348
|
+
const sourceGtTargetOppo = sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];
|
|
1349
|
+
const sourceLtTargetOppo = sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];
|
|
1350
|
+
const flipSourceTarget = (sourceDir[dirAccessor] === 1 && ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||
|
|
1351
|
+
(sourceDir[dirAccessor] !== 1 && ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));
|
|
1352
|
+
if (flipSourceTarget) {
|
|
1353
|
+
points = dirAccessor === 'x' ? sourceTarget : targetSource;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
const sourceGapPoint = { x: sourceGapped.x + sourceGapOffset.x, y: sourceGapped.y + sourceGapOffset.y };
|
|
1357
|
+
const targetGapPoint = { x: targetGapped.x + targetGapOffset.x, y: targetGapped.y + targetGapOffset.y };
|
|
1358
|
+
const maxXDistance = Math.max(Math.abs(sourceGapPoint.x - points[0].x), Math.abs(targetGapPoint.x - points[0].x));
|
|
1359
|
+
const maxYDistance = Math.max(Math.abs(sourceGapPoint.y - points[0].y), Math.abs(targetGapPoint.y - points[0].y));
|
|
1360
|
+
// we want to place the label on the longest segment of the edge
|
|
1361
|
+
if (maxXDistance >= maxYDistance) {
|
|
1362
|
+
centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;
|
|
1363
|
+
centerY = points[0].y;
|
|
1364
|
+
}
|
|
1365
|
+
else {
|
|
1366
|
+
centerX = points[0].x;
|
|
1367
|
+
centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
const pathPoints = [
|
|
1371
|
+
source,
|
|
1372
|
+
{ x: sourceGapped.x + sourceGapOffset.x, y: sourceGapped.y + sourceGapOffset.y },
|
|
1373
|
+
...points,
|
|
1374
|
+
{ x: targetGapped.x + targetGapOffset.x, y: targetGapped.y + targetGapOffset.y },
|
|
1375
|
+
target,
|
|
1376
|
+
];
|
|
1377
|
+
return [pathPoints, centerX, centerY];
|
|
1378
|
+
}
|
|
1379
|
+
function getBend(a, b, c, size) {
|
|
1380
|
+
const bendSize = Math.min(distance(a, b) / 2, distance(b, c) / 2, size);
|
|
1381
|
+
const { x, y } = b;
|
|
1382
|
+
// no bend
|
|
1383
|
+
if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {
|
|
1384
|
+
return `L${x} ${y}`;
|
|
1385
|
+
}
|
|
1386
|
+
// first segment is horizontal
|
|
1387
|
+
if (a.y === y) {
|
|
1388
|
+
const xDir = a.x < c.x ? -1 : 1;
|
|
1389
|
+
const yDir = a.y < c.y ? 1 : -1;
|
|
1390
|
+
return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;
|
|
1391
|
+
}
|
|
1392
|
+
const xDir = a.x < c.x ? 1 : -1;
|
|
1393
|
+
const yDir = a.y < c.y ? -1 : 1;
|
|
1394
|
+
return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
|
|
1395
|
+
}
|
|
1396
|
+
function smoothStepPath(source, target, sourcePosition, targetPosition, borderRadius = 5) {
|
|
1397
|
+
const [points, labelX, labelY] = getPoints({
|
|
1398
|
+
source,
|
|
1399
|
+
sourcePosition,
|
|
1400
|
+
target,
|
|
1401
|
+
targetPosition,
|
|
1402
|
+
offset: 20
|
|
1403
|
+
});
|
|
1404
|
+
const path = points.reduce((res, p, i) => {
|
|
1405
|
+
let segment = '';
|
|
1406
|
+
if (i > 0 && i < points.length - 1) {
|
|
1407
|
+
segment = getBend(points[i - 1], p, points[i + 1], borderRadius);
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;
|
|
1411
|
+
}
|
|
1412
|
+
res += segment;
|
|
1413
|
+
return res;
|
|
1414
|
+
}, '');
|
|
1415
|
+
return {
|
|
1416
|
+
path,
|
|
1417
|
+
points: {
|
|
1418
|
+
// TODO start and end points temporary unavailable for this path
|
|
1419
|
+
start: { x: labelX, y: labelY },
|
|
1420
|
+
center: { x: labelX, y: labelY },
|
|
1421
|
+
end: { x: labelX, y: labelY },
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1216
1426
|
class EdgeModel {
|
|
1217
1427
|
constructor(edge) {
|
|
1218
1428
|
this.edge = edge;
|
|
@@ -1282,6 +1492,10 @@ class EdgeModel {
|
|
|
1282
1492
|
return straightPath(source.pointAbsolute(), target.pointAbsolute(), this.usingPoints);
|
|
1283
1493
|
case 'bezier':
|
|
1284
1494
|
return bezierPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position, this.usingPoints);
|
|
1495
|
+
case 'smooth-step':
|
|
1496
|
+
return smoothStepPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position);
|
|
1497
|
+
case 'step':
|
|
1498
|
+
return smoothStepPath(source.pointAbsolute(), target.pointAbsolute(), source.rawHandle.position, target.rawHandle.position, 0);
|
|
1285
1499
|
}
|
|
1286
1500
|
});
|
|
1287
1501
|
this.edgeLabels = {};
|
|
@@ -1359,10 +1573,10 @@ class NodesChangeService {
|
|
|
1359
1573
|
// you can't get valid list of detached edges
|
|
1360
1574
|
observeOn(asyncScheduler, DELAY_FOR_SCHEDULER));
|
|
1361
1575
|
}
|
|
1362
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1363
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1576
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1577
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService }); }
|
|
1364
1578
|
}
|
|
1365
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1579
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodesChangeService, decorators: [{
|
|
1366
1580
|
type: Injectable
|
|
1367
1581
|
}] });
|
|
1368
1582
|
|
|
@@ -1403,10 +1617,10 @@ class EdgeChangesService {
|
|
|
1403
1617
|
// right after [nodes] input change
|
|
1404
1618
|
observeOn(asyncScheduler));
|
|
1405
1619
|
}
|
|
1406
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1407
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1620
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1621
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService }); }
|
|
1408
1622
|
}
|
|
1409
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1623
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeChangesService, decorators: [{
|
|
1410
1624
|
type: Injectable
|
|
1411
1625
|
}] });
|
|
1412
1626
|
|
|
@@ -1417,146 +1631,65 @@ class ChangesControllerDirective {
|
|
|
1417
1631
|
/**
|
|
1418
1632
|
* Watch nodes change
|
|
1419
1633
|
*/
|
|
1420
|
-
this.onNodesChange = this.nodesChangeService.changes
|
|
1421
|
-
this.onNodesChangePosition = this.nodeChangesOfType('position');
|
|
1422
|
-
this.onNodesChangePositionSignle = this.singleChange(this.nodeChangesOfType('position'));
|
|
1423
|
-
this.onNodesChangePositionMany = this.manyChanges(this.nodeChangesOfType('position'));
|
|
1424
|
-
this.onNodesChangeSize = this.nodeChangesOfType('size');
|
|
1425
|
-
this.onNodesChangeSizeSingle = this.singleChange(this.nodeChangesOfType('size'));
|
|
1426
|
-
this.onNodesChangeSizeMany = this.manyChanges(this.nodeChangesOfType('size'));
|
|
1427
|
-
this.onNodesChangeAdd = this.nodeChangesOfType('add');
|
|
1428
|
-
this.onNodesChangeAddSingle = this.singleChange(this.nodeChangesOfType('add'));
|
|
1429
|
-
this.onNodesChangeAddMany = this.manyChanges(this.nodeChangesOfType('add'));
|
|
1430
|
-
this.onNodesChangeRemove = this.nodeChangesOfType('remove');
|
|
1431
|
-
this.onNodesChangeRemoveSingle = this.singleChange(this.nodeChangesOfType('remove'));
|
|
1432
|
-
this.onNodesChangeRemoveMany = this.manyChanges(this.nodeChangesOfType('remove'));
|
|
1433
|
-
this.onNodesChangeSelect = this.nodeChangesOfType('select');
|
|
1434
|
-
this.onNodesChangeSelectSingle = this.singleChange(this.nodeChangesOfType('select'));
|
|
1435
|
-
this.onNodesChangeSelectMany = this.manyChanges(this.nodeChangesOfType('select'));
|
|
1634
|
+
this.onNodesChange = outputFromObservable(this.nodesChangeService.changes$);
|
|
1635
|
+
this.onNodesChangePosition = outputFromObservable(this.nodeChangesOfType('position'), { alias: 'onNodesChange.position' });
|
|
1636
|
+
this.onNodesChangePositionSignle = outputFromObservable(this.singleChange(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.single' });
|
|
1637
|
+
this.onNodesChangePositionMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('position')), { alias: 'onNodesChange.position.many' });
|
|
1638
|
+
this.onNodesChangeSize = outputFromObservable(this.nodeChangesOfType('size'), { alias: 'onNodesChange.size' });
|
|
1639
|
+
this.onNodesChangeSizeSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.single' });
|
|
1640
|
+
this.onNodesChangeSizeMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('size')), { alias: 'onNodesChange.size.many' });
|
|
1641
|
+
this.onNodesChangeAdd = outputFromObservable(this.nodeChangesOfType('add'), { alias: 'onNodesChange.add' });
|
|
1642
|
+
this.onNodesChangeAddSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.single' });
|
|
1643
|
+
this.onNodesChangeAddMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('add')), { alias: 'onNodesChange.add.many' });
|
|
1644
|
+
this.onNodesChangeRemove = outputFromObservable(this.nodeChangesOfType('remove'), { alias: 'onNodesChange.remove' });
|
|
1645
|
+
this.onNodesChangeRemoveSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.single' });
|
|
1646
|
+
this.onNodesChangeRemoveMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('remove')), { alias: 'onNodesChange.remove.many' });
|
|
1647
|
+
this.onNodesChangeSelect = outputFromObservable(this.nodeChangesOfType('select'), { alias: 'onNodesChange.select' });
|
|
1648
|
+
this.onNodesChangeSelectSingle = outputFromObservable(this.singleChange(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.single' });
|
|
1649
|
+
this.onNodesChangeSelectMany = outputFromObservable(this.manyChanges(this.nodeChangesOfType('select')), { alias: 'onNodesChange.select.many' });
|
|
1436
1650
|
/**
|
|
1437
1651
|
* Watch edges change
|
|
1438
1652
|
*/
|
|
1439
|
-
this.onEdgesChange = this.edgesChangeService.changes
|
|
1440
|
-
this.onNodesChangeDetached = this.edgeChangesOfType('detached');
|
|
1441
|
-
this.onNodesChangeDetachedSingle = this.singleChange(this.edgeChangesOfType('detached'));
|
|
1442
|
-
this.onNodesChangeDetachedMany = this.manyChanges(this.edgeChangesOfType('detached'));
|
|
1443
|
-
this.onEdgesChangeAdd = this.edgeChangesOfType('add');
|
|
1444
|
-
this.onEdgeChangeAddSingle = this.singleChange(this.edgeChangesOfType('add'));
|
|
1445
|
-
this.onEdgeChangeAddMany = this.manyChanges(this.edgeChangesOfType('add'));
|
|
1446
|
-
this.onEdgeChangeRemove = this.edgeChangesOfType('remove');
|
|
1447
|
-
this.onEdgeChangeRemoveSingle = this.singleChange(this.edgeChangesOfType('remove'));
|
|
1448
|
-
this.onEdgeChangeRemoveMany = this.manyChanges(this.edgeChangesOfType('remove'));
|
|
1449
|
-
this.onEdgeChangeSelect = this.edgeChangesOfType('select');
|
|
1450
|
-
this.onEdgeChangeSelectSingle = this.singleChange(this.edgeChangesOfType('select'));
|
|
1451
|
-
this.onEdgeChangeSelectMany = this.manyChanges(this.edgeChangesOfType('select'));
|
|
1653
|
+
this.onEdgesChange = outputFromObservable(this.edgesChangeService.changes$);
|
|
1654
|
+
this.onNodesChangeDetached = outputFromObservable(this.edgeChangesOfType('detached'), { alias: 'onEdgesChange.detached' });
|
|
1655
|
+
this.onNodesChangeDetachedSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.single' });
|
|
1656
|
+
this.onNodesChangeDetachedMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('detached')), { alias: 'onEdgesChange.detached.many' });
|
|
1657
|
+
this.onEdgesChangeAdd = outputFromObservable(this.edgeChangesOfType('add'), { alias: 'onEdgesChange.add' });
|
|
1658
|
+
this.onEdgeChangeAddSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.single' });
|
|
1659
|
+
this.onEdgeChangeAddMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('add')), { alias: 'onEdgesChange.add.many' });
|
|
1660
|
+
this.onEdgeChangeRemove = outputFromObservable(this.edgeChangesOfType('remove'), { alias: 'onEdgesChange.remove' });
|
|
1661
|
+
this.onEdgeChangeRemoveSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.single' });
|
|
1662
|
+
this.onEdgeChangeRemoveMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('remove')), { alias: 'onEdgesChange.remove.many' });
|
|
1663
|
+
this.onEdgeChangeSelect = outputFromObservable(this.edgeChangesOfType('select'), { alias: 'onEdgesChange.select' });
|
|
1664
|
+
this.onEdgeChangeSelectSingle = outputFromObservable(this.singleChange(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.single' });
|
|
1665
|
+
this.onEdgeChangeSelectMany = outputFromObservable(this.manyChanges(this.edgeChangesOfType('select')), { alias: 'onEdgesChange.select.many' });
|
|
1452
1666
|
}
|
|
1453
1667
|
nodeChangesOfType(type) {
|
|
1454
|
-
return this.nodesChangeService.changes$.pipe(map(changes => changes.filter((c) => c.type === type)), filter(changes => !!changes.length));
|
|
1668
|
+
return this.nodesChangeService.changes$.pipe(map((changes) => changes.filter((c) => c.type === type)), filter((changes) => !!changes.length));
|
|
1455
1669
|
}
|
|
1456
1670
|
edgeChangesOfType(type) {
|
|
1457
|
-
return this.edgesChangeService.changes$.pipe(map(changes => changes.filter((c) => c.type === type)), filter(changes => !!changes.length));
|
|
1671
|
+
return this.edgesChangeService.changes$.pipe(map((changes) => changes.filter((c) => c.type === type)), filter((changes) => !!changes.length));
|
|
1458
1672
|
}
|
|
1459
1673
|
singleChange(changes$) {
|
|
1460
|
-
return changes$.pipe(filter(changes => changes.length === 1), map(([first]) => first));
|
|
1674
|
+
return changes$.pipe(filter((changes) => changes.length === 1), map(([first]) => first));
|
|
1461
1675
|
}
|
|
1462
1676
|
manyChanges(changes$) {
|
|
1463
|
-
return changes$.pipe(filter(changes => changes.length > 1));
|
|
1677
|
+
return changes$.pipe(filter((changes) => changes.length > 1));
|
|
1464
1678
|
}
|
|
1465
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1466
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1679
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChangesControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1680
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ChangesControllerDirective, isStandalone: true, selector: "[changesController]", outputs: { onNodesChange: "onNodesChange", onNodesChangePosition: "onNodesChange.position", onNodesChangePositionSignle: "onNodesChange.position.single", onNodesChangePositionMany: "onNodesChange.position.many", onNodesChangeSize: "onNodesChange.size", onNodesChangeSizeSingle: "onNodesChange.size.single", onNodesChangeSizeMany: "onNodesChange.size.many", onNodesChangeAdd: "onNodesChange.add", onNodesChangeAddSingle: "onNodesChange.add.single", onNodesChangeAddMany: "onNodesChange.add.many", onNodesChangeRemove: "onNodesChange.remove", onNodesChangeRemoveSingle: "onNodesChange.remove.single", onNodesChangeRemoveMany: "onNodesChange.remove.many", onNodesChangeSelect: "onNodesChange.select", onNodesChangeSelectSingle: "onNodesChange.select.single", onNodesChangeSelectMany: "onNodesChange.select.many", onEdgesChange: "onEdgesChange", onNodesChangeDetached: "onEdgesChange.detached", onNodesChangeDetachedSingle: "onEdgesChange.detached.single", onNodesChangeDetachedMany: "onEdgesChange.detached.many", onEdgesChangeAdd: "onEdgesChange.add", onEdgeChangeAddSingle: "onEdgesChange.add.single", onEdgeChangeAddMany: "onEdgesChange.add.many", onEdgeChangeRemove: "onEdgesChange.remove", onEdgeChangeRemoveSingle: "onEdgesChange.remove.single", onEdgeChangeRemoveMany: "onEdgesChange.remove.many", onEdgeChangeSelect: "onEdgesChange.select", onEdgeChangeSelectSingle: "onEdgesChange.select.single", onEdgeChangeSelectMany: "onEdgesChange.select.many" }, ngImport: i0 }); }
|
|
1467
1681
|
}
|
|
1468
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1682
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChangesControllerDirective, decorators: [{
|
|
1469
1683
|
type: Directive,
|
|
1470
1684
|
args: [{
|
|
1471
1685
|
selector: '[changesController]',
|
|
1472
|
-
standalone: true
|
|
1686
|
+
standalone: true,
|
|
1473
1687
|
}]
|
|
1474
|
-
}]
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
}], onNodesChangePositionSignle: [{
|
|
1480
|
-
type: Output,
|
|
1481
|
-
args: ['onNodesChange.position.single']
|
|
1482
|
-
}], onNodesChangePositionMany: [{
|
|
1483
|
-
type: Output,
|
|
1484
|
-
args: ['onNodesChange.position.many']
|
|
1485
|
-
}], onNodesChangeSize: [{
|
|
1486
|
-
type: Output,
|
|
1487
|
-
args: ['onNodesChange.size']
|
|
1488
|
-
}], onNodesChangeSizeSingle: [{
|
|
1489
|
-
type: Output,
|
|
1490
|
-
args: ['onNodesChange.size.single']
|
|
1491
|
-
}], onNodesChangeSizeMany: [{
|
|
1492
|
-
type: Output,
|
|
1493
|
-
args: ['onNodesChange.size.many']
|
|
1494
|
-
}], onNodesChangeAdd: [{
|
|
1495
|
-
type: Output,
|
|
1496
|
-
args: ['onNodesChange.add']
|
|
1497
|
-
}], onNodesChangeAddSingle: [{
|
|
1498
|
-
type: Output,
|
|
1499
|
-
args: ['onNodesChange.add.single']
|
|
1500
|
-
}], onNodesChangeAddMany: [{
|
|
1501
|
-
type: Output,
|
|
1502
|
-
args: ['onNodesChange.add.many']
|
|
1503
|
-
}], onNodesChangeRemove: [{
|
|
1504
|
-
type: Output,
|
|
1505
|
-
args: ['onNodesChange.remove']
|
|
1506
|
-
}], onNodesChangeRemoveSingle: [{
|
|
1507
|
-
type: Output,
|
|
1508
|
-
args: ['onNodesChange.remove.single']
|
|
1509
|
-
}], onNodesChangeRemoveMany: [{
|
|
1510
|
-
type: Output,
|
|
1511
|
-
args: ['onNodesChange.remove.many']
|
|
1512
|
-
}], onNodesChangeSelect: [{
|
|
1513
|
-
type: Output,
|
|
1514
|
-
args: ['onNodesChange.select']
|
|
1515
|
-
}], onNodesChangeSelectSingle: [{
|
|
1516
|
-
type: Output,
|
|
1517
|
-
args: ['onNodesChange.select.single']
|
|
1518
|
-
}], onNodesChangeSelectMany: [{
|
|
1519
|
-
type: Output,
|
|
1520
|
-
args: ['onNodesChange.select.many']
|
|
1521
|
-
}], onEdgesChange: [{
|
|
1522
|
-
type: Output
|
|
1523
|
-
}], onNodesChangeDetached: [{
|
|
1524
|
-
type: Output,
|
|
1525
|
-
args: ['onEdgesChange.detached']
|
|
1526
|
-
}], onNodesChangeDetachedSingle: [{
|
|
1527
|
-
type: Output,
|
|
1528
|
-
args: ['onEdgesChange.detached.single']
|
|
1529
|
-
}], onNodesChangeDetachedMany: [{
|
|
1530
|
-
type: Output,
|
|
1531
|
-
args: ['onEdgesChange.detached.many']
|
|
1532
|
-
}], onEdgesChangeAdd: [{
|
|
1533
|
-
type: Output,
|
|
1534
|
-
args: ['onEdgesChange.add']
|
|
1535
|
-
}], onEdgeChangeAddSingle: [{
|
|
1536
|
-
type: Output,
|
|
1537
|
-
args: ['onEdgesChange.add.single']
|
|
1538
|
-
}], onEdgeChangeAddMany: [{
|
|
1539
|
-
type: Output,
|
|
1540
|
-
args: ['onEdgesChange.add.many']
|
|
1541
|
-
}], onEdgeChangeRemove: [{
|
|
1542
|
-
type: Output,
|
|
1543
|
-
args: ['onEdgesChange.remove']
|
|
1544
|
-
}], onEdgeChangeRemoveSingle: [{
|
|
1545
|
-
type: Output,
|
|
1546
|
-
args: ['onEdgesChange.remove.single']
|
|
1547
|
-
}], onEdgeChangeRemoveMany: [{
|
|
1548
|
-
type: Output,
|
|
1549
|
-
args: ['onEdgesChange.remove.many']
|
|
1550
|
-
}], onEdgeChangeSelect: [{
|
|
1551
|
-
type: Output,
|
|
1552
|
-
args: ['onEdgesChange.select']
|
|
1553
|
-
}], onEdgeChangeSelectSingle: [{
|
|
1554
|
-
type: Output,
|
|
1555
|
-
args: ['onEdgesChange.select.single']
|
|
1556
|
-
}], onEdgeChangeSelectMany: [{
|
|
1557
|
-
type: Output,
|
|
1558
|
-
args: ['onEdgesChange.select.many']
|
|
1559
|
-
}] } });
|
|
1688
|
+
}] });
|
|
1689
|
+
|
|
1690
|
+
function isGroupNode(node) {
|
|
1691
|
+
return node.node.type === 'default-group' || node.node.type === 'template-group';
|
|
1692
|
+
}
|
|
1560
1693
|
|
|
1561
1694
|
class NodeRenderingService {
|
|
1562
1695
|
constructor() {
|
|
@@ -1565,6 +1698,12 @@ class NodeRenderingService {
|
|
|
1565
1698
|
return this.flowEntitiesService.nodes()
|
|
1566
1699
|
.sort((aNode, bNode) => aNode.renderOrder() - bNode.renderOrder());
|
|
1567
1700
|
});
|
|
1701
|
+
this.groups = computed(() => {
|
|
1702
|
+
return this.nodes().filter(n => isGroupNode(n));
|
|
1703
|
+
});
|
|
1704
|
+
this.nonGroups = computed(() => {
|
|
1705
|
+
return this.nodes().filter(n => !isGroupNode(n));
|
|
1706
|
+
});
|
|
1568
1707
|
this.maxOrder = computed(() => {
|
|
1569
1708
|
return Math.max(...this.flowEntitiesService.nodes().map((n) => n.renderOrder()));
|
|
1570
1709
|
});
|
|
@@ -1579,10 +1718,10 @@ class NodeRenderingService {
|
|
|
1579
1718
|
.filter(n => n.parent() === node)
|
|
1580
1719
|
.forEach(n => this.pullNode(n));
|
|
1581
1720
|
}
|
|
1582
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1583
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1721
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1722
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService }); }
|
|
1584
1723
|
}
|
|
1585
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1724
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeRenderingService, decorators: [{
|
|
1586
1725
|
type: Injectable
|
|
1587
1726
|
}] });
|
|
1588
1727
|
|
|
@@ -1634,12 +1773,15 @@ class RootPointerDirective {
|
|
|
1634
1773
|
setInitialTouch(event) {
|
|
1635
1774
|
this.initialTouch$.next(event);
|
|
1636
1775
|
}
|
|
1637
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1638
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1776
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootPointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1777
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootPointerDirective, isStandalone: true, selector: "svg[rootPointer]", ngImport: i0 }); }
|
|
1639
1778
|
}
|
|
1640
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1779
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootPointerDirective, decorators: [{
|
|
1641
1780
|
type: Directive,
|
|
1642
|
-
args: [{
|
|
1781
|
+
args: [{
|
|
1782
|
+
standalone: true,
|
|
1783
|
+
selector: 'svg[rootPointer]',
|
|
1784
|
+
}]
|
|
1643
1785
|
}] });
|
|
1644
1786
|
|
|
1645
1787
|
class SpacePointContextDirective {
|
|
@@ -1668,12 +1810,15 @@ class SpacePointContextDirective {
|
|
|
1668
1810
|
point.y = documentPoint.y;
|
|
1669
1811
|
return point.matrixTransform(this.host.getScreenCTM().inverse());
|
|
1670
1812
|
}
|
|
1671
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1672
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1813
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpacePointContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1814
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SpacePointContextDirective, isStandalone: true, selector: "g[spacePointContext]", ngImport: i0 }); }
|
|
1673
1815
|
}
|
|
1674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpacePointContextDirective, decorators: [{
|
|
1675
1817
|
type: Directive,
|
|
1676
|
-
args: [{
|
|
1818
|
+
args: [{
|
|
1819
|
+
standalone: true,
|
|
1820
|
+
selector: 'g[spacePointContext]',
|
|
1821
|
+
}]
|
|
1677
1822
|
}] });
|
|
1678
1823
|
|
|
1679
1824
|
function transformBackground(background) {
|
|
@@ -1710,8 +1855,8 @@ class OverlaysService {
|
|
|
1710
1855
|
removeToolbar(toolbar) {
|
|
1711
1856
|
this.toolbars.update((toolbars) => toolbars.filter(t => t !== toolbar));
|
|
1712
1857
|
}
|
|
1713
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1714
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1858
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1859
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService }); }
|
|
1715
1860
|
}
|
|
1716
1861
|
__decorate([
|
|
1717
1862
|
Microtask
|
|
@@ -1719,10 +1864,105 @@ __decorate([
|
|
|
1719
1864
|
__decorate([
|
|
1720
1865
|
Microtask
|
|
1721
1866
|
], OverlaysService.prototype, "removeToolbar", null);
|
|
1722
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1867
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: OverlaysService, decorators: [{
|
|
1723
1868
|
type: Injectable
|
|
1724
1869
|
}], propDecorators: { addToolbar: [], removeToolbar: [] } });
|
|
1725
1870
|
|
|
1871
|
+
class EdgeLabelComponent {
|
|
1872
|
+
constructor() {
|
|
1873
|
+
// TODO: too many inputs
|
|
1874
|
+
this.model = input.required();
|
|
1875
|
+
this.edgeModel = input.required();
|
|
1876
|
+
this.point = input({ x: 0, y: 0 });
|
|
1877
|
+
this.htmlTemplate = input();
|
|
1878
|
+
this.edgeLabelWrapperRef = viewChild.required('edgeLabelWrapper');
|
|
1879
|
+
/**
|
|
1880
|
+
* Centered point of label
|
|
1881
|
+
*
|
|
1882
|
+
* TODO: maybe put it into EdgeLabelModel
|
|
1883
|
+
*/
|
|
1884
|
+
this.edgeLabelPoint = computed(() => {
|
|
1885
|
+
const point = this.point();
|
|
1886
|
+
const { width, height } = this.model().size();
|
|
1887
|
+
return {
|
|
1888
|
+
x: point.x - width / 2,
|
|
1889
|
+
y: point.y - height / 2,
|
|
1890
|
+
};
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
ngAfterViewInit() {
|
|
1894
|
+
// this is a fix for visual artifact in chrome that for some reason adresses only for edge label.
|
|
1895
|
+
// the bug reproduces if edgeLabelWrapperRef size fully matched the size of parent foreignObject
|
|
1896
|
+
const MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME = 2;
|
|
1897
|
+
const width = this.edgeLabelWrapperRef().nativeElement.clientWidth +
|
|
1898
|
+
MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
|
|
1899
|
+
const height = this.edgeLabelWrapperRef().nativeElement.clientHeight +
|
|
1900
|
+
MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
|
|
1901
|
+
this.model().size.set({ width, height });
|
|
1902
|
+
}
|
|
1903
|
+
getLabelContext() {
|
|
1904
|
+
return {
|
|
1905
|
+
$implicit: {
|
|
1906
|
+
edge: this.edgeModel().edge,
|
|
1907
|
+
label: this.model().edgeLabel,
|
|
1908
|
+
},
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1912
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeLabelComponent, isStandalone: true, selector: "g[edgeLabel]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeModel: { classPropertyName: "edgeModel", publicName: "edgeModel", isSignal: true, isRequired: true, transformFunction: null }, point: { classPropertyName: "point", publicName: "point", isSignal: true, isRequired: false, transformFunction: null }, htmlTemplate: { classPropertyName: "htmlTemplate", publicName: "htmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "@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 >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1913
|
+
}
|
|
1914
|
+
__decorate([
|
|
1915
|
+
Microtask
|
|
1916
|
+
], EdgeLabelComponent.prototype, "ngAfterViewInit", null);
|
|
1917
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeLabelComponent, decorators: [{
|
|
1918
|
+
type: Component,
|
|
1919
|
+
args: [{ standalone: true, selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: "@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 >\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n </svg:foreignObject>\n }\n}\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
|
|
1920
|
+
}], propDecorators: { ngAfterViewInit: [] } });
|
|
1921
|
+
|
|
1922
|
+
class EdgeComponent {
|
|
1923
|
+
constructor() {
|
|
1924
|
+
this.injector = inject(Injector);
|
|
1925
|
+
this.selectionService = inject(SelectionService);
|
|
1926
|
+
this.flowSettingsService = inject(FlowSettingsService);
|
|
1927
|
+
this.model = input.required();
|
|
1928
|
+
this.edgeTemplate = input();
|
|
1929
|
+
this.edgeLabelHtmlTemplate = input();
|
|
1930
|
+
this.markerStartUrl = computed(() => {
|
|
1931
|
+
const marker = this.model().edge.markers?.start;
|
|
1932
|
+
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1933
|
+
});
|
|
1934
|
+
this.markerEndUrl = computed(() => {
|
|
1935
|
+
const marker = this.model().edge.markers?.end;
|
|
1936
|
+
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
ngOnInit() {
|
|
1940
|
+
this.edgeContext = {
|
|
1941
|
+
$implicit: {
|
|
1942
|
+
// TODO: check if edge could change
|
|
1943
|
+
edge: this.model().edge,
|
|
1944
|
+
path: computed(() => this.model().path().path),
|
|
1945
|
+
markerStart: this.markerStartUrl,
|
|
1946
|
+
markerEnd: this.markerEndUrl,
|
|
1947
|
+
selected: this.model().selected.asReadonly(),
|
|
1948
|
+
},
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
onEdgeMouseDown() {
|
|
1952
|
+
if (this.flowSettingsService.entitiesSelectable()) {
|
|
1953
|
+
this.selectionService.select(this.model());
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1957
|
+
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 (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\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\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\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\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", 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 }); }
|
|
1958
|
+
}
|
|
1959
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
|
|
1960
|
+
type: Component,
|
|
1961
|
+
args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1962
|
+
class: 'selectable',
|
|
1963
|
+
}, imports: [NgTemplateOutlet, EdgeLabelComponent], template: "@if (model().type === \"default\") {\n <svg:path\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model().selected()\"\n />\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\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\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\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", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
|
|
1964
|
+
}] });
|
|
1965
|
+
|
|
1726
1966
|
class HandleService {
|
|
1727
1967
|
constructor() {
|
|
1728
1968
|
this.node = signal(null);
|
|
@@ -1739,13 +1979,13 @@ class HandleService {
|
|
|
1739
1979
|
node.handles.update(handles => handles.filter(handle => handle !== handleToDestoy));
|
|
1740
1980
|
}
|
|
1741
1981
|
}
|
|
1742
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1743
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1982
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1983
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService }); }
|
|
1744
1984
|
}
|
|
1745
1985
|
__decorate([
|
|
1746
1986
|
Microtask // TODO fixes rendering of handle for group node
|
|
1747
1987
|
], HandleService.prototype, "createHandle", null);
|
|
1748
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1988
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleService, decorators: [{
|
|
1749
1989
|
type: Injectable
|
|
1750
1990
|
}], propDecorators: { createHandle: [] } });
|
|
1751
1991
|
|
|
@@ -1776,176 +2016,71 @@ const implementsWithInjector = (instance) => {
|
|
|
1776
2016
|
return 'injector' in instance && 'get' in instance.injector;
|
|
1777
2017
|
};
|
|
1778
2018
|
|
|
1779
|
-
|
|
1780
|
-
* Service to fix cyclic dependency between node and resizable component
|
|
1781
|
-
*/
|
|
1782
|
-
class NodeAccessorService {
|
|
2019
|
+
class HandleSizeControllerDirective {
|
|
1783
2020
|
constructor() {
|
|
1784
|
-
this.
|
|
2021
|
+
this.handleModel = input.required({
|
|
2022
|
+
alias: 'handleSizeController',
|
|
2023
|
+
});
|
|
2024
|
+
this.handleWrapper = inject(ElementRef);
|
|
2025
|
+
}
|
|
2026
|
+
ngAfterViewInit() {
|
|
2027
|
+
const element = this.handleWrapper.nativeElement;
|
|
2028
|
+
const rect = element.getBBox();
|
|
2029
|
+
const stroke = getChildStrokeWidth(element);
|
|
2030
|
+
this.handleModel().size.set({
|
|
2031
|
+
width: rect.width + stroke,
|
|
2032
|
+
height: rect.height + stroke,
|
|
2033
|
+
});
|
|
1785
2034
|
}
|
|
1786
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1787
|
-
static { this.ɵ
|
|
2035
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2036
|
+
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 }); }
|
|
1788
2037
|
}
|
|
1789
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1790
|
-
type:
|
|
2038
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleSizeControllerDirective, decorators: [{
|
|
2039
|
+
type: Directive,
|
|
2040
|
+
args: [{
|
|
2041
|
+
standalone: true,
|
|
2042
|
+
selector: '[handleSizeController]',
|
|
2043
|
+
}]
|
|
1791
2044
|
}] });
|
|
2045
|
+
function getChildStrokeWidth(element) {
|
|
2046
|
+
const child = element.firstElementChild;
|
|
2047
|
+
if (child) {
|
|
2048
|
+
const stroke = getComputedStyle(child).strokeWidth;
|
|
2049
|
+
const strokeAsNumber = Number(stroke.replace('px', ''));
|
|
2050
|
+
if (isNaN(strokeAsNumber)) {
|
|
2051
|
+
return 0;
|
|
2052
|
+
}
|
|
2053
|
+
return strokeAsNumber;
|
|
2054
|
+
}
|
|
2055
|
+
return 0;
|
|
2056
|
+
}
|
|
1792
2057
|
|
|
1793
2058
|
class DefaultNodeComponent {
|
|
1794
2059
|
constructor() {
|
|
1795
|
-
this.selected = false;
|
|
2060
|
+
this.selected = input(false);
|
|
1796
2061
|
}
|
|
1797
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1798
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2062
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2063
|
+
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"] }); }
|
|
1799
2064
|
}
|
|
1800
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2065
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultNodeComponent, decorators: [{
|
|
1801
2066
|
type: Component,
|
|
1802
|
-
args: [{ selector: 'default-node', host: {
|
|
1803
|
-
'[class.selected]': 'selected'
|
|
2067
|
+
args: [{ standalone: true, selector: 'default-node', host: {
|
|
2068
|
+
'[class.selected]': 'selected()',
|
|
1804
2069
|
}, 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"] }]
|
|
1805
|
-
}]
|
|
1806
|
-
type: Input
|
|
1807
|
-
}] } });
|
|
2070
|
+
}] });
|
|
1808
2071
|
|
|
1809
|
-
class
|
|
1810
|
-
constructor(
|
|
1811
|
-
this.
|
|
1812
|
-
this.
|
|
1813
|
-
this.
|
|
2072
|
+
class PointerDirective {
|
|
2073
|
+
constructor() {
|
|
2074
|
+
this.hostElement = inject(ElementRef).nativeElement;
|
|
2075
|
+
this.pointerMovementDirective = inject(RootPointerDirective);
|
|
2076
|
+
this.pointerOver = output();
|
|
2077
|
+
this.pointerOut = output();
|
|
1814
2078
|
/**
|
|
1815
|
-
*
|
|
1816
|
-
*
|
|
2079
|
+
* @todo the Angular may somehow ignore the event.
|
|
2080
|
+
* reproduced here: https://www.ngx-vflow.org/workshops/layout/vizdom-layout
|
|
1817
2081
|
*/
|
|
1818
|
-
this.
|
|
1819
|
-
|
|
1820
|
-
height: 10 + (2 * this.strokeWidth)
|
|
1821
|
-
});
|
|
1822
|
-
this.offset = computed(() => {
|
|
1823
|
-
switch (this.rawHandle.position) {
|
|
1824
|
-
case 'left': return {
|
|
1825
|
-
x: 0,
|
|
1826
|
-
y: this.parentPosition().y + (this.parentSize().height / 2)
|
|
1827
|
-
};
|
|
1828
|
-
case 'right': return {
|
|
1829
|
-
x: this.parentNode.size().width,
|
|
1830
|
-
y: this.parentPosition().y + (this.parentSize().height / 2)
|
|
1831
|
-
};
|
|
1832
|
-
case 'top': return {
|
|
1833
|
-
x: this.parentPosition().x + (this.parentSize().width / 2),
|
|
1834
|
-
y: 0
|
|
1835
|
-
};
|
|
1836
|
-
case 'bottom': return {
|
|
1837
|
-
x: this.parentPosition().x + this.parentSize().width / 2,
|
|
1838
|
-
y: this.parentNode.size().height
|
|
1839
|
-
};
|
|
1840
|
-
}
|
|
1841
|
-
});
|
|
1842
|
-
this.sizeOffset = computed(() => {
|
|
1843
|
-
switch (this.rawHandle.position) {
|
|
1844
|
-
case 'left': return { x: -(this.size().width / 2), y: 0 };
|
|
1845
|
-
case 'right': return { x: this.size().width / 2, y: 0 };
|
|
1846
|
-
case 'top': return { x: 0, y: -(this.size().height / 2) };
|
|
1847
|
-
case 'bottom': return { x: 0, y: this.size().height / 2 };
|
|
1848
|
-
}
|
|
1849
|
-
});
|
|
1850
|
-
this.pointAbsolute = computed(() => {
|
|
1851
|
-
return {
|
|
1852
|
-
x: this.parentNode.globalPoint().x + this.offset().x + this.sizeOffset().x,
|
|
1853
|
-
y: this.parentNode.globalPoint().y + this.offset().y + this.sizeOffset().y,
|
|
1854
|
-
};
|
|
1855
|
-
});
|
|
1856
|
-
this.state = signal('idle');
|
|
1857
|
-
this.updateParentSizeAndPosition$ = new Subject();
|
|
1858
|
-
this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
|
|
1859
|
-
initialValue: { width: 0, height: 0 }
|
|
1860
|
-
});
|
|
1861
|
-
this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
|
|
1862
|
-
x: this.parentReference instanceof HTMLElement
|
|
1863
|
-
? this.parentReference.offsetLeft
|
|
1864
|
-
: 0,
|
|
1865
|
-
y: this.parentReference instanceof HTMLElement
|
|
1866
|
-
? this.parentReference.offsetTop
|
|
1867
|
-
: 0 // for now just 0 for group nodes
|
|
1868
|
-
}))), {
|
|
1869
|
-
initialValue: { x: 0, y: 0 }
|
|
1870
|
-
});
|
|
1871
|
-
this.parentReference = this.rawHandle.parentReference;
|
|
1872
|
-
this.template = this.rawHandle.template;
|
|
1873
|
-
this.templateContext = {
|
|
1874
|
-
$implicit: {
|
|
1875
|
-
point: this.offset,
|
|
1876
|
-
state: this.state,
|
|
1877
|
-
node: this.parentNode.node
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
}
|
|
1881
|
-
updateParent() {
|
|
1882
|
-
this.updateParentSizeAndPosition$.next();
|
|
1883
|
-
}
|
|
1884
|
-
getParentSize() {
|
|
1885
|
-
if (this.parentReference instanceof HTMLElement) {
|
|
1886
|
-
return {
|
|
1887
|
-
width: this.parentReference.offsetWidth,
|
|
1888
|
-
height: this.parentReference.offsetHeight
|
|
1889
|
-
};
|
|
1890
|
-
}
|
|
1891
|
-
else if (this.parentReference instanceof SVGGraphicsElement) {
|
|
1892
|
-
return this.parentReference.getBBox();
|
|
1893
|
-
}
|
|
1894
|
-
return { width: 0, height: 0 };
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
class HandleComponent {
|
|
1899
|
-
constructor() {
|
|
1900
|
-
this.injector = inject(Injector);
|
|
1901
|
-
this.handleService = inject(HandleService);
|
|
1902
|
-
this.element = inject(ElementRef).nativeElement;
|
|
1903
|
-
this.destroyRef = inject(DestroyRef);
|
|
1904
|
-
}
|
|
1905
|
-
ngOnInit() {
|
|
1906
|
-
const node = this.handleService.node();
|
|
1907
|
-
if (node) {
|
|
1908
|
-
this.model = new HandleModel({
|
|
1909
|
-
position: this.position,
|
|
1910
|
-
type: this.type,
|
|
1911
|
-
id: this.id,
|
|
1912
|
-
parentReference: this.element.parentElement,
|
|
1913
|
-
template: this.template
|
|
1914
|
-
}, node);
|
|
1915
|
-
this.handleService.createHandle(this.model);
|
|
1916
|
-
requestAnimationFrame(() => this.model.updateParent());
|
|
1917
|
-
this.destroyRef.onDestroy(() => this.handleService.destroyHandle(this.model));
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1921
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HandleComponent, selector: "handle", inputs: { position: "position", type: "type", id: "id", template: "template" }, ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1922
|
-
}
|
|
1923
|
-
__decorate([
|
|
1924
|
-
InjectionContext
|
|
1925
|
-
], HandleComponent.prototype, "ngOnInit", null);
|
|
1926
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleComponent, decorators: [{
|
|
1927
|
-
type: Component,
|
|
1928
|
-
args: [{ selector: 'handle', changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
|
|
1929
|
-
}], propDecorators: { position: [{
|
|
1930
|
-
type: Input,
|
|
1931
|
-
args: [{ required: true }]
|
|
1932
|
-
}], type: [{
|
|
1933
|
-
type: Input,
|
|
1934
|
-
args: [{ required: true }]
|
|
1935
|
-
}], id: [{
|
|
1936
|
-
type: Input
|
|
1937
|
-
}], template: [{
|
|
1938
|
-
type: Input
|
|
1939
|
-
}], ngOnInit: [] } });
|
|
1940
|
-
|
|
1941
|
-
class PointerDirective {
|
|
1942
|
-
constructor() {
|
|
1943
|
-
this.hostElement = inject(ElementRef).nativeElement;
|
|
1944
|
-
this.pointerMovementDirective = inject(RootPointerDirective);
|
|
1945
|
-
this.pointerOver = new EventEmitter();
|
|
1946
|
-
this.pointerOut = new EventEmitter();
|
|
1947
|
-
this.pointerStart = new EventEmitter();
|
|
1948
|
-
this.pointerEnd = new EventEmitter();
|
|
2082
|
+
this.pointerStart = output();
|
|
2083
|
+
this.pointerEnd = output();
|
|
1949
2084
|
this.wasPointerOver = false;
|
|
1950
2085
|
// TODO check if i could avoid global touch end
|
|
1951
2086
|
this.touchEnd = this.pointerMovementDirective.touchEnd$
|
|
@@ -1986,21 +2121,16 @@ class PointerDirective {
|
|
|
1986
2121
|
this.wasPointerOver = false;
|
|
1987
2122
|
}
|
|
1988
2123
|
}
|
|
1989
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1990
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
2124
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PointerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2125
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: PointerDirective, isStandalone: true, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: { pointerOver: "pointerOver", pointerOut: "pointerOut", pointerStart: "pointerStart", pointerEnd: "pointerEnd" }, host: { listeners: { "mousedown": "onPointerStart($event)", "touchstart": "onPointerStart($event)", "mouseup": "onPointerEnd($event)", "mouseover": "onMouseOver($event)", "mouseout": "onMouseOut($event)" } }, ngImport: i0 }); }
|
|
1991
2126
|
}
|
|
1992
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PointerDirective, decorators: [{
|
|
1993
2128
|
type: Directive,
|
|
1994
|
-
args: [{
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
}], pointerStart: [{
|
|
2000
|
-
type: Output
|
|
2001
|
-
}], pointerEnd: [{
|
|
2002
|
-
type: Output
|
|
2003
|
-
}], onPointerStart: [{
|
|
2129
|
+
args: [{
|
|
2130
|
+
standalone: true,
|
|
2131
|
+
selector: '[pointerStart], [pointerEnd], [pointerOver], [pointerOut]',
|
|
2132
|
+
}]
|
|
2133
|
+
}], propDecorators: { onPointerStart: [{
|
|
2004
2134
|
type: HostListener,
|
|
2005
2135
|
args: ['mousedown', ['$event']]
|
|
2006
2136
|
}, {
|
|
@@ -2018,14 +2148,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2018
2148
|
}] } });
|
|
2019
2149
|
|
|
2020
2150
|
class ResizableComponent {
|
|
2151
|
+
get model() {
|
|
2152
|
+
return this.nodeAccessor.model();
|
|
2153
|
+
}
|
|
2021
2154
|
constructor() {
|
|
2022
2155
|
this.nodeAccessor = inject(NodeAccessorService);
|
|
2023
2156
|
this.rootPointer = inject(RootPointerDirective);
|
|
2024
2157
|
this.viewportService = inject(ViewportService);
|
|
2025
2158
|
this.spacePointContext = inject(SpacePointContextDirective);
|
|
2026
2159
|
this.hostRef = inject(ElementRef);
|
|
2027
|
-
this.
|
|
2028
|
-
this.
|
|
2160
|
+
this.resizable = input();
|
|
2161
|
+
this.resizerColor = input('#2e414c');
|
|
2162
|
+
this.gap = input(1.5);
|
|
2163
|
+
this.resizer = viewChild.required('resizer');
|
|
2029
2164
|
this.lineGap = 3;
|
|
2030
2165
|
this.handleSize = 6;
|
|
2031
2166
|
this.resizeSide = null;
|
|
@@ -2039,24 +2174,24 @@ class ResizableComponent {
|
|
|
2039
2174
|
this.endResizeOnGlobalMouseUp = this.rootPointer.documentPointerEnd$
|
|
2040
2175
|
.pipe(tap(() => this.endResize()), takeUntilDestroyed())
|
|
2041
2176
|
.subscribe();
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
get model() {
|
|
2052
|
-
return this.nodeAccessor.model();
|
|
2177
|
+
effect(() => {
|
|
2178
|
+
const resizable = this.resizable();
|
|
2179
|
+
if (typeof resizable === 'boolean') {
|
|
2180
|
+
this.model.resizable.set(resizable);
|
|
2181
|
+
}
|
|
2182
|
+
else {
|
|
2183
|
+
this.model.resizable.set(true);
|
|
2184
|
+
}
|
|
2185
|
+
}, { allowSignalWrites: true });
|
|
2053
2186
|
}
|
|
2054
2187
|
ngOnInit() {
|
|
2055
|
-
this.model.resizerTemplate.set(this.resizer);
|
|
2188
|
+
this.model.resizerTemplate.set(this.resizer());
|
|
2056
2189
|
}
|
|
2057
2190
|
ngAfterViewInit() {
|
|
2058
|
-
this.minWidth =
|
|
2059
|
-
|
|
2191
|
+
this.minWidth =
|
|
2192
|
+
+getComputedStyle(this.hostRef.nativeElement).minWidth.replace('px', '') || 0;
|
|
2193
|
+
this.minHeight =
|
|
2194
|
+
+getComputedStyle(this.hostRef.nativeElement).minHeight.replace('px', '') || 0;
|
|
2060
2195
|
}
|
|
2061
2196
|
startResize(side, event) {
|
|
2062
2197
|
event.stopPropagation();
|
|
@@ -2077,13 +2212,15 @@ class ResizableComponent {
|
|
|
2077
2212
|
this.resizeSide = null;
|
|
2078
2213
|
this.model.resizing.set(false);
|
|
2079
2214
|
}
|
|
2080
|
-
isResizeConstrained({ x, y, movementX, movementY }) {
|
|
2215
|
+
isResizeConstrained({ x, y, movementX, movementY, }) {
|
|
2081
2216
|
const flowPoint = this.spacePointContext.documentPointToFlowPoint({ x, y });
|
|
2082
2217
|
if (this.resizeSide?.includes('right')) {
|
|
2083
|
-
if (movementX > 0 &&
|
|
2218
|
+
if (movementX > 0 &&
|
|
2219
|
+
flowPoint.x < this.model.point().x + this.model.size().width) {
|
|
2084
2220
|
return true;
|
|
2085
2221
|
}
|
|
2086
|
-
if (movementX < 0 &&
|
|
2222
|
+
if (movementX < 0 &&
|
|
2223
|
+
flowPoint.x > this.model.point().x + this.model.size().width) {
|
|
2087
2224
|
return true;
|
|
2088
2225
|
}
|
|
2089
2226
|
}
|
|
@@ -2096,10 +2233,12 @@ class ResizableComponent {
|
|
|
2096
2233
|
}
|
|
2097
2234
|
}
|
|
2098
2235
|
if (this.resizeSide?.includes('bottom')) {
|
|
2099
|
-
if (movementY > 0 &&
|
|
2236
|
+
if (movementY > 0 &&
|
|
2237
|
+
flowPoint.y < this.model.point().y + this.model.size().height) {
|
|
2100
2238
|
return true;
|
|
2101
2239
|
}
|
|
2102
|
-
if (movementY < 0 &&
|
|
2240
|
+
if (movementY < 0 &&
|
|
2241
|
+
flowPoint.y > this.model.point().y + this.model.size().height) {
|
|
2103
2242
|
return true;
|
|
2104
2243
|
}
|
|
2105
2244
|
}
|
|
@@ -2113,29 +2252,20 @@ class ResizableComponent {
|
|
|
2113
2252
|
}
|
|
2114
2253
|
return false;
|
|
2115
2254
|
}
|
|
2116
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2117
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2255
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2256
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: ResizableComponent, isStandalone: true, selector: "[resizable]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizerColor: { classPropertyName: "resizerColor", publicName: "resizerColor", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "resizer", first: true, predicate: ["resizer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"], dependencies: [{ kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }] }); }
|
|
2118
2257
|
}
|
|
2119
2258
|
__decorate([
|
|
2120
2259
|
Microtask
|
|
2121
2260
|
], ResizableComponent.prototype, "ngAfterViewInit", null);
|
|
2122
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2261
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResizableComponent, decorators: [{
|
|
2123
2262
|
type: Component,
|
|
2124
|
-
args: [{ selector: '[resizable]', template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap\"\n [attr.y]=\"-(handleSize / 2) - gap\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width -
|
|
2125
|
-
}], propDecorators: {
|
|
2126
|
-
type: Input
|
|
2127
|
-
}], resizerColor: [{
|
|
2128
|
-
type: Input
|
|
2129
|
-
}], gap: [{
|
|
2130
|
-
type: Input
|
|
2131
|
-
}], resizer: [{
|
|
2132
|
-
type: ViewChild,
|
|
2133
|
-
args: ['resizer', { static: true }]
|
|
2134
|
-
}], ngAfterViewInit: [] } });
|
|
2263
|
+
args: [{ standalone: true, selector: '[resizable]', imports: [PointerDirective], template: "<ng-template #resizer>\n <svg:g>\n <!-- top line -->\n <svg:line\n class=\"top\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"-gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"-gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('top', $event)\"\n />\n <!-- Left line -->\n <svg:line\n class=\"left\"\n [attr.x1]=\"-gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"-gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('left', $event)\"\n />\n <!-- Bottom line -->\n <svg:line\n class=\"bottom\"\n [attr.x1]=\"lineGap\"\n [attr.y1]=\"model.size().height + gap()\"\n [attr.x2]=\"model.size().width - lineGap\"\n [attr.y2]=\"model.size().height + gap()\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('bottom', $event)\"\n />\n <!-- Right line -->\n <svg:line\n class=\"right\"\n [attr.x1]=\"model.size().width + gap()\"\n [attr.y1]=\"lineGap\"\n [attr.x2]=\"model.size().width + gap()\"\n [attr.y2]=\"model.size().height - lineGap\"\n [attr.stroke]=\"resizerColor()\"\n stroke-width=\"2\"\n (pointerStart)=\"startResize('right', $event)\"\n />\n\n <!-- Top Left -->\n <svg:rect\n class=\"top-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-left', $event)\"\n />\n\n <!-- Top right -->\n <svg:rect\n class=\"top-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"-(handleSize / 2) - gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('top-right', $event)\"\n />\n\n <!-- Bottom left -->\n <svg:rect\n class=\"bottom-left\"\n [attr.x]=\"-(handleSize / 2) - gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-left', $event)\"\n />\n\n <!-- Bottom right -->\n <svg:rect\n class=\"bottom-right\"\n [attr.x]=\"model.size().width - handleSize / 2 + gap()\"\n [attr.y]=\"model.size().height - handleSize / 2 + gap()\"\n [attr.width]=\"handleSize\"\n [attr.height]=\"handleSize\"\n [attr.fill]=\"resizerColor()\"\n (pointerStart)=\"startResize('bottom-right', $event)\"\n />\n </svg:g>\n</ng-template>\n\n<ng-content />\n", styles: [".top{cursor:n-resize}.left{cursor:w-resize}.right{cursor:e-resize}.bottom{cursor:s-resize}.top-left{cursor:nw-resize}.top-right{cursor:ne-resize}.bottom-left{cursor:sw-resize}.bottom-right{cursor:se-resize}\n"] }]
|
|
2264
|
+
}], ctorParameters: () => [], propDecorators: { ngAfterViewInit: [] } });
|
|
2135
2265
|
function calcOffset(movementX, movementY, zoom) {
|
|
2136
2266
|
return {
|
|
2137
2267
|
offsetX: round(movementX / zoom),
|
|
2138
|
-
offsetY: round(movementY / zoom)
|
|
2268
|
+
offsetY: round(movementY / zoom),
|
|
2139
2269
|
};
|
|
2140
2270
|
}
|
|
2141
2271
|
function applyResize(side, model, offset) {
|
|
@@ -2153,11 +2283,26 @@ function applyResize(side, model, offset) {
|
|
|
2153
2283
|
case 'bottom':
|
|
2154
2284
|
return { x, y, width, height: height + offsetY };
|
|
2155
2285
|
case 'top-left':
|
|
2156
|
-
return {
|
|
2286
|
+
return {
|
|
2287
|
+
x: x + offsetX,
|
|
2288
|
+
y: y + offsetY,
|
|
2289
|
+
width: width - offsetX,
|
|
2290
|
+
height: height - offsetY,
|
|
2291
|
+
};
|
|
2157
2292
|
case 'top-right':
|
|
2158
|
-
return {
|
|
2293
|
+
return {
|
|
2294
|
+
x,
|
|
2295
|
+
y: y + offsetY,
|
|
2296
|
+
width: width + offsetX,
|
|
2297
|
+
height: height - offsetY,
|
|
2298
|
+
};
|
|
2159
2299
|
case 'bottom-left':
|
|
2160
|
-
return {
|
|
2300
|
+
return {
|
|
2301
|
+
x: x + offsetX,
|
|
2302
|
+
y,
|
|
2303
|
+
width: width - offsetX,
|
|
2304
|
+
height: height + offsetY,
|
|
2305
|
+
};
|
|
2161
2306
|
case 'bottom-right':
|
|
2162
2307
|
return { x, y, width: width + offsetX, height: height + offsetY };
|
|
2163
2308
|
}
|
|
@@ -2191,7 +2336,7 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
|
|
|
2191
2336
|
// 4. Apply child node constraints (if children exist)
|
|
2192
2337
|
if (bounds) {
|
|
2193
2338
|
if (side.includes('left')) {
|
|
2194
|
-
x = Math.min(x,
|
|
2339
|
+
x = Math.min(x, model.point().x + model.size().width - (bounds.x + bounds.width));
|
|
2195
2340
|
width = Math.max(width, bounds.x + bounds.width);
|
|
2196
2341
|
}
|
|
2197
2342
|
if (side.includes('right')) {
|
|
@@ -2201,7 +2346,7 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
|
|
|
2201
2346
|
height = Math.max(height, bounds.y + bounds.height);
|
|
2202
2347
|
}
|
|
2203
2348
|
if (side.includes('top')) {
|
|
2204
|
-
y = Math.min(y,
|
|
2349
|
+
y = Math.min(y, model.point().y + model.size().height - (bounds.y + bounds.height));
|
|
2205
2350
|
height = Math.max(height, bounds.y + bounds.height);
|
|
2206
2351
|
}
|
|
2207
2352
|
}
|
|
@@ -2209,45 +2354,144 @@ function constrainRect(rect, model, side, minWidth, minHeight) {
|
|
|
2209
2354
|
x,
|
|
2210
2355
|
y,
|
|
2211
2356
|
width,
|
|
2212
|
-
height
|
|
2357
|
+
height,
|
|
2213
2358
|
};
|
|
2214
2359
|
}
|
|
2215
2360
|
|
|
2216
|
-
class
|
|
2217
|
-
constructor() {
|
|
2218
|
-
this.
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2361
|
+
class HandleModel {
|
|
2362
|
+
constructor(rawHandle, parentNode) {
|
|
2363
|
+
this.rawHandle = rawHandle;
|
|
2364
|
+
this.parentNode = parentNode;
|
|
2365
|
+
this.strokeWidth = 2;
|
|
2366
|
+
/**
|
|
2367
|
+
* Pre-computed size for default handle, changed dynamically
|
|
2368
|
+
* for custom handles
|
|
2369
|
+
*/
|
|
2370
|
+
this.size = signal({
|
|
2371
|
+
width: 10 + (2 * this.strokeWidth),
|
|
2372
|
+
height: 10 + (2 * this.strokeWidth)
|
|
2227
2373
|
});
|
|
2374
|
+
this.offset = computed(() => {
|
|
2375
|
+
switch (this.rawHandle.position) {
|
|
2376
|
+
case 'left': return {
|
|
2377
|
+
x: 0,
|
|
2378
|
+
y: this.parentPosition().y + (this.parentSize().height / 2)
|
|
2379
|
+
};
|
|
2380
|
+
case 'right': return {
|
|
2381
|
+
x: this.parentNode.size().width,
|
|
2382
|
+
y: this.parentPosition().y + (this.parentSize().height / 2)
|
|
2383
|
+
};
|
|
2384
|
+
case 'top': return {
|
|
2385
|
+
x: this.parentPosition().x + (this.parentSize().width / 2),
|
|
2386
|
+
y: 0
|
|
2387
|
+
};
|
|
2388
|
+
case 'bottom': return {
|
|
2389
|
+
x: this.parentPosition().x + this.parentSize().width / 2,
|
|
2390
|
+
y: this.parentNode.size().height
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
});
|
|
2394
|
+
this.sizeOffset = computed(() => {
|
|
2395
|
+
switch (this.rawHandle.position) {
|
|
2396
|
+
case 'left': return { x: -(this.size().width / 2), y: 0 };
|
|
2397
|
+
case 'right': return { x: this.size().width / 2, y: 0 };
|
|
2398
|
+
case 'top': return { x: 0, y: -(this.size().height / 2) };
|
|
2399
|
+
case 'bottom': return { x: 0, y: this.size().height / 2 };
|
|
2400
|
+
}
|
|
2401
|
+
});
|
|
2402
|
+
this.pointAbsolute = computed(() => {
|
|
2403
|
+
return {
|
|
2404
|
+
x: this.parentNode.globalPoint().x + this.offset().x + this.sizeOffset().x,
|
|
2405
|
+
y: this.parentNode.globalPoint().y + this.offset().y + this.sizeOffset().y,
|
|
2406
|
+
};
|
|
2407
|
+
});
|
|
2408
|
+
this.state = signal('idle');
|
|
2409
|
+
this.updateParentSizeAndPosition$ = new Subject();
|
|
2410
|
+
this.parentSize = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => this.getParentSize())), {
|
|
2411
|
+
initialValue: { width: 0, height: 0 }
|
|
2412
|
+
});
|
|
2413
|
+
this.parentPosition = toSignal(this.updateParentSizeAndPosition$.pipe(map(() => ({
|
|
2414
|
+
x: this.parentReference instanceof HTMLElement
|
|
2415
|
+
? this.parentReference.offsetLeft
|
|
2416
|
+
: 0, // for now just 0 for group nodes
|
|
2417
|
+
y: this.parentReference instanceof HTMLElement
|
|
2418
|
+
? this.parentReference.offsetTop
|
|
2419
|
+
: 0 // for now just 0 for group nodes
|
|
2420
|
+
}))), {
|
|
2421
|
+
initialValue: { x: 0, y: 0 }
|
|
2422
|
+
});
|
|
2423
|
+
this.parentReference = this.rawHandle.parentReference;
|
|
2424
|
+
this.template = this.rawHandle.template;
|
|
2425
|
+
this.templateContext = {
|
|
2426
|
+
$implicit: {
|
|
2427
|
+
point: this.offset,
|
|
2428
|
+
state: this.state,
|
|
2429
|
+
node: this.parentNode.node
|
|
2430
|
+
}
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
updateParent() {
|
|
2434
|
+
this.updateParentSizeAndPosition$.next();
|
|
2435
|
+
}
|
|
2436
|
+
getParentSize() {
|
|
2437
|
+
if (this.parentReference instanceof HTMLElement) {
|
|
2438
|
+
return {
|
|
2439
|
+
width: this.parentReference.offsetWidth,
|
|
2440
|
+
height: this.parentReference.offsetHeight
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
else if (this.parentReference instanceof SVGGraphicsElement) {
|
|
2444
|
+
return this.parentReference.getBBox();
|
|
2445
|
+
}
|
|
2446
|
+
return { width: 0, height: 0 };
|
|
2228
2447
|
}
|
|
2229
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HandleSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2230
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: { handleModel: ["handleSizeController", "handleModel"] }, ngImport: i0 }); }
|
|
2231
2448
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2449
|
+
|
|
2450
|
+
class HandleComponent {
|
|
2451
|
+
constructor() {
|
|
2452
|
+
this.injector = inject(Injector);
|
|
2453
|
+
this.handleService = inject(HandleService);
|
|
2454
|
+
this.element = inject(ElementRef).nativeElement;
|
|
2455
|
+
this.destroyRef = inject(DestroyRef);
|
|
2456
|
+
/**
|
|
2457
|
+
* At what side of node this component should be placed
|
|
2458
|
+
*/
|
|
2459
|
+
this.position = input.required();
|
|
2460
|
+
/**
|
|
2461
|
+
* Source or target
|
|
2462
|
+
*/
|
|
2463
|
+
this.type = input.required();
|
|
2464
|
+
/**
|
|
2465
|
+
* Should be used if node has more than one source/target
|
|
2466
|
+
*/
|
|
2467
|
+
this.id = input();
|
|
2468
|
+
this.template = input();
|
|
2469
|
+
}
|
|
2470
|
+
ngOnInit() {
|
|
2471
|
+
const node = this.handleService.node();
|
|
2472
|
+
if (node) {
|
|
2473
|
+
this.model = new HandleModel({
|
|
2474
|
+
position: this.position(),
|
|
2475
|
+
type: this.type(),
|
|
2476
|
+
id: this.id(),
|
|
2477
|
+
parentReference: this.element.parentElement,
|
|
2478
|
+
template: this.template(),
|
|
2479
|
+
}, node);
|
|
2480
|
+
this.handleService.createHandle(this.model);
|
|
2481
|
+
requestAnimationFrame(() => this.model.updateParent());
|
|
2482
|
+
this.destroyRef.onDestroy(() => this.handleService.destroyHandle(this.model));
|
|
2246
2483
|
}
|
|
2247
|
-
return strokeAsNumber;
|
|
2248
2484
|
}
|
|
2249
|
-
|
|
2485
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2486
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: HandleComponent, isStandalone: true, selector: "handle", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2250
2487
|
}
|
|
2488
|
+
__decorate([
|
|
2489
|
+
InjectionContext
|
|
2490
|
+
], HandleComponent.prototype, "ngOnInit", null);
|
|
2491
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HandleComponent, decorators: [{
|
|
2492
|
+
type: Component,
|
|
2493
|
+
args: [{ standalone: true, selector: 'handle', changeDetection: ChangeDetectionStrategy.OnPush, template: "" }]
|
|
2494
|
+
}], propDecorators: { ngOnInit: [] } });
|
|
2251
2495
|
|
|
2252
2496
|
class NodeComponent {
|
|
2253
2497
|
constructor() {
|
|
@@ -2263,40 +2507,47 @@ class NodeComponent {
|
|
|
2263
2507
|
this.nodeAccessor = inject(NodeAccessorService);
|
|
2264
2508
|
this.overlaysService = inject(OverlaysService);
|
|
2265
2509
|
this.zone = inject(NgZone);
|
|
2510
|
+
this.nodeModel = input.required();
|
|
2511
|
+
this.nodeTemplate = input();
|
|
2512
|
+
this.groupNodeTemplate = input();
|
|
2513
|
+
this.htmlWrapperRef = viewChild.required('htmlWrapper');
|
|
2266
2514
|
this.showMagnet = computed(() => this.flowStatusService.status().state === 'connection-start' ||
|
|
2267
2515
|
this.flowStatusService.status().state === 'connection-validation');
|
|
2268
|
-
this.styleWidth = computed(() => `${this.nodeModel.size().width}px`);
|
|
2269
|
-
this.styleHeight = computed(() => `${this.nodeModel.size().height}px`);
|
|
2270
|
-
this.toolbar = computed(() => this.overlaysService.nodeToolbars().get(this.nodeModel));
|
|
2516
|
+
this.styleWidth = computed(() => `${this.nodeModel().size().width}px`);
|
|
2517
|
+
this.styleHeight = computed(() => `${this.nodeModel().size().height}px`);
|
|
2518
|
+
this.toolbar = computed(() => this.overlaysService.nodeToolbars().get(this.nodeModel()));
|
|
2271
2519
|
}
|
|
2272
2520
|
ngOnInit() {
|
|
2273
|
-
this.nodeAccessor.model.set(this.nodeModel);
|
|
2274
|
-
this.handleService.node.set(this.nodeModel);
|
|
2521
|
+
this.nodeAccessor.model.set(this.nodeModel());
|
|
2522
|
+
this.handleService.node.set(this.nodeModel());
|
|
2275
2523
|
effect(() => {
|
|
2276
|
-
if (this.nodeModel.draggable()) {
|
|
2277
|
-
this.draggableService.enable(this.hostRef.nativeElement, this.nodeModel);
|
|
2524
|
+
if (this.nodeModel().draggable()) {
|
|
2525
|
+
this.draggableService.enable(this.hostRef.nativeElement, this.nodeModel());
|
|
2278
2526
|
}
|
|
2279
2527
|
else {
|
|
2280
2528
|
this.draggableService.disable(this.hostRef.nativeElement);
|
|
2281
2529
|
}
|
|
2282
2530
|
});
|
|
2283
|
-
this.nodeModel
|
|
2284
|
-
.pipe(switchMap((handles) => resizable(handles.map(h => h.parentReference), this.zone)
|
|
2285
|
-
.pipe(map(() => handles))), tap((handles) => {
|
|
2531
|
+
this.nodeModel()
|
|
2532
|
+
.handles$.pipe(switchMap((handles) => resizable(handles.map((h) => h.parentReference), this.zone).pipe(map(() => handles))), tap((handles) => {
|
|
2286
2533
|
// TODO (performance) inspect how to avoid calls of this when flow initially rendered
|
|
2287
|
-
handles.forEach(h => h.updateParent());
|
|
2534
|
+
handles.forEach((h) => h.updateParent());
|
|
2288
2535
|
}), takeUntilDestroyed())
|
|
2289
2536
|
.subscribe();
|
|
2290
2537
|
}
|
|
2291
2538
|
ngAfterViewInit() {
|
|
2292
|
-
this.nodeModel.linkDefaultNodeSizeWithModelSize();
|
|
2293
|
-
if (this.nodeModel.node.type === 'html-template' ||
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
this.nodeModel.
|
|
2299
|
-
|
|
2539
|
+
this.nodeModel().linkDefaultNodeSizeWithModelSize();
|
|
2540
|
+
if (this.nodeModel().node.type === 'html-template' ||
|
|
2541
|
+
this.nodeModel().isComponentType) {
|
|
2542
|
+
resizable([this.htmlWrapperRef().nativeElement], this.zone)
|
|
2543
|
+
.pipe(startWith(null), tap(() => this.nodeModel()
|
|
2544
|
+
.handles()
|
|
2545
|
+
.forEach((h) => h.updateParent())), filter(() => !this.nodeModel().resizing()), tap(() => {
|
|
2546
|
+
const width = this.htmlWrapperRef().nativeElement.clientWidth;
|
|
2547
|
+
const height = this.htmlWrapperRef().nativeElement.clientHeight;
|
|
2548
|
+
this.nodeModel().size.set({ width, height });
|
|
2549
|
+
}), takeUntilDestroyed())
|
|
2550
|
+
.subscribe();
|
|
2300
2551
|
}
|
|
2301
2552
|
}
|
|
2302
2553
|
ngOnDestroy() {
|
|
@@ -2317,15 +2568,15 @@ class NodeComponent {
|
|
|
2317
2568
|
this.connectionController.endConnection(handle);
|
|
2318
2569
|
}
|
|
2319
2570
|
pullNode() {
|
|
2320
|
-
this.nodeRenderingService.pullNode(this.nodeModel);
|
|
2571
|
+
this.nodeRenderingService.pullNode(this.nodeModel());
|
|
2321
2572
|
}
|
|
2322
2573
|
selectNode() {
|
|
2323
2574
|
if (this.flowSettingsService.entitiesSelectable()) {
|
|
2324
|
-
this.selectionService.select(this.nodeModel);
|
|
2575
|
+
this.selectionService.select(this.nodeModel());
|
|
2325
2576
|
}
|
|
2326
2577
|
}
|
|
2327
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2328
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2578
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2579
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NodeComponent, isStandalone: true, selector: "g[node]", inputs: { nodeModel: { classPropertyName: "nodeModel", publicName: "nodeModel", 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], viewQueries: [{ propertyName: "htmlWrapperRef", first: true, predicate: ["htmlWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\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 >\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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: HandleSizeControllerDirective, selector: "[handleSizeController]", inputs: ["handleSizeController"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2329
2580
|
}
|
|
2330
2581
|
__decorate([
|
|
2331
2582
|
InjectionContext
|
|
@@ -2333,130 +2584,25 @@ __decorate([
|
|
|
2333
2584
|
__decorate([
|
|
2334
2585
|
InjectionContext
|
|
2335
2586
|
], NodeComponent.prototype, "ngAfterViewInit", null);
|
|
2336
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2587
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeComponent, decorators: [{
|
|
2337
2588
|
type: Component,
|
|
2338
|
-
args: [{ selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], host: {
|
|
2339
|
-
|
|
2340
|
-
},
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
}], htmlWrapperRef: [{
|
|
2351
|
-
type: ViewChild,
|
|
2352
|
-
args: ['htmlWrapper']
|
|
2353
|
-
}], ngOnInit: [], ngAfterViewInit: [] } });
|
|
2354
|
-
|
|
2355
|
-
class EdgeLabelComponent {
|
|
2356
|
-
constructor() {
|
|
2357
|
-
/**
|
|
2358
|
-
* Centered point of label
|
|
2359
|
-
*
|
|
2360
|
-
* TODO: maybe put it into EdgeLabelModel
|
|
2361
|
-
*/
|
|
2362
|
-
this.edgeLabelPoint = computed(() => {
|
|
2363
|
-
const point = this.pointSignal();
|
|
2364
|
-
const { width, height } = this.model.size();
|
|
2365
|
-
return {
|
|
2366
|
-
x: point.x - (width / 2),
|
|
2367
|
-
y: point.y - (height / 2)
|
|
2368
|
-
};
|
|
2369
|
-
});
|
|
2370
|
-
this.pointSignal = signal({ x: 0, y: 0 });
|
|
2371
|
-
}
|
|
2372
|
-
set point(point) { this.pointSignal.set(point); }
|
|
2373
|
-
ngAfterViewInit() {
|
|
2374
|
-
// this is a fix for visual artifact in chrome that for some reason adresses only for edge label.
|
|
2375
|
-
// the bug reproduces if edgeLabelWrapperRef size fully matched the size of parent foreignObject
|
|
2376
|
-
const MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME = 2;
|
|
2377
|
-
const width = this.edgeLabelWrapperRef.nativeElement.clientWidth + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
|
|
2378
|
-
const height = this.edgeLabelWrapperRef.nativeElement.clientHeight + MAGIC_VALUE_TO_FIX_GLITCH_IN_CHROME;
|
|
2379
|
-
this.model.size.set({ width, height });
|
|
2380
|
-
}
|
|
2381
|
-
getLabelContext() {
|
|
2382
|
-
return {
|
|
2383
|
-
$implicit: {
|
|
2384
|
-
edge: this.edgeModel.edge,
|
|
2385
|
-
label: this.model.edgeLabel
|
|
2386
|
-
}
|
|
2387
|
-
};
|
|
2388
|
-
}
|
|
2389
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2390
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: { model: "model", edgeModel: "edgeModel", point: "point", htmlTemplate: "htmlTemplate" }, viewQueries: [{ propertyName: "edgeLabelWrapperRef", first: true, predicate: ["edgeLabelWrapper"], descendants: true }], ngImport: i0, template: "<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 *ngIf=\"model.edgeLabel.type === 'html-template' && htmlTemplate\"\n>\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n</svg:foreignObject>\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2391
|
-
}
|
|
2392
|
-
__decorate([
|
|
2393
|
-
Microtask
|
|
2394
|
-
], EdgeLabelComponent.prototype, "ngAfterViewInit", null);
|
|
2395
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeLabelComponent, decorators: [{
|
|
2396
|
-
type: Component,
|
|
2397
|
-
args: [{ selector: 'g[edgeLabel]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<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 *ngIf=\"model.edgeLabel.type === 'html-template' && htmlTemplate\"\n>\n <div #edgeLabelWrapper class=\"edge-label-wrapper\">\n <ng-container\n *ngTemplateOutlet=\"htmlTemplate; context: getLabelContext()\"\n />\n </div>\n</svg:foreignObject>\n", styles: [".edge-label-wrapper{width:max-content;margin-top:1px;margin-left:1px}\n"] }]
|
|
2398
|
-
}], propDecorators: { model: [{
|
|
2399
|
-
type: Input
|
|
2400
|
-
}], edgeModel: [{
|
|
2401
|
-
type: Input
|
|
2402
|
-
}], point: [{
|
|
2403
|
-
type: Input
|
|
2404
|
-
}], htmlTemplate: [{
|
|
2405
|
-
type: Input
|
|
2406
|
-
}], edgeLabelWrapperRef: [{
|
|
2407
|
-
type: ViewChild,
|
|
2408
|
-
args: ['edgeLabelWrapper']
|
|
2409
|
-
}], ngAfterViewInit: [] } });
|
|
2410
|
-
|
|
2411
|
-
class EdgeComponent {
|
|
2412
|
-
constructor() {
|
|
2413
|
-
this.injector = inject(Injector);
|
|
2414
|
-
this.selectionService = inject(SelectionService);
|
|
2415
|
-
this.flowSettingsService = inject(FlowSettingsService);
|
|
2416
|
-
this.markerStartUrl = computed(() => {
|
|
2417
|
-
const marker = this.model.edge.markers?.start;
|
|
2418
|
-
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
2419
|
-
});
|
|
2420
|
-
this.markerEndUrl = computed(() => {
|
|
2421
|
-
const marker = this.model.edge.markers?.end;
|
|
2422
|
-
return marker ? `url(#${hashCode(JSON.stringify(marker))})` : '';
|
|
2423
|
-
});
|
|
2424
|
-
}
|
|
2425
|
-
ngOnInit() {
|
|
2426
|
-
this.edgeContext = {
|
|
2427
|
-
$implicit: {
|
|
2428
|
-
// TODO: check if edge could change
|
|
2429
|
-
edge: this.model.edge,
|
|
2430
|
-
path: computed(() => this.model.path().path),
|
|
2431
|
-
markerStart: this.markerStartUrl,
|
|
2432
|
-
markerEnd: this.markerEndUrl,
|
|
2433
|
-
selected: this.model.selected.asReadonly()
|
|
2434
|
-
}
|
|
2435
|
-
};
|
|
2436
|
-
}
|
|
2437
|
-
onEdgeMouseDown() {
|
|
2438
|
-
if (this.flowSettingsService.entitiesSelectable()) {
|
|
2439
|
-
this.selectionService.select(this.model);
|
|
2440
|
-
}
|
|
2441
|
-
}
|
|
2442
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2443
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EdgeComponent, selector: "g[edge]", inputs: { model: "model", edgeTemplate: "edgeTemplate", edgeLabelHtmlTemplate: "edgeLabelHtmlTemplate" }, host: { classAttribute: "selectable" }, ngImport: i0, template: "<svg:path\n *ngIf=\"model.type === 'default'\"\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model.path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model.selected()\"\n/>\n\n<ng-container *ngIf=\"model.type === 'template' && edgeTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n ></ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.start as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.start\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.center as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.center\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.end as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.end\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2444
|
-
}
|
|
2445
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EdgeComponent, decorators: [{
|
|
2446
|
-
type: Component,
|
|
2447
|
-
args: [{ selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2448
|
-
'class': 'selectable'
|
|
2449
|
-
}, template: "<svg:path\n *ngIf=\"model.type === 'default'\"\n (mousedown)=\"onEdgeMouseDown()\"\n [attr.d]=\"model.path().path\"\n [attr.marker-start]=\"markerStartUrl()\"\n [attr.marker-end]=\"markerEndUrl()\"\n class=\"edge\"\n [class.edge_selected]=\"model.selected()\"\n/>\n\n<ng-container *ngIf=\"model.type === 'template' && edgeTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"edgeContext\"\n [ngTemplateOutletInjector]=\"injector\"\n ></ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.start as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.start\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.center as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.center\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n\n<ng-container *ngIf=\"model.edgeLabels?.end as label\">\n <svg:g edgeLabel\n [model]=\"label\"\n [point]=\"model.path().points.end\"\n [edgeModel]=\"model\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate\"\n />\n</ng-container>\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}\n"] }]
|
|
2450
|
-
}], propDecorators: { model: [{
|
|
2451
|
-
type: Input
|
|
2452
|
-
}], edgeTemplate: [{
|
|
2453
|
-
type: Input
|
|
2454
|
-
}], edgeLabelHtmlTemplate: [{
|
|
2455
|
-
type: Input
|
|
2456
|
-
}] } });
|
|
2589
|
+
args: [{ standalone: true, selector: 'g[node]', changeDetection: ChangeDetectionStrategy.OnPush, providers: [HandleService, NodeAccessorService], host: {
|
|
2590
|
+
class: 'vflow-node',
|
|
2591
|
+
}, imports: [
|
|
2592
|
+
PointerDirective,
|
|
2593
|
+
DefaultNodeComponent,
|
|
2594
|
+
HandleComponent,
|
|
2595
|
+
NgTemplateOutlet,
|
|
2596
|
+
NgComponentOutlet,
|
|
2597
|
+
ResizableComponent,
|
|
2598
|
+
HandleSizeControllerDirective,
|
|
2599
|
+
], template: "<!-- Default node -->\n@if (nodeModel().node.type === \"default\") {\n @defer {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode(); selectNode()\"\n >\n <default-node\n #htmlWrapper\n [selected]=\"nodeModel().selected()\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n [style.max-width]=\"styleWidth()\"\n [style.max-height]=\"styleHeight()\"\n >\n <div [outerHTML]=\"nodeModel().text()\"></div>\n\n <handle type=\"source\" position=\"right\"/>\n <handle type=\"target\" position=\"left\" />\n </default-node>\n </svg:foreignObject>\n }\n}\n\n<!-- Template node -->\n@if (nodeModel().node.type === \"html-template\" && nodeTemplate()) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: { node: nodeModel().node, selected: nodeModel().selected },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Component node -->\n@if (nodeModel().isComponentType) {\n <svg:foreignObject\n class=\"selectable\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n (pointerStart)=\"pullNode()\"\n >\n <div\n #htmlWrapper\n class=\"wrapper\"\n [style.width]=\"styleWidth()\"\n [style.height]=\"styleHeight()\"\n >\n <ng-container\n [ngComponentOutlet]=\"$any(nodeModel().node.type)\"\n [ngComponentOutletInputs]=\"nodeModel().componentTypeInputs\"\n [ngComponentOutletInjector]=\"injector\"\n />\n </div>\n </svg:foreignObject>\n}\n\n<!-- Default group node -->\n@if (nodeModel().node.type === \"default-group\") {\n @defer {\n <svg:rect\n [resizable]=\"nodeModel().resizable()\"\n [gap]=\"3\"\n [resizerColor]=\"nodeModel().color()\"\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [class.default-group-node_selected]=\"nodeModel().selected()\"\n [attr.width]=\"nodeModel().size().width\"\n [attr.height]=\"nodeModel().size().height\"\n [style.stroke]=\"nodeModel().color()\"\n [style.fill]=\"nodeModel().color()\"\n (pointerStart)=\"pullNode(); selectNode()\"\n />\n }\n}\n\n<!-- Template group node -->\n@if (nodeModel().node.type === \"template-group\" && groupNodeTemplate()) {\n <svg:g class=\"selectable\" (pointerStart)=\"pullNode()\">\n <ng-container\n [ngTemplateOutlet]=\"groupNodeTemplate() ?? null\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n node: nodeModel().node,\n selected: nodeModel().selected,\n width: nodeModel().width,\n height: nodeModel().height,\n },\n }\"\n [ngTemplateOutletInjector]=\"injector\"\n />\n </svg:g>\n}\n\n<!-- Resizer -->\n@if (nodeModel().resizerTemplate(); as template) {\n @if (nodeModel().resizable()) {\n <ng-template [ngTemplateOutlet]=\"template\" />\n }\n}\n\n<!-- Handles -->\n@for (handle of nodeModel().handles(); track handle) {\n @if (!handle.template) {\n <svg:circle\n class=\"default-handle\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n [attr.stroke-width]=\"handle.strokeWidth\"\n r=\"5\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n />\n }\n\n @if (handle.template) {\n <svg:g\n [handleSizeController]=\"handle\"\n (pointerStart)=\"startConnection($event, handle)\"\n (pointerEnd)=\"endConnection(handle)\"\n >\n <ng-container\n *ngTemplateOutlet=\"handle.template; context: handle.templateContext\"\n />\n </svg:g>\n }\n\n @if (showMagnet()) {\n <svg:circle\n class=\"magnet\"\n [attr.r]=\"nodeModel().magnetRadius\"\n [attr.cx]=\"handle.offset().x\"\n [attr.cy]=\"handle.offset().y\"\n (pointerEnd)=\"endConnection(handle); resetValidateConnection(handle)\"\n (pointerOver)=\"validateConnection(handle)\"\n (pointerOut)=\"resetValidateConnection(handle)\"\n />\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 >\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"] }]
|
|
2600
|
+
}], propDecorators: { ngOnInit: [], ngAfterViewInit: [] } });
|
|
2457
2601
|
|
|
2458
2602
|
class ConnectionComponent {
|
|
2459
2603
|
constructor() {
|
|
2604
|
+
this.model = input.required();
|
|
2605
|
+
this.template = input();
|
|
2460
2606
|
this.flowStatusService = inject(FlowStatusService);
|
|
2461
2607
|
this.spacePointContext = inject(SpacePointContextDirective);
|
|
2462
2608
|
this.path = computed(() => {
|
|
@@ -2467,9 +2613,15 @@ class ConnectionComponent {
|
|
|
2467
2613
|
const sourcePosition = sourceHandle.rawHandle.position;
|
|
2468
2614
|
const targetPoint = this.spacePointContext.svgCurrentSpacePoint();
|
|
2469
2615
|
const targetPosition = getOppositePostion(sourceHandle.rawHandle.position);
|
|
2470
|
-
switch (this.model.curve) {
|
|
2471
|
-
case 'straight':
|
|
2472
|
-
|
|
2616
|
+
switch (this.model().curve) {
|
|
2617
|
+
case 'straight':
|
|
2618
|
+
return straightPath(sourcePoint, targetPoint).path;
|
|
2619
|
+
case 'bezier':
|
|
2620
|
+
return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
|
|
2621
|
+
case 'smooth-step':
|
|
2622
|
+
return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
|
|
2623
|
+
case 'step':
|
|
2624
|
+
return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
|
|
2473
2625
|
}
|
|
2474
2626
|
}
|
|
2475
2627
|
if (status.state === 'connection-validation') {
|
|
@@ -2484,15 +2636,21 @@ class ConnectionComponent {
|
|
|
2484
2636
|
const targetPosition = status.payload.valid
|
|
2485
2637
|
? targetHandle.rawHandle.position
|
|
2486
2638
|
: getOppositePostion(sourceHandle.rawHandle.position);
|
|
2487
|
-
switch (this.model.curve) {
|
|
2488
|
-
case 'straight':
|
|
2489
|
-
|
|
2639
|
+
switch (this.model().curve) {
|
|
2640
|
+
case 'straight':
|
|
2641
|
+
return straightPath(sourcePoint, targetPoint).path;
|
|
2642
|
+
case 'bezier':
|
|
2643
|
+
return bezierPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
|
|
2644
|
+
case 'smooth-step':
|
|
2645
|
+
return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition).path;
|
|
2646
|
+
case 'step':
|
|
2647
|
+
return smoothStepPath(sourcePoint, targetPoint, sourcePosition, targetPosition, 0).path;
|
|
2490
2648
|
}
|
|
2491
2649
|
}
|
|
2492
2650
|
return null;
|
|
2493
2651
|
});
|
|
2494
2652
|
this.markerUrl = computed(() => {
|
|
2495
|
-
const marker = this.model.settings.marker;
|
|
2653
|
+
const marker = this.model().settings.marker;
|
|
2496
2654
|
if (marker) {
|
|
2497
2655
|
return `url(#${hashCode(JSON.stringify(marker))})`;
|
|
2498
2656
|
}
|
|
@@ -2504,56 +2662,59 @@ class ConnectionComponent {
|
|
|
2504
2662
|
return {
|
|
2505
2663
|
$implicit: {
|
|
2506
2664
|
path: this.path,
|
|
2507
|
-
marker: this.markerUrl
|
|
2508
|
-
}
|
|
2665
|
+
marker: this.markerUrl,
|
|
2666
|
+
},
|
|
2509
2667
|
};
|
|
2510
2668
|
}
|
|
2511
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2512
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
}
|
|
2529
|
-
|
|
2669
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2670
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ConnectionComponent, isStandalone: true, selector: "g[connection]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2671
|
+
@if (model().type === 'default') {
|
|
2672
|
+
@if (path(); as path) {
|
|
2673
|
+
<svg:path
|
|
2674
|
+
[attr.d]="path"
|
|
2675
|
+
[attr.marker-end]="markerUrl()"
|
|
2676
|
+
[attr.stroke]="defaultColor"
|
|
2677
|
+
fill="none"
|
|
2678
|
+
stroke-width="2"
|
|
2679
|
+
/>
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
@if (model().type === 'template') {
|
|
2684
|
+
@if (template(); as template) {
|
|
2685
|
+
<ng-container *ngTemplateOutlet="template; context: getContext()" />
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2689
|
+
}
|
|
2690
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ConnectionComponent, decorators: [{
|
|
2530
2691
|
type: Component,
|
|
2531
2692
|
args: [{
|
|
2693
|
+
standalone: true,
|
|
2532
2694
|
selector: 'g[connection]',
|
|
2533
2695
|
template: `
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2696
|
+
@if (model().type === 'default') {
|
|
2697
|
+
@if (path(); as path) {
|
|
2698
|
+
<svg:path
|
|
2699
|
+
[attr.d]="path"
|
|
2700
|
+
[attr.marker-end]="markerUrl()"
|
|
2701
|
+
[attr.stroke]="defaultColor"
|
|
2702
|
+
fill="none"
|
|
2703
|
+
stroke-width="2"
|
|
2704
|
+
/>
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
@if (model().type === 'template') {
|
|
2709
|
+
@if (template(); as template) {
|
|
2710
|
+
<ng-container *ngTemplateOutlet="template; context: getContext()" />
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2548
2713
|
`,
|
|
2549
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
2714
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2715
|
+
imports: [NgTemplateOutlet],
|
|
2550
2716
|
}]
|
|
2551
|
-
}]
|
|
2552
|
-
type: Input,
|
|
2553
|
-
args: [{ required: true }]
|
|
2554
|
-
}], template: [{
|
|
2555
|
-
type: Input
|
|
2556
|
-
}] } });
|
|
2717
|
+
}] });
|
|
2557
2718
|
function getOppositePostion(position) {
|
|
2558
2719
|
switch (position) {
|
|
2559
2720
|
case 'top':
|
|
@@ -2567,22 +2728,6 @@ function getOppositePostion(position) {
|
|
|
2567
2728
|
}
|
|
2568
2729
|
}
|
|
2569
2730
|
|
|
2570
|
-
class DefsComponent {
|
|
2571
|
-
constructor() {
|
|
2572
|
-
this.markers = new Map();
|
|
2573
|
-
this.defaultColor = 'rgb(177, 177, 183)';
|
|
2574
|
-
}
|
|
2575
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2576
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DefsComponent, selector: "defs[flowDefs]", inputs: { markers: "markers" }, ngImport: i0, template: "<svg:marker\n *ngFor=\"let marker of markers | keyvalue\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n>\n <polyline\n *ngIf=\"marker.value.type === 'arrow-closed' || !marker.value.type\"\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n\n <polyline\n *ngIf=\"marker.value.type === 'arrow'\"\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n</svg:marker>\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2577
|
-
}
|
|
2578
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DefsComponent, decorators: [{
|
|
2579
|
-
type: Component,
|
|
2580
|
-
args: [{ selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:marker\n *ngFor=\"let marker of markers | keyvalue\"\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n>\n <polyline\n *ngIf=\"marker.value.type === 'arrow-closed' || !marker.value.type\"\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n\n <polyline\n *ngIf=\"marker.value.type === 'arrow'\"\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n</svg:marker>\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
|
|
2581
|
-
}], propDecorators: { markers: [{
|
|
2582
|
-
type: Input,
|
|
2583
|
-
args: [{ required: true }]
|
|
2584
|
-
}] } });
|
|
2585
|
-
|
|
2586
2731
|
function id() {
|
|
2587
2732
|
const randomLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
|
|
2588
2733
|
return randomLetter + Date.now();
|
|
@@ -2592,12 +2737,15 @@ const defaultBg = '#fff';
|
|
|
2592
2737
|
const defaultGap = 20;
|
|
2593
2738
|
const defaultDotSize = 2;
|
|
2594
2739
|
const defaultDotColor = 'rgb(177, 177, 183)';
|
|
2740
|
+
const defaultImageScale = 0.1;
|
|
2741
|
+
const defaultRepeated = true;
|
|
2595
2742
|
class BackgroundComponent {
|
|
2596
2743
|
constructor() {
|
|
2597
2744
|
this.viewportService = inject(ViewportService);
|
|
2598
2745
|
this.rootSvg = inject(RootSvgReferenceDirective).element;
|
|
2599
2746
|
this.settingsService = inject(FlowSettingsService);
|
|
2600
2747
|
this.backgroundSignal = this.settingsService.background;
|
|
2748
|
+
// DOTS PATTERN
|
|
2601
2749
|
this.scaledGap = computed(() => {
|
|
2602
2750
|
const background = this.backgroundSignal();
|
|
2603
2751
|
if (background.type === 'dots') {
|
|
@@ -2608,7 +2756,13 @@ class BackgroundComponent {
|
|
|
2608
2756
|
});
|
|
2609
2757
|
this.x = computed(() => this.viewportService.readableViewport().x % this.scaledGap());
|
|
2610
2758
|
this.y = computed(() => this.viewportService.readableViewport().y % this.scaledGap());
|
|
2611
|
-
this.patternColor = computed(() =>
|
|
2759
|
+
this.patternColor = computed(() => {
|
|
2760
|
+
const bg = this.backgroundSignal();
|
|
2761
|
+
if (bg.type === 'dots') {
|
|
2762
|
+
return bg.color ?? defaultDotColor;
|
|
2763
|
+
}
|
|
2764
|
+
return defaultDotColor;
|
|
2765
|
+
});
|
|
2612
2766
|
this.patternSize = computed(() => {
|
|
2613
2767
|
const background = this.backgroundSignal();
|
|
2614
2768
|
if (background.type === 'dots') {
|
|
@@ -2616,6 +2770,56 @@ class BackgroundComponent {
|
|
|
2616
2770
|
}
|
|
2617
2771
|
return 0;
|
|
2618
2772
|
});
|
|
2773
|
+
// IMAGE PATTERN
|
|
2774
|
+
this.bgImageSrc = computed(() => {
|
|
2775
|
+
const background = this.backgroundSignal();
|
|
2776
|
+
return background.type === 'image' ? background.src : '';
|
|
2777
|
+
});
|
|
2778
|
+
this.imageSize = toSignal(toObservable(this.backgroundSignal).pipe(switchMap(() => createImage(this.bgImageSrc())), map((image) => ({ width: image.naturalWidth, height: image.naturalHeight }))), { initialValue: { width: 0, height: 0 } });
|
|
2779
|
+
this.scaledImageWidth = computed(() => {
|
|
2780
|
+
const background = this.backgroundSignal();
|
|
2781
|
+
if (background.type === 'image') {
|
|
2782
|
+
const zoom = background.fixed ? 1 : this.viewportService.readableViewport().zoom;
|
|
2783
|
+
return this.imageSize().width * zoom * (background.scale ?? defaultImageScale);
|
|
2784
|
+
}
|
|
2785
|
+
return 0;
|
|
2786
|
+
});
|
|
2787
|
+
this.scaledImageHeight = computed(() => {
|
|
2788
|
+
const background = this.backgroundSignal();
|
|
2789
|
+
if (background.type === 'image') {
|
|
2790
|
+
const zoom = background.fixed ? 1 : this.viewportService.readableViewport().zoom;
|
|
2791
|
+
return this.imageSize().height * zoom * (background.scale ?? defaultImageScale);
|
|
2792
|
+
}
|
|
2793
|
+
return 0;
|
|
2794
|
+
});
|
|
2795
|
+
this.imageX = computed(() => {
|
|
2796
|
+
const background = this.backgroundSignal();
|
|
2797
|
+
if (background.type === 'image') {
|
|
2798
|
+
if (!background.repeat) {
|
|
2799
|
+
return background.fixed ? 0 : this.viewportService.readableViewport().x;
|
|
2800
|
+
}
|
|
2801
|
+
return background.fixed
|
|
2802
|
+
? 0
|
|
2803
|
+
: this.viewportService.readableViewport().x % this.scaledImageWidth();
|
|
2804
|
+
}
|
|
2805
|
+
return 0;
|
|
2806
|
+
});
|
|
2807
|
+
this.imageY = computed(() => {
|
|
2808
|
+
const background = this.backgroundSignal();
|
|
2809
|
+
if (background.type === 'image') {
|
|
2810
|
+
if (!background.repeat) {
|
|
2811
|
+
return background.fixed ? 0 : this.viewportService.readableViewport().y;
|
|
2812
|
+
}
|
|
2813
|
+
return background.fixed
|
|
2814
|
+
? 0
|
|
2815
|
+
: this.viewportService.readableViewport().y % this.scaledImageHeight();
|
|
2816
|
+
}
|
|
2817
|
+
return 0;
|
|
2818
|
+
});
|
|
2819
|
+
this.repeated = computed(() => {
|
|
2820
|
+
const background = this.backgroundSignal();
|
|
2821
|
+
return background.type === 'image' && (background.repeat ?? defaultRepeated);
|
|
2822
|
+
});
|
|
2619
2823
|
// Without ID there will be pattern collision for several flows on the page
|
|
2620
2824
|
// Later pattern ID may be exposed to API
|
|
2621
2825
|
this.patternId = id();
|
|
@@ -2630,39 +2834,33 @@ class BackgroundComponent {
|
|
|
2630
2834
|
}
|
|
2631
2835
|
});
|
|
2632
2836
|
}
|
|
2633
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2634
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2837
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2838
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: BackgroundComponent, isStandalone: true, selector: "g[background]", ngImport: i0, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2635
2839
|
}
|
|
2636
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2840
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BackgroundComponent, decorators: [{
|
|
2637
2841
|
type: Component,
|
|
2638
|
-
args: [{ selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "
|
|
2639
|
-
}], ctorParameters:
|
|
2842
|
+
args: [{ standalone: true, selector: 'g[background]', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (backgroundSignal().type === 'dots') {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"x()\"\n [attr.y]=\"y()\"\n [attr.width]=\"scaledGap()\"\n [attr.height]=\"scaledGap()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:circle\n [attr.cx]=\"patternSize()\"\n [attr.cy]=\"patternSize()\"\n [attr.r]=\"patternSize()\"\n [attr.fill]=\"patternColor()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n}\n\n@if (backgroundSignal().type === 'image') {\n @if (repeated()) {\n <svg:pattern\n [attr.id]=\"patternId\"\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n patternUnits=\"userSpaceOnUse\"\n >\n <svg:image\n [attr.href]=\"bgImageSrc()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n />\n </svg:pattern>\n\n <svg:rect\n x=\"0\"\n y=\"0\"\n width=\"100%\"\n height=\"100%\"\n [attr.fill]=\"patternUrl\"\n />\n }\n\n @if (!repeated()) {\n <svg:image\n [attr.x]=\"imageX()\"\n [attr.y]=\"imageY()\"\n [attr.width]=\"scaledImageWidth()\"\n [attr.height]=\"scaledImageHeight()\"\n [attr.href]=\"bgImageSrc()\"\n />\n }\n}\n" }]
|
|
2843
|
+
}], ctorParameters: () => [] });
|
|
2844
|
+
function createImage(url) {
|
|
2845
|
+
const image = new Image();
|
|
2846
|
+
image.src = url;
|
|
2847
|
+
return new Promise(resolve => {
|
|
2848
|
+
image.onload = () => resolve(image);
|
|
2849
|
+
});
|
|
2850
|
+
}
|
|
2640
2851
|
|
|
2641
|
-
|
|
2642
|
-
class RootSvgContextDirective {
|
|
2852
|
+
class DefsComponent {
|
|
2643
2853
|
constructor() {
|
|
2644
|
-
this.
|
|
2645
|
-
|
|
2646
|
-
// TODO: check for multiple instances on page
|
|
2647
|
-
resetConnection() {
|
|
2648
|
-
const status = this.flowStatusService.status();
|
|
2649
|
-
if (status.state === 'connection-start') {
|
|
2650
|
-
this.flowStatusService.setIdleStatus();
|
|
2651
|
-
}
|
|
2854
|
+
this.markers = input.required();
|
|
2855
|
+
this.defaultColor = 'rgb(177, 177, 183)';
|
|
2652
2856
|
}
|
|
2653
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2654
|
-
static { this.ɵ
|
|
2857
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2858
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DefsComponent, isStandalone: true, selector: "defs[flowDefs]", inputs: { markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"], dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2655
2859
|
}
|
|
2656
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2657
|
-
type:
|
|
2658
|
-
args: [{ selector: 'svg[
|
|
2659
|
-
}]
|
|
2660
|
-
type: HostListener,
|
|
2661
|
-
args: ['document:mouseup']
|
|
2662
|
-
}, {
|
|
2663
|
-
type: HostListener,
|
|
2664
|
-
args: ['document:touchend']
|
|
2665
|
-
}] } });
|
|
2860
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefsComponent, decorators: [{
|
|
2861
|
+
type: Component,
|
|
2862
|
+
args: [{ standalone: true, selector: 'defs[flowDefs]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KeyValuePipe], template: "@for (marker of markers() | keyvalue; track marker) {\n <svg:marker\n [attr.id]=\"marker.key\"\n [attr.markerWidth]=\"marker.value.width ?? 16.5\"\n [attr.markerHeight]=\"marker.value.height ?? 16.5\"\n [attr.orient]=\"marker.value.orient ?? 'auto-start-reverse'\"\n viewBox=\"-10 -10 20 20\"\n [attr.markerUnits]=\"marker.value.markerUnits ?? 'userSpaceOnUse'\"\n refX=\"0\"\n refY=\"0\"\n >\n @if (marker.value.type === \"arrow-closed\" || !marker.value.type) {\n <polyline\n class=\"marker__arrow_closed\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n [style.fill]=\"marker.value.color ?? defaultColor\"\n points=\"-5,-4 1,0 -5,4 -5,-4\"\n />\n }\n\n @if (marker.value.type === \"arrow\") {\n <polyline\n class=\"marker__arrow_default\"\n [style.stroke]=\"marker.value.color ?? defaultColor\"\n [style.stroke-width]=\"marker.value.strokeWidth ?? 2\"\n points=\"-5,-4 0,0 -5,4\"\n />\n }\n </svg:marker>\n}\n", styles: [".marker__arrow_default{stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;fill:none}.marker__arrow_closed{stroke-linecap:round;stroke-linejoin:round}\n"] }]
|
|
2863
|
+
}] });
|
|
2666
2864
|
|
|
2667
2865
|
class FlowSizeControllerDirective {
|
|
2668
2866
|
constructor() {
|
|
@@ -2681,23 +2879,53 @@ class FlowSizeControllerDirective {
|
|
|
2681
2879
|
this.flowSettingsService.computedFlowHeight.set(entry.contentRect.height);
|
|
2682
2880
|
}), takeUntilDestroyed()).subscribe();
|
|
2683
2881
|
}
|
|
2684
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2685
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
2882
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSizeControllerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2883
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: FlowSizeControllerDirective, isStandalone: true, selector: "svg[flowSizeController]", host: { properties: { "attr.width": "flowWidth()", "attr.height": "flowHeight()" } }, ngImport: i0 }); }
|
|
2686
2884
|
}
|
|
2687
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2885
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlowSizeControllerDirective, decorators: [{
|
|
2688
2886
|
type: Directive,
|
|
2689
2887
|
args: [{
|
|
2888
|
+
standalone: true,
|
|
2690
2889
|
selector: 'svg[flowSizeController]',
|
|
2691
2890
|
host: {
|
|
2692
2891
|
'[attr.width]': 'flowWidth()',
|
|
2693
2892
|
'[attr.height]': 'flowHeight()'
|
|
2694
|
-
}
|
|
2893
|
+
},
|
|
2695
2894
|
}]
|
|
2696
|
-
}], ctorParameters:
|
|
2895
|
+
}], ctorParameters: () => [] });
|
|
2896
|
+
|
|
2897
|
+
// TODO: too general purpose nane
|
|
2898
|
+
class RootSvgContextDirective {
|
|
2899
|
+
constructor() {
|
|
2900
|
+
this.flowStatusService = inject(FlowStatusService);
|
|
2901
|
+
}
|
|
2902
|
+
// TODO: check for multiple instances on page
|
|
2903
|
+
resetConnection() {
|
|
2904
|
+
const status = this.flowStatusService.status();
|
|
2905
|
+
if (status.state === 'connection-start') {
|
|
2906
|
+
this.flowStatusService.setIdleStatus();
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2910
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: RootSvgContextDirective, isStandalone: true, selector: "svg[rootSvgContext]", host: { listeners: { "document:mouseup": "resetConnection()", "document:touchend": "resetConnection()" } }, ngImport: i0 }); }
|
|
2911
|
+
}
|
|
2912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RootSvgContextDirective, decorators: [{
|
|
2913
|
+
type: Directive,
|
|
2914
|
+
args: [{
|
|
2915
|
+
standalone: true,
|
|
2916
|
+
selector: 'svg[rootSvgContext]',
|
|
2917
|
+
}]
|
|
2918
|
+
}], propDecorators: { resetConnection: [{
|
|
2919
|
+
type: HostListener,
|
|
2920
|
+
args: ['document:mouseup']
|
|
2921
|
+
}, {
|
|
2922
|
+
type: HostListener,
|
|
2923
|
+
args: ['document:touchend']
|
|
2924
|
+
}] } });
|
|
2697
2925
|
|
|
2698
2926
|
const connectionControllerHostDirective = {
|
|
2699
2927
|
directive: ConnectionControllerDirective,
|
|
2700
|
-
outputs: ['onConnect']
|
|
2928
|
+
outputs: ['onConnect'],
|
|
2701
2929
|
};
|
|
2702
2930
|
const changesControllerHostDirective = {
|
|
2703
2931
|
directive: ChangesControllerDirective,
|
|
@@ -2731,7 +2959,7 @@ const changesControllerHostDirective = {
|
|
|
2731
2959
|
'onEdgesChange.select',
|
|
2732
2960
|
'onEdgesChange.select.single',
|
|
2733
2961
|
'onEdgesChange.select.many',
|
|
2734
|
-
]
|
|
2962
|
+
],
|
|
2735
2963
|
};
|
|
2736
2964
|
class VflowComponent {
|
|
2737
2965
|
constructor() {
|
|
@@ -2745,10 +2973,12 @@ class VflowComponent {
|
|
|
2745
2973
|
this.componentEventBusService = inject(ComponentEventBusService);
|
|
2746
2974
|
this.keyboardService = inject(KeyboardService);
|
|
2747
2975
|
this.injector = inject(Injector);
|
|
2748
|
-
this.optimization = {
|
|
2749
|
-
|
|
2750
|
-
};
|
|
2976
|
+
this.optimization = input({
|
|
2977
|
+
detachedGroupsLayer: false,
|
|
2978
|
+
});
|
|
2751
2979
|
this.nodeModels = computed(() => this.nodeRenderingService.nodes());
|
|
2980
|
+
this.groups = computed(() => this.nodeRenderingService.groups());
|
|
2981
|
+
this.nonGroups = computed(() => this.nodeRenderingService.nonGroups());
|
|
2752
2982
|
this.edgeModels = computed(() => this.flowEntitiesService.validEdges());
|
|
2753
2983
|
// #endregion
|
|
2754
2984
|
// #region OUTPUTS
|
|
@@ -2757,7 +2987,18 @@ class VflowComponent {
|
|
|
2757
2987
|
*
|
|
2758
2988
|
* @experimental
|
|
2759
2989
|
*/
|
|
2760
|
-
this.onComponentNodeEvent = this.componentEventBusService.event
|
|
2990
|
+
this.onComponentNodeEvent = outputFromObservable(this.componentEventBusService.event$); // TODO: research how to remove any
|
|
2991
|
+
// #endregion
|
|
2992
|
+
// #region TEMPLATES
|
|
2993
|
+
this.nodeTemplateDirective = contentChild(NodeHtmlTemplateDirective);
|
|
2994
|
+
this.groupNodeTemplateDirective = contentChild(GroupNodeTemplateDirective);
|
|
2995
|
+
this.edgeTemplateDirective = contentChild(EdgeTemplateDirective);
|
|
2996
|
+
this.edgeLabelHtmlDirective = contentChild(EdgeLabelHtmlTemplateDirective);
|
|
2997
|
+
this.connectionTemplateDirective = contentChild(ConnectionTemplateDirective);
|
|
2998
|
+
// #endregion
|
|
2999
|
+
// #region DIRECTIVES
|
|
3000
|
+
this.mapContext = viewChild(MapContextDirective);
|
|
3001
|
+
this.spacePointContext = viewChild.required(SpacePointContextDirective);
|
|
2761
3002
|
// #endregion
|
|
2762
3003
|
// #region SIGNAL_API
|
|
2763
3004
|
/**
|
|
@@ -2767,18 +3008,21 @@ class VflowComponent {
|
|
|
2767
3008
|
/**
|
|
2768
3009
|
* Signal for reading nodes change
|
|
2769
3010
|
*/
|
|
2770
|
-
this.nodesChange = toSignal(this.nodesChangeService.changes$, {
|
|
3011
|
+
this.nodesChange = toSignal(this.nodesChangeService.changes$, {
|
|
3012
|
+
initialValue: [],
|
|
3013
|
+
});
|
|
2771
3014
|
/**
|
|
2772
3015
|
* Signal to reading edges change
|
|
2773
3016
|
*/
|
|
2774
|
-
this.edgesChange = toSignal(this.edgesChangeService.changes$, {
|
|
3017
|
+
this.edgesChange = toSignal(this.edgesChangeService.changes$, {
|
|
3018
|
+
initialValue: [],
|
|
3019
|
+
});
|
|
2775
3020
|
// #endregion
|
|
2776
3021
|
// #region RX_API
|
|
2777
3022
|
/**
|
|
2778
3023
|
* Observable with viewport change
|
|
2779
3024
|
*/
|
|
2780
|
-
this.viewportChange$ = toObservable(this.viewportService.readableViewport)
|
|
2781
|
-
.pipe(skip(1)); // skip default value that set by signal
|
|
3025
|
+
this.viewportChange$ = toObservable(this.viewportService.readableViewport).pipe(skip(1)); // skip default value that set by signal
|
|
2782
3026
|
/**
|
|
2783
3027
|
* Observable with nodes change
|
|
2784
3028
|
*/
|
|
@@ -2815,17 +3059,6 @@ class VflowComponent {
|
|
|
2815
3059
|
set maxZoom(value) {
|
|
2816
3060
|
this.flowSettingsService.maxZoom.set(value);
|
|
2817
3061
|
}
|
|
2818
|
-
/**
|
|
2819
|
-
* Object that controls flow direction.
|
|
2820
|
-
*
|
|
2821
|
-
* For example, if you want to archieve right to left direction
|
|
2822
|
-
* then you need to pass these positions { source: 'left', target: 'right' }
|
|
2823
|
-
*
|
|
2824
|
-
* @deprecated
|
|
2825
|
-
*/
|
|
2826
|
-
set handlePositions(handlePositions) {
|
|
2827
|
-
this.flowSettingsService.handlePositions.set(handlePositions);
|
|
2828
|
-
}
|
|
2829
3062
|
/**
|
|
2830
3063
|
* Background for flow
|
|
2831
3064
|
*/
|
|
@@ -2846,8 +3079,12 @@ class VflowComponent {
|
|
|
2846
3079
|
*
|
|
2847
3080
|
* You need to pass `ConnectionSettings` in this input.
|
|
2848
3081
|
*/
|
|
2849
|
-
set connection(connection) {
|
|
2850
|
-
|
|
3082
|
+
set connection(connection) {
|
|
3083
|
+
this.flowEntitiesService.connection.set(connection);
|
|
3084
|
+
}
|
|
3085
|
+
get connection() {
|
|
3086
|
+
return this.flowEntitiesService.connection();
|
|
3087
|
+
}
|
|
2851
3088
|
// #endregion
|
|
2852
3089
|
// #region MAIN_INPUTS
|
|
2853
3090
|
/**
|
|
@@ -2878,7 +3115,11 @@ class VflowComponent {
|
|
|
2878
3115
|
* @param viewport viewport state
|
|
2879
3116
|
*/
|
|
2880
3117
|
viewportTo(viewport) {
|
|
2881
|
-
this.viewportService.writableViewport.set({
|
|
3118
|
+
this.viewportService.writableViewport.set({
|
|
3119
|
+
changeType: 'absolute',
|
|
3120
|
+
state: viewport,
|
|
3121
|
+
duration: 0,
|
|
3122
|
+
});
|
|
2882
3123
|
}
|
|
2883
3124
|
/**
|
|
2884
3125
|
* Change zoom
|
|
@@ -2886,7 +3127,11 @@ class VflowComponent {
|
|
|
2886
3127
|
* @param zoom zoom value
|
|
2887
3128
|
*/
|
|
2888
3129
|
zoomTo(zoom) {
|
|
2889
|
-
this.viewportService.writableViewport.set({
|
|
3130
|
+
this.viewportService.writableViewport.set({
|
|
3131
|
+
changeType: 'absolute',
|
|
3132
|
+
state: { zoom },
|
|
3133
|
+
duration: 0,
|
|
3134
|
+
});
|
|
2890
3135
|
}
|
|
2891
3136
|
/**
|
|
2892
3137
|
* Move to specified coordinate
|
|
@@ -2894,7 +3139,11 @@ class VflowComponent {
|
|
|
2894
3139
|
* @param point point where to move
|
|
2895
3140
|
*/
|
|
2896
3141
|
panTo(point) {
|
|
2897
|
-
this.viewportService.writableViewport.set({
|
|
3142
|
+
this.viewportService.writableViewport.set({
|
|
3143
|
+
changeType: 'absolute',
|
|
3144
|
+
state: point,
|
|
3145
|
+
duration: 0,
|
|
3146
|
+
});
|
|
2898
3147
|
}
|
|
2899
3148
|
fitView(options) {
|
|
2900
3149
|
this.viewportService.fitView(options);
|
|
@@ -2911,13 +3160,13 @@ class VflowComponent {
|
|
|
2911
3160
|
* Sync method to get detached edges
|
|
2912
3161
|
*/
|
|
2913
3162
|
getDetachedEdges() {
|
|
2914
|
-
return this.flowEntitiesService.getDetachedEdges().map(e => e.edge);
|
|
3163
|
+
return this.flowEntitiesService.getDetachedEdges().map((e) => e.edge);
|
|
2915
3164
|
}
|
|
2916
3165
|
/**
|
|
2917
3166
|
* Convert point received from document to point on the flow
|
|
2918
3167
|
*/
|
|
2919
3168
|
documentPointToFlowPoint(point) {
|
|
2920
|
-
return this.spacePointContext.documentPointToFlowPoint(point);
|
|
3169
|
+
return this.spacePointContext().documentPointToFlowPoint(point);
|
|
2921
3170
|
}
|
|
2922
3171
|
// #endregion
|
|
2923
3172
|
trackNodes(idx, { node }) {
|
|
@@ -2927,19 +3176,17 @@ class VflowComponent {
|
|
|
2927
3176
|
return edge;
|
|
2928
3177
|
}
|
|
2929
3178
|
setInitialNodesOrder() {
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
this.nodeRenderingService.pullNode(model);
|
|
2936
|
-
}
|
|
3179
|
+
this.nodeModels().forEach((model) => {
|
|
3180
|
+
switch (model.node.type) {
|
|
3181
|
+
case 'default-group':
|
|
3182
|
+
case 'template-group': {
|
|
3183
|
+
this.nodeRenderingService.pullNode(model);
|
|
2937
3184
|
}
|
|
2938
|
-
}
|
|
2939
|
-
}
|
|
3185
|
+
}
|
|
3186
|
+
});
|
|
2940
3187
|
}
|
|
2941
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2942
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3188
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3189
|
+
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) }, 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: [
|
|
2943
3190
|
DraggableService,
|
|
2944
3191
|
ViewportService,
|
|
2945
3192
|
FlowStatusService,
|
|
@@ -2951,12 +3198,12 @@ class VflowComponent {
|
|
|
2951
3198
|
FlowSettingsService,
|
|
2952
3199
|
ComponentEventBusService,
|
|
2953
3200
|
KeyboardService,
|
|
2954
|
-
OverlaysService
|
|
2955
|
-
], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, descendants: true }, { propertyName: "groupNodeTemplateDirective", first: true, predicate: GroupNodeTemplateDirective, descendants: true }, { propertyName: "edgeTemplateDirective", first: true, predicate: EdgeTemplateDirective, descendants: true }, { propertyName: "edgeLabelHtmlDirective", first: true, predicate: EdgeLabelHtmlTemplateDirective, descendants: true }, { propertyName: "connectionTemplateDirective", first: true, predicate: ConnectionTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "mapContext", first: true, predicate: MapContextDirective, descendants: true }, { propertyName: "spacePointContext", first: true, predicate: SpacePointContextDirective, descendants: true }], hostDirectives: [{ directive: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { 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\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g
|
|
3201
|
+
OverlaysService,
|
|
3202
|
+
], queries: [{ propertyName: "nodeTemplateDirective", first: true, predicate: NodeHtmlTemplateDirective, 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: ConnectionControllerDirective, outputs: ["onConnect", "onConnect"] }, { 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\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\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 }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().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 <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\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: ["nodeModel", "nodeTemplate", "groupNodeTemplate"] }, { kind: "component", type: EdgeComponent, selector: "g[edge]", inputs: ["model", "edgeTemplate", "edgeLabelHtmlTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2956
3203
|
}
|
|
2957
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3204
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, decorators: [{
|
|
2958
3205
|
type: Component,
|
|
2959
|
-
args: [{ selector: 'vflow', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3206
|
+
args: [{ standalone: true, selector: 'vflow', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
2960
3207
|
DraggableService,
|
|
2961
3208
|
ViewportService,
|
|
2962
3209
|
FlowStatusService,
|
|
@@ -2968,60 +3215,73 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2968
3215
|
FlowSettingsService,
|
|
2969
3216
|
ComponentEventBusService,
|
|
2970
3217
|
KeyboardService,
|
|
2971
|
-
OverlaysService
|
|
3218
|
+
OverlaysService,
|
|
2972
3219
|
], hostDirectives: [
|
|
2973
3220
|
connectionControllerHostDirective,
|
|
2974
|
-
changesControllerHostDirective
|
|
2975
|
-
],
|
|
3221
|
+
changesControllerHostDirective,
|
|
3222
|
+
], imports: [
|
|
3223
|
+
RootSvgReferenceDirective,
|
|
3224
|
+
RootSvgContextDirective,
|
|
3225
|
+
RootPointerDirective,
|
|
3226
|
+
FlowSizeControllerDirective,
|
|
3227
|
+
DefsComponent,
|
|
3228
|
+
BackgroundComponent,
|
|
3229
|
+
MapContextDirective,
|
|
3230
|
+
SpacePointContextDirective,
|
|
3231
|
+
ConnectionComponent,
|
|
3232
|
+
NodeComponent,
|
|
3233
|
+
EdgeComponent,
|
|
3234
|
+
NgTemplateOutlet,
|
|
3235
|
+
], template: "<svg:svg\n rootSvgRef\n rootSvgContext\n rootPointer\n flowSizeController\n class=\"root-svg\"\n #flow\n>\n <defs [markers]=\"markers()\" flowDefs />\n\n <g background />\n\n <svg:g mapContext spacePointContext>\n <!-- Connection -->\n <svg:g\n connection\n [model]=\"connection\"\n [template]=\"connectionTemplateDirective()?.templateRef\"\n />\n\n @if (optimization().detachedGroupsLayer) {\n <!-- Groups -->\n @for (model of groups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\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 }\n <!-- Nodes -->\n @for (model of nonGroups(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n\n @if (!optimization().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 <!-- Nodes -->\n @for (model of nodeModels(); track trackNodes($index, model)) {\n <svg:g\n node\n [nodeModel]=\"model\"\n [nodeTemplate]=\"nodeTemplateDirective()?.templateRef\"\n [groupNodeTemplate]=\"groupNodeTemplateDirective()?.templateRef\"\n [attr.transform]=\"model.pointTransform()\"\n />\n }\n }\n </svg:g>\n\n <!-- Minimap -->\n @if (minimap(); as minimap) {\n <ng-container [ngTemplateOutlet]=\"minimap.template()\" />\n }\n</svg:svg>\n", styles: [":host{display:block;width:100%;height:100%;-webkit-user-select:none;user-select:none}:host ::ng-deep *{box-sizing:border-box}\n"] }]
|
|
2976
3236
|
}], propDecorators: { view: [{
|
|
2977
3237
|
type: Input
|
|
2978
3238
|
}], minZoom: [{
|
|
2979
3239
|
type: Input
|
|
2980
3240
|
}], maxZoom: [{
|
|
2981
3241
|
type: Input
|
|
2982
|
-
}], handlePositions: [{
|
|
2983
|
-
type: Input
|
|
2984
3242
|
}], background: [{
|
|
2985
3243
|
type: Input
|
|
2986
|
-
}], optimization: [{
|
|
2987
|
-
type: Input
|
|
2988
3244
|
}], entitiesSelectable: [{
|
|
2989
3245
|
type: Input
|
|
2990
3246
|
}], keyboardShortcuts: [{
|
|
2991
3247
|
type: Input
|
|
2992
3248
|
}], connection: [{
|
|
2993
3249
|
type: Input,
|
|
2994
|
-
args: [{
|
|
3250
|
+
args: [{
|
|
3251
|
+
transform: (settings) => new ConnectionModel(settings),
|
|
3252
|
+
}]
|
|
2995
3253
|
}], nodes: [{
|
|
2996
3254
|
type: Input,
|
|
2997
3255
|
args: [{ required: true }]
|
|
2998
3256
|
}], edges: [{
|
|
2999
3257
|
type: Input
|
|
3000
|
-
}], onComponentNodeEvent: [{
|
|
3001
|
-
type: Output
|
|
3002
|
-
}], nodeTemplateDirective: [{
|
|
3003
|
-
type: ContentChild,
|
|
3004
|
-
args: [NodeHtmlTemplateDirective]
|
|
3005
|
-
}], groupNodeTemplateDirective: [{
|
|
3006
|
-
type: ContentChild,
|
|
3007
|
-
args: [GroupNodeTemplateDirective]
|
|
3008
|
-
}], edgeTemplateDirective: [{
|
|
3009
|
-
type: ContentChild,
|
|
3010
|
-
args: [EdgeTemplateDirective]
|
|
3011
|
-
}], edgeLabelHtmlDirective: [{
|
|
3012
|
-
type: ContentChild,
|
|
3013
|
-
args: [EdgeLabelHtmlTemplateDirective]
|
|
3014
|
-
}], connectionTemplateDirective: [{
|
|
3015
|
-
type: ContentChild,
|
|
3016
|
-
args: [ConnectionTemplateDirective]
|
|
3017
|
-
}], mapContext: [{
|
|
3018
|
-
type: ViewChild,
|
|
3019
|
-
args: [MapContextDirective]
|
|
3020
|
-
}], spacePointContext: [{
|
|
3021
|
-
type: ViewChild,
|
|
3022
|
-
args: [SpacePointContextDirective]
|
|
3023
3258
|
}] } });
|
|
3024
3259
|
|
|
3260
|
+
class DragHandleDirective {
|
|
3261
|
+
get model() {
|
|
3262
|
+
return this.nodeAccessor.model();
|
|
3263
|
+
}
|
|
3264
|
+
constructor() {
|
|
3265
|
+
this.nodeAccessor = inject(NodeAccessorService);
|
|
3266
|
+
this.model.dragHandlesCount.update((count) => count + 1);
|
|
3267
|
+
inject(DestroyRef).onDestroy(() => {
|
|
3268
|
+
this.model.dragHandlesCount.update(count => count - 1);
|
|
3269
|
+
});
|
|
3270
|
+
}
|
|
3271
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3272
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DragHandleDirective, isStandalone: true, selector: "[dragHandle]", host: { classAttribute: "vflow-drag-handle" }, ngImport: i0 }); }
|
|
3273
|
+
}
|
|
3274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DragHandleDirective, decorators: [{
|
|
3275
|
+
type: Directive,
|
|
3276
|
+
args: [{
|
|
3277
|
+
standalone: true,
|
|
3278
|
+
selector: '[dragHandle]',
|
|
3279
|
+
host: {
|
|
3280
|
+
'class': 'vflow-drag-handle'
|
|
3281
|
+
},
|
|
3282
|
+
}]
|
|
3283
|
+
}], ctorParameters: () => [] });
|
|
3284
|
+
|
|
3025
3285
|
class SelectableDirective {
|
|
3026
3286
|
constructor() {
|
|
3027
3287
|
this.flowSettingsService = inject(FlowSettingsService);
|
|
@@ -3037,19 +3297,22 @@ class SelectableDirective {
|
|
|
3037
3297
|
}
|
|
3038
3298
|
entity() {
|
|
3039
3299
|
if (this.parentNode) {
|
|
3040
|
-
return this.parentNode.nodeModel;
|
|
3300
|
+
return this.parentNode.nodeModel();
|
|
3041
3301
|
}
|
|
3042
3302
|
else if (this.parentEdge) {
|
|
3043
|
-
return this.parentEdge.model;
|
|
3303
|
+
return this.parentEdge.model();
|
|
3044
3304
|
}
|
|
3045
3305
|
return null;
|
|
3046
3306
|
}
|
|
3047
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3048
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
3307
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3308
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SelectableDirective, isStandalone: true, selector: "[selectable]", host: { listeners: { "mousedown": "onMousedown()", "touchstart": "onMousedown()" } }, ngImport: i0 }); }
|
|
3049
3309
|
}
|
|
3050
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectableDirective, decorators: [{
|
|
3051
3311
|
type: Directive,
|
|
3052
|
-
args: [{
|
|
3312
|
+
args: [{
|
|
3313
|
+
standalone: true,
|
|
3314
|
+
selector: '[selectable]',
|
|
3315
|
+
}]
|
|
3053
3316
|
}], propDecorators: { onMousedown: [{
|
|
3054
3317
|
type: HostListener,
|
|
3055
3318
|
args: ['mousedown']
|
|
@@ -3073,38 +3336,61 @@ class MiniMapComponent {
|
|
|
3073
3336
|
/**
|
|
3074
3337
|
* The color outside the viewport (invisible area)
|
|
3075
3338
|
*/
|
|
3076
|
-
this.maskColor = `rgba(215, 215, 215, 0.6)
|
|
3339
|
+
this.maskColor = input(`rgba(215, 215, 215, 0.6)`);
|
|
3077
3340
|
/**
|
|
3078
3341
|
* The minimap stroke color
|
|
3079
3342
|
*/
|
|
3080
|
-
this.strokeColor = `rgb(200, 200, 200)
|
|
3343
|
+
this.strokeColor = input(`rgb(200, 200, 200)`);
|
|
3344
|
+
/**
|
|
3345
|
+
* The corner of the flow where to render a mini-map
|
|
3346
|
+
*/
|
|
3347
|
+
this.position = input('bottom-right');
|
|
3348
|
+
/**
|
|
3349
|
+
* Make a minimap bigger on hover
|
|
3350
|
+
*/
|
|
3351
|
+
this.scaleOnHover = input(false);
|
|
3352
|
+
this.minimap = viewChild.required('minimap');
|
|
3081
3353
|
this.minimapOffset = 10;
|
|
3082
3354
|
this.minimapScale = computed(() => {
|
|
3083
|
-
if (this.
|
|
3355
|
+
if (this.scaleOnHover()) {
|
|
3084
3356
|
return this.hovered() ? 0.4 : 0.2;
|
|
3085
3357
|
}
|
|
3086
3358
|
return 0.2;
|
|
3087
3359
|
});
|
|
3088
|
-
this.viewportColor = computed(() =>
|
|
3360
|
+
this.viewportColor = computed(() => {
|
|
3361
|
+
const bg = this.flowSettingsService.background();
|
|
3362
|
+
if (bg.type === 'dots' || bg.type === 'solid') {
|
|
3363
|
+
return bg.color ?? '#fff';
|
|
3364
|
+
}
|
|
3365
|
+
return '#fff';
|
|
3366
|
+
});
|
|
3089
3367
|
this.hovered = signal(false);
|
|
3090
3368
|
this.minimapPoint = computed(() => {
|
|
3091
|
-
switch (this.
|
|
3369
|
+
switch (this.position()) {
|
|
3092
3370
|
case 'top-left':
|
|
3093
3371
|
return { x: this.minimapOffset, y: this.minimapOffset };
|
|
3094
3372
|
case 'top-right':
|
|
3095
3373
|
return {
|
|
3096
|
-
x: this.flowSettingsService.computedFlowWidth() -
|
|
3097
|
-
|
|
3374
|
+
x: this.flowSettingsService.computedFlowWidth() -
|
|
3375
|
+
this.minimapWidth() -
|
|
3376
|
+
this.minimapOffset,
|
|
3377
|
+
y: this.minimapOffset,
|
|
3098
3378
|
};
|
|
3099
3379
|
case 'bottom-left':
|
|
3100
3380
|
return {
|
|
3101
3381
|
x: this.minimapOffset,
|
|
3102
|
-
y: this.flowSettingsService.computedFlowHeight() -
|
|
3382
|
+
y: this.flowSettingsService.computedFlowHeight() -
|
|
3383
|
+
this.minimapHeight() -
|
|
3384
|
+
this.minimapOffset,
|
|
3103
3385
|
};
|
|
3104
3386
|
case 'bottom-right':
|
|
3105
3387
|
return {
|
|
3106
|
-
x: this.flowSettingsService.computedFlowWidth() -
|
|
3107
|
-
|
|
3388
|
+
x: this.flowSettingsService.computedFlowWidth() -
|
|
3389
|
+
this.minimapWidth() -
|
|
3390
|
+
this.minimapOffset,
|
|
3391
|
+
y: this.flowSettingsService.computedFlowHeight() -
|
|
3392
|
+
this.minimapHeight() -
|
|
3393
|
+
this.minimapOffset,
|
|
3108
3394
|
};
|
|
3109
3395
|
}
|
|
3110
3396
|
});
|
|
@@ -3131,47 +3417,22 @@ class MiniMapComponent {
|
|
|
3131
3417
|
const scale = vport.zoom * this.minimapScale();
|
|
3132
3418
|
return `translate(${x} ${y}) scale(${scale})`;
|
|
3133
3419
|
});
|
|
3134
|
-
this.minimapPosition = signal('bottom-right');
|
|
3135
|
-
this.scaleOnHoverSignal = signal(false);
|
|
3136
|
-
}
|
|
3137
|
-
/**
|
|
3138
|
-
* The corner of the flow where to render a mini-map
|
|
3139
|
-
*/
|
|
3140
|
-
set position(value) {
|
|
3141
|
-
this.minimapPosition.set(value);
|
|
3142
|
-
}
|
|
3143
|
-
/**
|
|
3144
|
-
* Make a minimap bigger on hover
|
|
3145
|
-
*/
|
|
3146
|
-
set scaleOnHover(value) {
|
|
3147
|
-
this.scaleOnHoverSignal.set(value);
|
|
3148
3420
|
}
|
|
3149
3421
|
ngOnInit() {
|
|
3150
3422
|
const model = new MinimapModel();
|
|
3151
|
-
model.template.set(this.minimap);
|
|
3423
|
+
model.template.set(this.minimap());
|
|
3152
3424
|
this.entitiesService.minimap.set(model);
|
|
3153
3425
|
}
|
|
3154
3426
|
trackNodes(idx, { node }) {
|
|
3155
3427
|
return node;
|
|
3156
3428
|
}
|
|
3157
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3158
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3429
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3430
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MiniMapComponent, isStandalone: true, selector: "mini-map", inputs: { maskColor: { classPropertyName: "maskColor", publicName: "maskColor", isSignal: true, isRequired: false, transformFunction: null }, strokeColor: { classPropertyName: "strokeColor", publicName: "strokeColor", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "minimap", first: true, predicate: ["minimap"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\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 />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"], dependencies: [{ kind: "component", type: DefaultNodeComponent, selector: "default-node", inputs: ["selected"] }] }); }
|
|
3159
3431
|
}
|
|
3160
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3432
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MiniMapComponent, decorators: [{
|
|
3161
3433
|
type: Component,
|
|
3162
|
-
args: [{ selector: 'mini-map', template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n
|
|
3163
|
-
}]
|
|
3164
|
-
type: Input
|
|
3165
|
-
}], maskColor: [{
|
|
3166
|
-
type: Input
|
|
3167
|
-
}], strokeColor: [{
|
|
3168
|
-
type: Input
|
|
3169
|
-
}], scaleOnHover: [{
|
|
3170
|
-
type: Input
|
|
3171
|
-
}], minimap: [{
|
|
3172
|
-
type: ViewChild,
|
|
3173
|
-
args: ['minimap', { static: true }]
|
|
3174
|
-
}] } });
|
|
3434
|
+
args: [{ standalone: true, selector: 'mini-map', imports: [DefaultNodeComponent], template: "<ng-template #minimap>\n <svg:rect\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.stroke]=\"strokeColor()\"\n fill=\"none\"\n />\n\n <svg:svg\n [attr.x]=\"minimapPoint().x\"\n [attr.y]=\"minimapPoint().y\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n (mouseover)=\"hovered.set(true)\"\n (mouseleave)=\"hovered.set(false)\"\n >\n <svg:rect\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n [attr.fill]=\"maskColor()\"\n />\n\n <svg:g [attr.transform]=\"minimapTransform()\">\n <svg:rect\n [attr.fill]=\"viewportColor()\"\n [attr.transform]=\"viewportTransform()\"\n [attr.width]=\"minimapWidth()\"\n [attr.height]=\"minimapHeight()\"\n />\n\n @for (model of entitiesService.nodes(); track trackNodes($index, model)) {\n <ng-container>\n @if (\n model.node.type === \"default\" ||\n model.node.type === \"html-template\" ||\n model.isComponentType\n ) {\n <svg:foreignObject\n [attr.transform]=\"model.pointTransform()\"\n [attr.width]=\"model.size().width\"\n [attr.height]=\"model.size().height\"\n >\n <default-node\n [selected]=\"model.selected()\"\n [style.width.px]=\"model.size().width\"\n [style.height.px]=\"model.size().height\"\n [style.max-width.px]=\"model.size().width\"\n [style.max-height.px]=\"model.size().height\"\n >\n <div [outerHTML]=\"model.text()\"></div>\n </default-node>\n </svg:foreignObject>\n }\n @if (\n model.node.type === \"default-group\" ||\n model.node.type === \"template-group\"\n ) {\n <svg:rect\n class=\"default-group-node\"\n rx=\"5\"\n ry=\"5\"\n [attr.transform]=\"model.pointTransform()\"\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 />\n }\n </ng-container>\n }\n </svg:g>\n </svg:svg>\n</ng-template>\n", styles: [".default-group-node{stroke-width:1.5px;fill-opacity:.05}.default-group-node_selected{stroke-width:2px}\n"] }]
|
|
3435
|
+
}] });
|
|
3175
3436
|
|
|
3176
3437
|
class ToolbarModel {
|
|
3177
3438
|
constructor(node) {
|
|
@@ -3212,114 +3473,67 @@ class NodeToolbarComponent {
|
|
|
3212
3473
|
constructor() {
|
|
3213
3474
|
this.overlaysService = inject(OverlaysService);
|
|
3214
3475
|
this.nodeService = inject(NodeAccessorService);
|
|
3476
|
+
this.position = input('top');
|
|
3477
|
+
this.toolbarContentTemplate = viewChild.required('toolbar');
|
|
3215
3478
|
this.model = new ToolbarModel(this.nodeService.model());
|
|
3216
|
-
|
|
3217
|
-
set position(value) {
|
|
3218
|
-
this.model.position.set(value);
|
|
3479
|
+
effect(() => this.model.position.set(this.position()), { allowSignalWrites: true });
|
|
3219
3480
|
}
|
|
3220
3481
|
ngOnInit() {
|
|
3221
|
-
this.model.template.set(this.toolbarContentTemplate);
|
|
3482
|
+
this.model.template.set(this.toolbarContentTemplate());
|
|
3222
3483
|
this.overlaysService.addToolbar(this.model);
|
|
3223
3484
|
}
|
|
3224
3485
|
ngOnDestroy() {
|
|
3225
3486
|
this.overlaysService.removeToolbar(this.model);
|
|
3226
3487
|
}
|
|
3227
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3228
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3488
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3489
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.12", type: NodeToolbarComponent, isStandalone: true, selector: "node-toolbar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "toolbarContentTemplate", first: true, predicate: ["toolbar"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3229
3490
|
<ng-template #toolbar>
|
|
3230
3491
|
<div class="wrapper" nodeToolbarWrapper [model]="model">
|
|
3231
3492
|
<ng-content />
|
|
3232
3493
|
</div>
|
|
3233
3494
|
</ng-template>
|
|
3234
|
-
`, isInline: true, styles: [".wrapper{width:max-content}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(
|
|
3495
|
+
`, isInline: true, styles: [".wrapper{width:max-content}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => NodeToolbarWrapperDirective), selector: "[nodeToolbarWrapper]", inputs: ["model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3235
3496
|
}
|
|
3236
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarComponent, decorators: [{
|
|
3237
3498
|
type: Component,
|
|
3238
|
-
args: [{ selector: 'node-toolbar', template: `
|
|
3499
|
+
args: [{ standalone: true, selector: 'node-toolbar', template: `
|
|
3239
3500
|
<ng-template #toolbar>
|
|
3240
3501
|
<div class="wrapper" nodeToolbarWrapper [model]="model">
|
|
3241
3502
|
<ng-content />
|
|
3242
3503
|
</div>
|
|
3243
3504
|
</ng-template>
|
|
3244
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".wrapper{width:max-content}\n"] }]
|
|
3245
|
-
}],
|
|
3246
|
-
type: Input
|
|
3247
|
-
}], toolbarContentTemplate: [{
|
|
3248
|
-
type: ViewChild,
|
|
3249
|
-
args: ['toolbar', { static: true }]
|
|
3250
|
-
}] } });
|
|
3505
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [forwardRef(() => NodeToolbarWrapperDirective)], styles: [".wrapper{width:max-content}\n"] }]
|
|
3506
|
+
}], ctorParameters: () => [] });
|
|
3251
3507
|
class NodeToolbarWrapperDirective {
|
|
3252
3508
|
constructor() {
|
|
3253
3509
|
this.element = inject(ElementRef);
|
|
3510
|
+
this.model = input.required();
|
|
3254
3511
|
}
|
|
3255
3512
|
ngOnInit() {
|
|
3256
|
-
this.model.size.set({
|
|
3513
|
+
this.model().size.set({
|
|
3257
3514
|
width: this.element.nativeElement.clientWidth,
|
|
3258
|
-
height: this.element.nativeElement.clientHeight
|
|
3259
|
-
});
|
|
3260
|
-
}
|
|
3261
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarWrapperDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3262
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: NodeToolbarWrapperDirective, selector: "[nodeToolbarWrapper]", inputs: { model: "model" }, ngImport: i0 }); }
|
|
3263
|
-
}
|
|
3264
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NodeToolbarWrapperDirective, decorators: [{
|
|
3265
|
-
type: Directive,
|
|
3266
|
-
args: [{ selector: '[nodeToolbarWrapper]' }]
|
|
3267
|
-
}], propDecorators: { model: [{
|
|
3268
|
-
type: Input
|
|
3269
|
-
}] } });
|
|
3270
|
-
|
|
3271
|
-
class DragHandleDirective {
|
|
3272
|
-
get model() {
|
|
3273
|
-
return this.nodeAccessor.model();
|
|
3274
|
-
}
|
|
3275
|
-
constructor() {
|
|
3276
|
-
this.nodeAccessor = inject(NodeAccessorService);
|
|
3277
|
-
this.model.dragHandlesCount.update((count) => count + 1);
|
|
3278
|
-
inject(DestroyRef).onDestroy(() => {
|
|
3279
|
-
this.model.dragHandlesCount.update(count => count - 1);
|
|
3515
|
+
height: this.element.nativeElement.clientHeight,
|
|
3280
3516
|
});
|
|
3281
3517
|
}
|
|
3282
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3283
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
3518
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarWrapperDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3519
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.12", type: NodeToolbarWrapperDirective, isStandalone: true, selector: "[nodeToolbarWrapper]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
3284
3520
|
}
|
|
3285
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3521
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NodeToolbarWrapperDirective, decorators: [{
|
|
3286
3522
|
type: Directive,
|
|
3287
3523
|
args: [{
|
|
3288
|
-
selector: '[
|
|
3289
|
-
|
|
3290
|
-
'class': 'vflow-drag-handle'
|
|
3291
|
-
}
|
|
3524
|
+
selector: '[nodeToolbarWrapper]',
|
|
3525
|
+
standalone: true
|
|
3292
3526
|
}]
|
|
3293
|
-
}]
|
|
3527
|
+
}] });
|
|
3294
3528
|
|
|
3295
|
-
const
|
|
3529
|
+
const Vflow = [
|
|
3296
3530
|
VflowComponent,
|
|
3297
|
-
NodeComponent,
|
|
3298
|
-
DefaultNodeComponent,
|
|
3299
|
-
EdgeComponent,
|
|
3300
|
-
EdgeLabelComponent,
|
|
3301
|
-
ConnectionComponent,
|
|
3302
3531
|
HandleComponent,
|
|
3303
|
-
DefsComponent,
|
|
3304
|
-
BackgroundComponent,
|
|
3305
3532
|
ResizableComponent,
|
|
3306
|
-
MiniMapComponent,
|
|
3307
|
-
NodeToolbarComponent
|
|
3308
|
-
];
|
|
3309
|
-
const directives = [
|
|
3310
|
-
SpacePointContextDirective,
|
|
3311
|
-
MapContextDirective,
|
|
3312
|
-
RootSvgReferenceDirective,
|
|
3313
|
-
RootSvgContextDirective,
|
|
3314
|
-
HandleSizeControllerDirective,
|
|
3315
3533
|
SelectableDirective,
|
|
3534
|
+
MiniMapComponent,
|
|
3535
|
+
NodeToolbarComponent,
|
|
3316
3536
|
DragHandleDirective,
|
|
3317
|
-
PointerDirective,
|
|
3318
|
-
RootPointerDirective,
|
|
3319
|
-
FlowSizeControllerDirective,
|
|
3320
|
-
NodeToolbarWrapperDirective
|
|
3321
|
-
];
|
|
3322
|
-
const templateDirectives = [
|
|
3323
3537
|
NodeHtmlTemplateDirective,
|
|
3324
3538
|
GroupNodeTemplateDirective,
|
|
3325
3539
|
EdgeLabelHtmlTemplateDirective,
|
|
@@ -3327,65 +3541,6 @@ const templateDirectives = [
|
|
|
3327
3541
|
ConnectionTemplateDirective,
|
|
3328
3542
|
HandleTemplateDirective
|
|
3329
3543
|
];
|
|
3330
|
-
class VflowModule {
|
|
3331
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3332
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, declarations: [VflowComponent,
|
|
3333
|
-
NodeComponent,
|
|
3334
|
-
DefaultNodeComponent,
|
|
3335
|
-
EdgeComponent,
|
|
3336
|
-
EdgeLabelComponent,
|
|
3337
|
-
ConnectionComponent,
|
|
3338
|
-
HandleComponent,
|
|
3339
|
-
DefsComponent,
|
|
3340
|
-
BackgroundComponent,
|
|
3341
|
-
ResizableComponent,
|
|
3342
|
-
MiniMapComponent,
|
|
3343
|
-
NodeToolbarComponent, SpacePointContextDirective,
|
|
3344
|
-
MapContextDirective,
|
|
3345
|
-
RootSvgReferenceDirective,
|
|
3346
|
-
RootSvgContextDirective,
|
|
3347
|
-
HandleSizeControllerDirective,
|
|
3348
|
-
SelectableDirective,
|
|
3349
|
-
DragHandleDirective,
|
|
3350
|
-
PointerDirective,
|
|
3351
|
-
RootPointerDirective,
|
|
3352
|
-
FlowSizeControllerDirective,
|
|
3353
|
-
NodeToolbarWrapperDirective, NodeHtmlTemplateDirective,
|
|
3354
|
-
GroupNodeTemplateDirective,
|
|
3355
|
-
EdgeLabelHtmlTemplateDirective,
|
|
3356
|
-
EdgeTemplateDirective,
|
|
3357
|
-
ConnectionTemplateDirective,
|
|
3358
|
-
HandleTemplateDirective], imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe], exports: [VflowComponent,
|
|
3359
|
-
HandleComponent,
|
|
3360
|
-
ResizableComponent,
|
|
3361
|
-
SelectableDirective,
|
|
3362
|
-
MiniMapComponent,
|
|
3363
|
-
NodeToolbarComponent,
|
|
3364
|
-
DragHandleDirective, NodeHtmlTemplateDirective,
|
|
3365
|
-
GroupNodeTemplateDirective,
|
|
3366
|
-
EdgeLabelHtmlTemplateDirective,
|
|
3367
|
-
EdgeTemplateDirective,
|
|
3368
|
-
ConnectionTemplateDirective,
|
|
3369
|
-
HandleTemplateDirective] }); }
|
|
3370
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule }); }
|
|
3371
|
-
}
|
|
3372
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: VflowModule, decorators: [{
|
|
3373
|
-
type: NgModule,
|
|
3374
|
-
args: [{
|
|
3375
|
-
imports: [NgIf, NgFor, NgTemplateOutlet, NgComponentOutlet, KeyValuePipe],
|
|
3376
|
-
exports: [
|
|
3377
|
-
VflowComponent,
|
|
3378
|
-
HandleComponent,
|
|
3379
|
-
ResizableComponent,
|
|
3380
|
-
SelectableDirective,
|
|
3381
|
-
MiniMapComponent,
|
|
3382
|
-
NodeToolbarComponent,
|
|
3383
|
-
DragHandleDirective,
|
|
3384
|
-
...templateDirectives
|
|
3385
|
-
],
|
|
3386
|
-
declarations: [...components, ...directives, ...templateDirectives],
|
|
3387
|
-
}]
|
|
3388
|
-
}] });
|
|
3389
3544
|
|
|
3390
3545
|
const mockModel = () => new NodeModel({ id: 'mock', type: 'default', point: { x: 0, y: 0 } });
|
|
3391
3546
|
function provideCustomNodeMocks() {
|
|
@@ -3442,11 +3597,11 @@ function provideCustomNodeMocks() {
|
|
|
3442
3597
|
];
|
|
3443
3598
|
}
|
|
3444
3599
|
|
|
3445
|
-
//
|
|
3600
|
+
// Standalone Util
|
|
3446
3601
|
|
|
3447
3602
|
/**
|
|
3448
3603
|
* Generated bundle index. Do not edit.
|
|
3449
3604
|
*/
|
|
3450
3605
|
|
|
3451
|
-
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective,
|
|
3606
|
+
export { ChangesControllerDirective, ConnectionControllerDirective, ConnectionTemplateDirective, CustomDynamicNodeComponent, CustomNodeComponent, DragHandleDirective, EdgeLabelHtmlTemplateDirective, EdgeTemplateDirective, GroupNodeTemplateDirective, HandleComponent, HandleTemplateDirective, MiniMapComponent, NodeHtmlTemplateDirective, NodeToolbarComponent, NodeToolbarWrapperDirective, ResizableComponent, SelectableDirective, Vflow, VflowComponent, isComponentDynamicNode, isComponentStaticNode, isDefaultDynamicGroupNode, isDefaultDynamicNode, isDefaultStaticGroupNode, isDefaultStaticNode, isDynamicNode, isStaticNode, isTemplateDynamicGroupNode, isTemplateDynamicNode, isTemplateStaticGroupNode, isTemplateStaticNode, provideCustomNodeMocks };
|
|
3452
3607
|
//# sourceMappingURL=ngx-vflow.mjs.map
|