@masterteam/structure-builder 0.0.41 → 0.0.42
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, Component, ChangeDetectionStrategy, output, viewChild, model, contentChild, computed, signal, effect } from '@angular/core';
|
|
2
|
+
import { inject, input, Component, ChangeDetectionStrategy, output, viewChild, model, contentChild, computed, signal, effect, untracked } from '@angular/core';
|
|
3
3
|
import * as i3 from '@jsverse/transloco';
|
|
4
4
|
import { TranslocoModule, TranslocoService } from '@jsverse/transloco';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
@@ -32,7 +32,7 @@ class NodeFormDialogComponent {
|
|
|
32
32
|
dynamicFormControl = new FormControl();
|
|
33
33
|
nodeData = {};
|
|
34
34
|
formSchema;
|
|
35
|
-
data = input(null, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
35
|
+
data = input(null, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
36
36
|
ngOnInit() {
|
|
37
37
|
this.nodeData = this.data()?.node ?? {};
|
|
38
38
|
this.formSchema = this.data()?.formSchema ?? [];
|
|
@@ -67,10 +67,10 @@ class NodeFormDialogComponent {
|
|
|
67
67
|
onCancel() {
|
|
68
68
|
this.ref.close();
|
|
69
69
|
}
|
|
70
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
71
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
70
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NodeFormDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
71
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NodeFormDialogComponent, isStandalone: true, selector: "mt-node-form-dialog", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"[modalService.contentClass, 'p-4']\">\r\n @if (this.data()?.template) {\r\n <ng-container\r\n *ngTemplateOutlet=\"data().template; context: templateContext\"\r\n ></ng-container>\r\n } @else {\r\n @if (nodeData) {\r\n <mt-dynamic-form\r\n [formConfig]=\"formSchema\"\r\n [formControl]=\"dynamicFormControl\"\r\n ></mt-dynamic-form>\r\n }\r\n }\r\n</div>\r\n<div [class]=\"modalService.footerClass\">\r\n <mt-button\r\n [label]=\"'structureBuilder.cancel' | transloco\"\r\n severity=\"secondary\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n @if (showSaveButton()) {\r\n <mt-button\r\n [disabled]=\"disableSaveButton()\"\r\n [label]=\"'structureBuilder.saveChanges' | transloco\"\r\n severity=\"primary\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i3.TranslocoPipe, name: "transloco" }] });
|
|
72
72
|
}
|
|
73
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NodeFormDialogComponent, decorators: [{
|
|
74
74
|
type: Component,
|
|
75
75
|
args: [{ selector: 'mt-node-form-dialog', standalone: true, imports: [
|
|
76
76
|
CommonModule,
|
|
@@ -84,7 +84,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
84
84
|
class ConnectionFormDialogComponent {
|
|
85
85
|
modalService = inject(ModalService);
|
|
86
86
|
ref = inject(ModalRef);
|
|
87
|
-
data = input(null, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
87
|
+
data = input(null, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
88
88
|
defaultToolbarTabs = [
|
|
89
89
|
'functions',
|
|
90
90
|
'properties',
|
|
@@ -120,10 +120,10 @@ class ConnectionFormDialogComponent {
|
|
|
120
120
|
onCancel() {
|
|
121
121
|
this.ref.close();
|
|
122
122
|
}
|
|
123
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
124
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
123
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ConnectionFormDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
124
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ConnectionFormDialogComponent, isStandalone: true, selector: "mt-connection-form-dialog", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\r\n [class]=\"\r\n modalService.contentClass +\r\n ' max-h-[80vh] overflow-x-hidden overflow-y-auto p-4'\r\n \"\r\n>\r\n <div class=\"space-y-6\">\r\n @if (formSchema?.sections?.length > 0) {\r\n <mt-dynamic-form\r\n class=\"block\"\r\n [formConfig]=\"formSchema\"\r\n [formControl]=\"dynamicFormControl\"\r\n ></mt-dynamic-form>\r\n }\r\n\r\n @if (formulaSchemaId) {\r\n <mt-card [title]=\"'structureBuilder.formula' | transloco\">\r\n <mt-formula-builder\r\n [formControl]=\"formulaControl\"\r\n [levelSchemaId]=\"formulaSchemaId\"\r\n [toolbarTabs]=\"formulaConfig.toolbarTabs ?? defaultToolbarTabs\"\r\n [codeOnly]=\"formulaConfig.codeOnly ?? false\"\r\n [hideToolbar]=\"formulaConfig.hideToolbar ?? false\"\r\n [hideStatusBar]=\"formulaConfig.hideStatusBar ?? false\"\r\n [isProcessBuilder]=\"formulaConfig.isProcessBuilder ?? false\"\r\n />\r\n </mt-card>\r\n }\r\n </div>\r\n</div>\r\n\r\n<div [class]=\"modalService.footerClass\">\r\n <mt-button\r\n [label]=\"'structureBuilder.cancel' | transloco\"\r\n severity=\"secondary\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n [disabled]=\"!dynamicFormControl.valid\"\r\n [label]=\"'structureBuilder.saveChanges' | transloco\"\r\n severity=\"primary\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: FormulaBuilder, selector: "mt-formula-builder", inputs: ["propertiesByPath", "levelSchemaId", "moduleId", "contextEntityTypeKey", "templateId", "placeholder", "hideToolbar", "hideStatusBar", "toolbarTabs", "codeOnly", "isProcessBuilder"], outputs: ["validationChange", "tokensChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i3.TranslocoPipe, name: "transloco" }] });
|
|
125
125
|
}
|
|
126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
126
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ConnectionFormDialogComponent, decorators: [{
|
|
127
127
|
type: Component,
|
|
128
128
|
args: [{ selector: 'mt-connection-form-dialog', standalone: true, imports: [
|
|
129
129
|
CommonModule,
|
|
@@ -137,7 +137,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
137
137
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
138
138
|
|
|
139
139
|
class Toolbar {
|
|
140
|
-
size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : []));
|
|
140
|
+
size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ []));
|
|
141
141
|
builderComponent = inject(StructureBuilder);
|
|
142
142
|
onZoomIn() {
|
|
143
143
|
this.builderComponent.fZoomDirective()?.zoomIn();
|
|
@@ -156,10 +156,10 @@ class Toolbar {
|
|
|
156
156
|
autoLayout() {
|
|
157
157
|
this.builderComponent.maybeAutoLayout();
|
|
158
158
|
}
|
|
159
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
160
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.
|
|
159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Toolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
160
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: Toolbar, isStandalone: true, selector: "mt-toolbar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-button\r\n (onClick)=\"autoLayout()\"\r\n class=\"bg-content rounded-(--p-button-border-radius)\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"arrow.refresh-cw-05\"\r\n></mt-button>\r\n\r\n<mt-buttongroup class=\"bg-content rounded-(--p-button-border-radius)\">\r\n <mt-button\r\n (onClick)=\"onZoomOut()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"general.minus\"\r\n ></mt-button>\r\n <mt-button\r\n (onClick)=\"onZoomIn()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"general.plus\"\r\n ></mt-button>\r\n <mt-button\r\n (onClick)=\"onFitToScreen()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"layout.grid-02\"\r\n ></mt-button>\r\n</mt-buttongroup>\r\n", styles: [":host{display:flex;justify-content:flex-end;align-items:center;position:absolute;gap:calc(var(--spacing) * 2);inset-inline-end:calc(var(--spacing) * 4);bottom:calc(var(--spacing) * 4)}\n"], dependencies: [{ kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ButtonGroup, selector: "mt-buttonGroup, mt-buttongroup, mt-button-group" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
161
161
|
}
|
|
162
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Toolbar, decorators: [{
|
|
163
163
|
type: Component,
|
|
164
164
|
args: [{ selector: 'mt-toolbar', imports: [Button, ButtonGroup], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mt-button\r\n (onClick)=\"autoLayout()\"\r\n class=\"bg-content rounded-(--p-button-border-radius)\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"arrow.refresh-cw-05\"\r\n></mt-button>\r\n\r\n<mt-buttongroup class=\"bg-content rounded-(--p-button-border-radius)\">\r\n <mt-button\r\n (onClick)=\"onZoomOut()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"general.minus\"\r\n ></mt-button>\r\n <mt-button\r\n (onClick)=\"onZoomIn()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"general.plus\"\r\n ></mt-button>\r\n <mt-button\r\n (onClick)=\"onFitToScreen()\"\r\n size=\"size()\"\r\n variant=\"outlined\"\r\n severity=\"secondary\"\r\n icon=\"layout.grid-02\"\r\n ></mt-button>\r\n</mt-buttongroup>\r\n", styles: [":host{display:flex;justify-content:flex-end;align-items:center;position:absolute;gap:calc(var(--spacing) * 2);inset-inline-end:calc(var(--spacing) * 4);bottom:calc(var(--spacing) * 4)}\n"] }]
|
|
165
165
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
@@ -185,6 +185,10 @@ const CONFIGURATION = {
|
|
|
185
185
|
inputSide: 'top',
|
|
186
186
|
},
|
|
187
187
|
};
|
|
188
|
+
const VERTICAL_CONNECTOR_SIDES = ['top', 'bottom'];
|
|
189
|
+
const HORIZONTAL_CONNECTOR_SIDES = ['left', 'right'];
|
|
190
|
+
const CONNECTOR_ID_SEPARATOR = '__sb-connector__';
|
|
191
|
+
const STRUCTURE_BUILDER_CONNECTOR_SUFFIX = /__sb-connector__(input|output)__(top|bottom|left|right)$/;
|
|
188
192
|
class StructureBuilder {
|
|
189
193
|
dialogService = inject(DialogService);
|
|
190
194
|
drawerService = inject(DrawerService);
|
|
@@ -193,53 +197,56 @@ class StructureBuilder {
|
|
|
193
197
|
dir = inject(Directionality, { optional: true });
|
|
194
198
|
nodeActionsEvent = output();
|
|
195
199
|
action = output();
|
|
196
|
-
availableNodes = input([], ...(ngDevMode ? [{ debugName: "availableNodes" }] : []));
|
|
197
|
-
fCanvas = viewChild(FCanvasComponent, ...(ngDevMode ? [{ debugName: "fCanvas" }] : []));
|
|
198
|
-
fFlowComponent = viewChild(FFlowComponent, ...(ngDevMode ? [{ debugName: "fFlowComponent" }] : []));
|
|
199
|
-
fCanvasComponent = viewChild(FCanvasComponent, ...(ngDevMode ? [{ debugName: "fCanvasComponent" }] : []));
|
|
200
|
-
fZoomDirective = viewChild(FZoomDirective, ...(ngDevMode ? [{ debugName: "fZoomDirective" }] : []));
|
|
201
|
-
nodeForm = input({ sections: [] }, ...(ngDevMode ? [{ debugName: "nodeForm" }] : []));
|
|
202
|
-
nodeDialogFooterConfig = input(null, ...(ngDevMode ? [{ debugName: "nodeDialogFooterConfig" }] : []));
|
|
203
|
-
connectionForm = input({ sections: [] }, ...(ngDevMode ? [{ debugName: "connectionForm" }] : []));
|
|
204
|
-
connectionFormulaSchemaId = input(undefined, ...(ngDevMode ? [{ debugName: "connectionFormulaSchemaId" }] : []));
|
|
205
|
-
connectionFormulaConfig = input(null, ...(ngDevMode ? [{ debugName: "connectionFormulaConfig" }] : []));
|
|
206
|
-
nodeActions = input([], ...(ngDevMode ? [{ debugName: "nodeActions" }] : []));
|
|
200
|
+
availableNodes = input([], ...(ngDevMode ? [{ debugName: "availableNodes" }] : /* istanbul ignore next */ []));
|
|
201
|
+
fCanvas = viewChild(FCanvasComponent, ...(ngDevMode ? [{ debugName: "fCanvas" }] : /* istanbul ignore next */ []));
|
|
202
|
+
fFlowComponent = viewChild(FFlowComponent, ...(ngDevMode ? [{ debugName: "fFlowComponent" }] : /* istanbul ignore next */ []));
|
|
203
|
+
fCanvasComponent = viewChild(FCanvasComponent, ...(ngDevMode ? [{ debugName: "fCanvasComponent" }] : /* istanbul ignore next */ []));
|
|
204
|
+
fZoomDirective = viewChild(FZoomDirective, ...(ngDevMode ? [{ debugName: "fZoomDirective" }] : /* istanbul ignore next */ []));
|
|
205
|
+
nodeForm = input({ sections: [] }, ...(ngDevMode ? [{ debugName: "nodeForm" }] : /* istanbul ignore next */ []));
|
|
206
|
+
nodeDialogFooterConfig = input(null, ...(ngDevMode ? [{ debugName: "nodeDialogFooterConfig" }] : /* istanbul ignore next */ []));
|
|
207
|
+
connectionForm = input({ sections: [] }, ...(ngDevMode ? [{ debugName: "connectionForm" }] : /* istanbul ignore next */ []));
|
|
208
|
+
connectionFormulaSchemaId = input(undefined, ...(ngDevMode ? [{ debugName: "connectionFormulaSchemaId" }] : /* istanbul ignore next */ []));
|
|
209
|
+
connectionFormulaConfig = input(null, ...(ngDevMode ? [{ debugName: "connectionFormulaConfig" }] : /* istanbul ignore next */ []));
|
|
210
|
+
nodeActions = input([], ...(ngDevMode ? [{ debugName: "nodeActions" }] : /* istanbul ignore next */ []));
|
|
207
211
|
nodeFields = input({
|
|
208
212
|
id: 'id',
|
|
209
213
|
name: 'name',
|
|
210
214
|
icon: 'icon',
|
|
211
215
|
color: 'color',
|
|
212
|
-
}, ...(ngDevMode ? [{ debugName: "nodeFields" }] : []));
|
|
213
|
-
isAutoLayout = input(true, ...(ngDevMode ? [{ debugName: "isAutoLayout" }] : []));
|
|
214
|
-
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
215
|
-
addModalType = input('dialog', ...(ngDevMode ? [{ debugName: "addModalType" }] : []));
|
|
216
|
-
updateModalType = input('drawer', ...(ngDevMode ? [{ debugName: "updateModalType" }] : []));
|
|
217
|
-
addModalStyleClass = input('!w-[35rem]', ...(ngDevMode ? [{ debugName: "addModalStyleClass" }] : []));
|
|
218
|
-
updateModalStyleClass = input('!w-[35rem]', ...(ngDevMode ? [{ debugName: "updateModalStyleClass" }] : []));
|
|
219
|
-
addModalHeader = input('', ...(ngDevMode ? [{ debugName: "addModalHeader" }] : []));
|
|
220
|
-
updateModalHeader = input('', ...(ngDevMode ? [{ debugName: "updateModalHeader" }] : []));
|
|
221
|
-
appendTo = input('', ...(ngDevMode ? [{ debugName: "appendTo" }] : []));
|
|
222
|
-
availableTabsClass = input('', ...(ngDevMode ? [{ debugName: "availableTabsClass" }] : []));
|
|
223
|
-
layoutDirection = input(Direction.TOP_TO_BOTTOM, ...(ngDevMode ? [{ debugName: "layoutDirection" }] : []));
|
|
224
|
-
nodes = model([], ...(ngDevMode ? [{ debugName: "nodes" }] : []));
|
|
225
|
-
connections = model([], ...(ngDevMode ? [{ debugName: "connections" }] : []));
|
|
226
|
-
nodeDialogTemplate = contentChild('nodeDialog', ...(ngDevMode ? [{ debugName: "nodeDialogTemplate" }] : []));
|
|
227
|
-
nodeTemplate = input(null, ...(ngDevMode ? [{ debugName: "nodeTemplate" }] : []));
|
|
228
|
-
nodeTemplateContent = contentChild('nodeTemplate', ...(ngDevMode ? [{ debugName: "nodeTemplateContent" }] : []));
|
|
229
|
-
effectiveNodeTemplate = computed(() => this.nodeTemplate() || this.nodeTemplateContent() || null, ...(ngDevMode ? [{ debugName: "effectiveNodeTemplate" }] : []));
|
|
230
|
-
contentDirection = computed(() => this.dir?.value ?? 'ltr', ...(ngDevMode ? [{ debugName: "contentDirection" }] : []));
|
|
231
|
-
collapsedConnectionIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "collapsedConnectionIds" }] : []));
|
|
232
|
-
activeTab = signal('0', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
216
|
+
}, ...(ngDevMode ? [{ debugName: "nodeFields" }] : /* istanbul ignore next */ []));
|
|
217
|
+
isAutoLayout = input(true, ...(ngDevMode ? [{ debugName: "isAutoLayout" }] : /* istanbul ignore next */ []));
|
|
218
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
219
|
+
addModalType = input('dialog', ...(ngDevMode ? [{ debugName: "addModalType" }] : /* istanbul ignore next */ []));
|
|
220
|
+
updateModalType = input('drawer', ...(ngDevMode ? [{ debugName: "updateModalType" }] : /* istanbul ignore next */ []));
|
|
221
|
+
addModalStyleClass = input('!w-[35rem]', ...(ngDevMode ? [{ debugName: "addModalStyleClass" }] : /* istanbul ignore next */ []));
|
|
222
|
+
updateModalStyleClass = input('!w-[35rem]', ...(ngDevMode ? [{ debugName: "updateModalStyleClass" }] : /* istanbul ignore next */ []));
|
|
223
|
+
addModalHeader = input('', ...(ngDevMode ? [{ debugName: "addModalHeader" }] : /* istanbul ignore next */ []));
|
|
224
|
+
updateModalHeader = input('', ...(ngDevMode ? [{ debugName: "updateModalHeader" }] : /* istanbul ignore next */ []));
|
|
225
|
+
appendTo = input('', ...(ngDevMode ? [{ debugName: "appendTo" }] : /* istanbul ignore next */ []));
|
|
226
|
+
availableTabsClass = input('', ...(ngDevMode ? [{ debugName: "availableTabsClass" }] : /* istanbul ignore next */ []));
|
|
227
|
+
layoutDirection = input(Direction.TOP_TO_BOTTOM, ...(ngDevMode ? [{ debugName: "layoutDirection" }] : /* istanbul ignore next */ []));
|
|
228
|
+
nodes = model([], ...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
|
|
229
|
+
connections = model([], ...(ngDevMode ? [{ debugName: "connections" }] : /* istanbul ignore next */ []));
|
|
230
|
+
nodeDialogTemplate = contentChild('nodeDialog', ...(ngDevMode ? [{ debugName: "nodeDialogTemplate" }] : /* istanbul ignore next */ []));
|
|
231
|
+
nodeTemplate = input(null, ...(ngDevMode ? [{ debugName: "nodeTemplate" }] : /* istanbul ignore next */ []));
|
|
232
|
+
nodeTemplateContent = contentChild('nodeTemplate', ...(ngDevMode ? [{ debugName: "nodeTemplateContent" }] : /* istanbul ignore next */ []));
|
|
233
|
+
effectiveNodeTemplate = computed(() => this.nodeTemplate() || this.nodeTemplateContent() || null, ...(ngDevMode ? [{ debugName: "effectiveNodeTemplate" }] : /* istanbul ignore next */ []));
|
|
234
|
+
contentDirection = computed(() => this.dir?.value ?? 'ltr', ...(ngDevMode ? [{ debugName: "contentDirection" }] : /* istanbul ignore next */ []));
|
|
235
|
+
collapsedConnectionIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "collapsedConnectionIds" }] : /* istanbul ignore next */ []));
|
|
236
|
+
activeTab = signal('0', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
233
237
|
eMarkerType = EFMarkerType;
|
|
234
|
-
effectiveDirection = computed(() => this.resolveDirection(this.layoutDirection()), ...(ngDevMode ? [{ debugName: "effectiveDirection" }] : []));
|
|
235
|
-
configuration = computed(() => CONFIGURATION[this.effectiveDirection()], ...(ngDevMode ? [{ debugName: "configuration" }] : []));
|
|
238
|
+
effectiveDirection = computed(() => this.resolveDirection(this.layoutDirection()), ...(ngDevMode ? [{ debugName: "effectiveDirection" }] : /* istanbul ignore next */ []));
|
|
239
|
+
configuration = computed(() => CONFIGURATION[this.effectiveDirection()], ...(ngDevMode ? [{ debugName: "configuration" }] : /* istanbul ignore next */ []));
|
|
240
|
+
nodeConnectorSides = computed(() => this.effectiveDirection() === Direction.TOP_TO_BOTTOM
|
|
241
|
+
? VERTICAL_CONNECTOR_SIDES
|
|
242
|
+
: HORIZONTAL_CONNECTOR_SIDES, ...(ngDevMode ? [{ debugName: "nodeConnectorSides" }] : /* istanbul ignore next */ []));
|
|
236
243
|
nodeActionHandler = (action, node) => {
|
|
237
244
|
this.buttonAction(action, node);
|
|
238
245
|
};
|
|
239
246
|
getFilteredNodeActions = (node) => this.readonly()
|
|
240
247
|
? []
|
|
241
248
|
: this.nodeActions().filter((action) => !action.condition || action.condition(node));
|
|
242
|
-
positions = signal({}, ...(ngDevMode ? [{ debugName: "positions" }] : []));
|
|
249
|
+
positions = signal({}, ...(ngDevMode ? [{ debugName: "positions" }] : /* istanbul ignore next */ []));
|
|
243
250
|
dialogRef;
|
|
244
251
|
fields = computed(() => {
|
|
245
252
|
const inputFields = this.nodeFields();
|
|
@@ -249,7 +256,7 @@ class StructureBuilder {
|
|
|
249
256
|
icon: inputFields.icon || 'icon',
|
|
250
257
|
color: inputFields.color || 'color',
|
|
251
258
|
};
|
|
252
|
-
}, ...(ngDevMode ? [{ debugName: "fields" }] : []));
|
|
259
|
+
}, ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
253
260
|
availableTabs = computed(() => {
|
|
254
261
|
const tabsSet = new Set();
|
|
255
262
|
this.availableNodes().forEach((node) => {
|
|
@@ -258,7 +265,7 @@ class StructureBuilder {
|
|
|
258
265
|
}
|
|
259
266
|
});
|
|
260
267
|
return Array.from(tabsSet).sort();
|
|
261
|
-
}, ...(ngDevMode ? [{ debugName: "availableTabs" }] : []));
|
|
268
|
+
}, ...(ngDevMode ? [{ debugName: "availableTabs" }] : /* istanbul ignore next */ []));
|
|
262
269
|
currentTabNodes = computed(() => {
|
|
263
270
|
const tabs = this.availableTabs();
|
|
264
271
|
const currentTabIndex = parseInt(this.activeTab());
|
|
@@ -266,7 +273,7 @@ class StructureBuilder {
|
|
|
266
273
|
return [];
|
|
267
274
|
const currentTab = tabs[currentTabIndex];
|
|
268
275
|
return this.availableNodes().filter((node) => node.tab.includes(currentTab));
|
|
269
|
-
}, ...(ngDevMode ? [{ debugName: "currentTabNodes" }] : []));
|
|
276
|
+
}, ...(ngDevMode ? [{ debugName: "currentTabNodes" }] : /* istanbul ignore next */ []));
|
|
270
277
|
nodesWithComputedProps = computed(() => {
|
|
271
278
|
const fields = this.fields();
|
|
272
279
|
const pos = this.positions();
|
|
@@ -288,12 +295,29 @@ class StructureBuilder {
|
|
|
288
295
|
configuration,
|
|
289
296
|
};
|
|
290
297
|
});
|
|
291
|
-
}, ...(ngDevMode ? [{ debugName: "nodesWithComputedProps" }] : []));
|
|
298
|
+
}, ...(ngDevMode ? [{ debugName: "nodesWithComputedProps" }] : /* istanbul ignore next */ []));
|
|
299
|
+
nodePositionsById = computed(() => this.nodesWithComputedProps().reduce((positions, node) => {
|
|
300
|
+
positions[node._computedId] = {
|
|
301
|
+
x: node.configuration?.x ?? 0,
|
|
302
|
+
y: node.configuration?.y ?? 0,
|
|
303
|
+
};
|
|
304
|
+
return positions;
|
|
305
|
+
}, {}), ...(ngDevMode ? [{ debugName: "nodePositionsById" }] : /* istanbul ignore next */ []));
|
|
292
306
|
connectionsComputed = computed(() => this.connections()?.map((c) => ({
|
|
293
307
|
...c,
|
|
294
|
-
from: String(c.from),
|
|
295
|
-
to: String(c.to),
|
|
296
|
-
})), ...(ngDevMode ? [{ debugName: "connectionsComputed" }] : []));
|
|
308
|
+
from: this.extractNodeId(String(c.from)),
|
|
309
|
+
to: this.extractNodeId(String(c.to)),
|
|
310
|
+
})), ...(ngDevMode ? [{ debugName: "connectionsComputed" }] : /* istanbul ignore next */ []));
|
|
311
|
+
renderedConnections = computed(() => this.connectionsComputed().map((connection) => {
|
|
312
|
+
const { inputSide, outputSide } = this.resolveConnectionConnectorSides(connection);
|
|
313
|
+
return {
|
|
314
|
+
...connection,
|
|
315
|
+
_inputConnectorId: this.createConnectorId(connection.to, 'input', inputSide),
|
|
316
|
+
_inputSide: inputSide,
|
|
317
|
+
_outputConnectorId: this.createConnectorId(connection.from, 'output', outputSide),
|
|
318
|
+
_outputSide: outputSide,
|
|
319
|
+
};
|
|
320
|
+
}), ...(ngDevMode ? [{ debugName: "renderedConnections" }] : /* istanbul ignore next */ []));
|
|
297
321
|
coreFields = computed(() => {
|
|
298
322
|
const fields = this.fields();
|
|
299
323
|
return new Set([
|
|
@@ -304,7 +328,7 @@ class StructureBuilder {
|
|
|
304
328
|
'_computedIcon',
|
|
305
329
|
'_computedColor',
|
|
306
330
|
]);
|
|
307
|
-
}, ...(ngDevMode ? [{ debugName: "coreFields" }] : []));
|
|
331
|
+
}, ...(ngDevMode ? [{ debugName: "coreFields" }] : /* istanbul ignore next */ []));
|
|
308
332
|
constructor() {
|
|
309
333
|
effect(() => {
|
|
310
334
|
const direction = this.effectiveDirection();
|
|
@@ -366,14 +390,16 @@ class StructureBuilder {
|
|
|
366
390
|
if (this.readonly()) {
|
|
367
391
|
return;
|
|
368
392
|
}
|
|
393
|
+
const sourceId = this.extractNodeId(event.sourceId ?? event.fOutputId ?? '');
|
|
394
|
+
const targetId = this.extractNodeId(event.targetId ?? event.fInputId ?? '');
|
|
395
|
+
if (!sourceId || !targetId) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
369
398
|
const newConnection = {
|
|
370
399
|
id: this.generateConnectionId(),
|
|
371
|
-
from:
|
|
372
|
-
to:
|
|
400
|
+
from: sourceId,
|
|
401
|
+
to: targetId,
|
|
373
402
|
};
|
|
374
|
-
if (!event.fInputId || !event.fOutputId) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
403
|
const exists = this.connectionsComputed().some((conn) => conn.from === newConnection.from && conn.to === newConnection.to);
|
|
378
404
|
if (!exists) {
|
|
379
405
|
if (this.connectionForm()?.sections.length > 0 ||
|
|
@@ -525,6 +551,7 @@ class StructureBuilder {
|
|
|
525
551
|
updateGraph(graph, direction) {
|
|
526
552
|
graph.setGraph({ rankdir: direction });
|
|
527
553
|
const SIZE = { width: 300, height: 200 };
|
|
554
|
+
const nodePositions = untracked(this.nodePositionsById);
|
|
528
555
|
const nodeIds = this.nodes()
|
|
529
556
|
.map((node) => this.getNestedValue(node, this.fields().id))
|
|
530
557
|
.filter((nodeId) => nodeId !== null && nodeId !== undefined && `${nodeId}` !== '')
|
|
@@ -540,7 +567,8 @@ class StructureBuilder {
|
|
|
540
567
|
connection.from !== connection.to);
|
|
541
568
|
if (validConnections.length > 0) {
|
|
542
569
|
validConnections.forEach((connection) => {
|
|
543
|
-
|
|
570
|
+
const [layoutSourceId, layoutTargetId] = this.resolveLayoutEdge(connection, direction, nodePositions);
|
|
571
|
+
graph.setEdge(layoutSourceId, layoutTargetId, {});
|
|
544
572
|
});
|
|
545
573
|
}
|
|
546
574
|
else if (nodeIds.length > 1) {
|
|
@@ -578,8 +606,8 @@ class StructureBuilder {
|
|
|
578
606
|
generateConnectionId() {
|
|
579
607
|
return `conn-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
580
608
|
}
|
|
581
|
-
|
|
582
|
-
return
|
|
609
|
+
createConnectorId(nodeId, role, side) {
|
|
610
|
+
return `${nodeId}${CONNECTOR_ID_SEPARATOR}${role}__${side}`;
|
|
583
611
|
}
|
|
584
612
|
resolveDirection(layoutDirection) {
|
|
585
613
|
if (layoutDirection === Direction.LEFT_TO_RIGHT) {
|
|
@@ -616,10 +644,54 @@ class StructureBuilder {
|
|
|
616
644
|
}
|
|
617
645
|
return visited;
|
|
618
646
|
}
|
|
619
|
-
|
|
620
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: StructureBuilder, isStandalone: true, selector: "mt-structure-builder", inputs: { availableNodes: { classPropertyName: "availableNodes", publicName: "availableNodes", isSignal: true, isRequired: false, transformFunction: null }, nodeForm: { classPropertyName: "nodeForm", publicName: "nodeForm", isSignal: true, isRequired: false, transformFunction: null }, nodeDialogFooterConfig: { classPropertyName: "nodeDialogFooterConfig", publicName: "nodeDialogFooterConfig", isSignal: true, isRequired: false, transformFunction: null }, connectionForm: { classPropertyName: "connectionForm", publicName: "connectionForm", isSignal: true, isRequired: false, transformFunction: null }, connectionFormulaSchemaId: { classPropertyName: "connectionFormulaSchemaId", publicName: "connectionFormulaSchemaId", isSignal: true, isRequired: false, transformFunction: null }, connectionFormulaConfig: { classPropertyName: "connectionFormulaConfig", publicName: "connectionFormulaConfig", isSignal: true, isRequired: false, transformFunction: null }, nodeActions: { classPropertyName: "nodeActions", publicName: "nodeActions", isSignal: true, isRequired: false, transformFunction: null }, nodeFields: { classPropertyName: "nodeFields", publicName: "nodeFields", isSignal: true, isRequired: false, transformFunction: null }, isAutoLayout: { classPropertyName: "isAutoLayout", publicName: "isAutoLayout", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, addModalType: { classPropertyName: "addModalType", publicName: "addModalType", isSignal: true, isRequired: false, transformFunction: null }, updateModalType: { classPropertyName: "updateModalType", publicName: "updateModalType", isSignal: true, isRequired: false, transformFunction: null }, addModalStyleClass: { classPropertyName: "addModalStyleClass", publicName: "addModalStyleClass", isSignal: true, isRequired: false, transformFunction: null }, updateModalStyleClass: { classPropertyName: "updateModalStyleClass", publicName: "updateModalStyleClass", isSignal: true, isRequired: false, transformFunction: null }, addModalHeader: { classPropertyName: "addModalHeader", publicName: "addModalHeader", isSignal: true, isRequired: false, transformFunction: null }, updateModalHeader: { classPropertyName: "updateModalHeader", publicName: "updateModalHeader", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, availableTabsClass: { classPropertyName: "availableTabsClass", publicName: "availableTabsClass", isSignal: true, isRequired: false, transformFunction: null }, layoutDirection: { classPropertyName: "layoutDirection", publicName: "layoutDirection", isSignal: true, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, connections: { classPropertyName: "connections", publicName: "connections", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeActionsEvent: "nodeActionsEvent", action: "action", nodes: "nodesChange", connections: "connectionsChange" }, host: { classAttribute: "flex h-full bg-surface-200 dark:bg-surface-700 relative rounded-2xl overflow-hidden" }, providers: [DialogService], queries: [{ propertyName: "nodeDialogTemplate", first: true, predicate: ["nodeDialog"], descendants: true, isSignal: true }, { propertyName: "nodeTemplateContent", first: true, predicate: ["nodeTemplate"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "fCanvas", first: true, predicate: FCanvasComponent, descendants: true, isSignal: true }, { propertyName: "fFlowComponent", first: true, predicate: FFlowComponent, descendants: true, isSignal: true }, { propertyName: "fCanvasComponent", first: true, predicate: FCanvasComponent, descendants: true, isSignal: true }, { propertyName: "fZoomDirective", first: true, predicate: FZoomDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- structure-builder.html -->\r\n@if (!readonly() && availableTabs().length > 0) {\r\n <mt-card\r\n class=\"absolute ms-4 mt-4 z-1 h-[calc(100%---spacing(8))] w-1/5 min-w-xs\"\r\n >\r\n <ng-template #headless>\r\n <!-- Header -->\r\n <div class=\"flex items-center justify-between px-4 pt-5\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"structureBuilder.levelTemplates\" | transloco }}\r\n </h3>\r\n </div>\r\n\r\n <!-- Tabs using PrimeNG -->\r\n <p-tabs\r\n [(value)]=\"activeTab\"\r\n styleClass=\"structure-tabs \"\r\n class=\"h-full overflow-hidden\"\r\n >\r\n <p-tablist>\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tab [value]=\"i.toString()\">{{ tab | titlecase }}</p-tab>\r\n }\r\n </p-tablist>\r\n <p-tabpanels class=\"bg-transparent! p-0! overflow-auto\">\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tabpanel [value]=\"i.toString()\">\r\n <p class=\"text-xs text-muted py-3 px-4\">\r\n {{ \"structureBuilder.dragToAdd\" | transloco }}\r\n </p>\r\n\r\n <!-- Node List -->\r\n <div class=\"space-y-1 px-4\">\r\n @for (node of currentTabNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move transition-colors\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{\r\n node.label\r\n }}</span>\r\n <mt-icon class=\"text-lg\" icon=\"general.menu-05\"></mt-icon>\r\n </div>\r\n }\r\n\r\n @if (currentTabNodes().length === 0) {\r\n <div class=\"text-center py-8 text-gray-400\">\r\n <p class=\"text-sm\">\r\n {{\r\n \"structureBuilder.allItemsInUse\"\r\n | transloco: { tab: tab }\r\n }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </p-tabpanel>\r\n }\r\n </p-tabpanels>\r\n </p-tabs>\r\n </ng-template>\r\n </mt-card>\r\n} @else if (!readonly() && availableNodes().length > 0) {\r\n <div [ngClass]=\"availableTabsClass() || 'absolute top-4 start-4 z-1 w-64'\">\r\n <mt-card [title]=\"'structureBuilder.steps' | transloco\">\r\n <div class=\"flex flex-col gap-2\">\r\n @for (node of availableNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move bg-content\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{ node.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n </div>\r\n}\r\n<!-- Left Sidebar -->\r\n\r\n<!-- Main Canvas Area -->\r\n<div class=\"flex-1 z-0 relative\">\r\n <ng-content select=\"[flowContent]\"></ng-content>\r\n\r\n <f-flow\r\n fDraggable\r\n dir=\"ltr\"\r\n (fLoaded)=\"onLoaded()\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n class=\"size-full\"\r\n >\r\n <f-background>\r\n <f-circle-pattern color=\"#b5b5b5\"></f-circle-pattern>\r\n </f-background>\r\n <f-canvas fZoom [fZoomMinimum]=\"0.1\" [fZoomMaximum]=\"2\">\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"straight\">\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-connection-for-create>\r\n <f-snap-connection\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n class=\"z-1\"\r\n [fSnapThreshold]=\"100\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-snap-connection>\r\n\r\n <f-connection-for-create></f-connection-for-create>\r\n\r\n <!-- Enhanced Connections with Edit Button -->\r\n @for (connection of connectionsComputed(); track connection.id) {\r\n <f-connection\r\n [fReassignDisabled]=\"true\"\r\n [fOutputId]=\"connection.from\"\r\n [fInputId]=\"connection.to\"\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n [ngClass]=\"{ 'connection-loading': connection.loading, 'z-1': true }\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n @if (!readonly()) {\r\n <div\r\n fConnectionCenter\r\n class=\"flex items-center gap-1 bg-content rounded-md p-1 shadow-sm\"\r\n >\r\n @if (!connection.loading) {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.edit-05'\"\r\n (click)=\"openConnectionDialog(connection)\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n severity=\"danger\"\r\n [icon]=\"'general.trash-01'\"\r\n (click)=\"removeConnection(connection)\"\r\n >\r\n </mt-button>\r\n } @else {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.loading-01'\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n <!-- Enhanced Nodes with Edit Button -->\r\n @for (node of nodesWithComputedProps(); track node._computedId) {\r\n <mt-card\r\n fNode\r\n fDragHandle\r\n [fNodePosition]=\"{\r\n x: node.configuration?.x || 200,\r\n y: node.configuration?.y || 100,\r\n }\"\r\n (fNodePositionChange)=\"onNodePositionChange($event, node._computedId)\"\r\n [style.--node-data-border-color]=\"node._computedColor\"\r\n >\r\n <ng-template #headless>\r\n @if (!node.loading) {\r\n <div [attr.dir]=\"contentDirection()\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"\r\n effectiveNodeTemplate() || defaultNodeTemplate\r\n \"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: node,\r\n node: node,\r\n actions: getFilteredNodeActions(node),\r\n onAction: nodeActionHandler,\r\n dir: contentDirection(),\r\n }\"\r\n >\r\n </ng-container>\r\n </div>\r\n <div\r\n fNodeInput\r\n [fInputId]=\"node._computedId\"\r\n [fInputConnectableSide]=\"configuration().inputSide\"\r\n [fInputMultiple]=\"true\"\r\n [ngClass]=\"configuration().inputSide\"\r\n ></div>\r\n\r\n <div\r\n fNodeOutput\r\n [fOutputId]=\"node._computedId\"\r\n [fOutputConnectableSide]=\"configuration().outputSide\"\r\n [isSelfConnectable]=\"false\"\r\n [fOutputMultiple]=\"true\"\r\n [ngClass]=\"configuration().outputSide\"\r\n class=\"bg-surface-50 dark:bg-surface-900\"\r\n ></div>\r\n } @else {\r\n <p-skeleton height=\"10rem\" width=\"15rem\" />\r\n }\r\n\r\n <!-- Node Header with Edit Button -->\r\n </ng-template>\r\n </mt-card>\r\n }\r\n\r\n <ng-template\r\n #defaultNodeTemplate\r\n let-node\r\n let-actions=\"actions\"\r\n let-onAction=\"onAction\"\r\n >\r\n <div\r\n class=\"flex flex-col items-center min-w-3xs gap-2 px-3 py-4 rounded-t-2xl bg-white dark:bg-surface-800 border-(--p-content-border-color)\"\r\n >\r\n @if (node._computedIcon) {\r\n <mt-icon\r\n class=\"text-2xl text-primary\"\r\n [icon]=\"node._computedIcon\"\r\n />\r\n }\r\n <div>{{ node._computedName }}</div>\r\n </div>\r\n <div\r\n class=\"flex justify-center pt-3 mb-4 gap-2 bg-surface-50 dark:bg-surface-900\"\r\n >\r\n @for (action of actions; track action.key) {\r\n <mt-button\r\n [size]=\"action?.size || 'small'\"\r\n [variant]=\"action?.variant\"\r\n [icon]=\"action?.icon\"\r\n [tooltip]=\"action?.tooltip\"\r\n [severity]=\"action?.severity\"\r\n (onClick)=\"onAction(action, node)\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n </ng-template>\r\n </f-canvas>\r\n </f-flow>\r\n</div>\r\n@if (!readonly()) {\r\n <mt-toolbar />\r\n}\r\n", styles: ["::ng-deep :root{--background-element-color: rgba(0, 0, 0, .1);--selection-area-color: rgba(100, 108, 255, .14);--disabled-color: #e2e2e2;--node-background-color: #ffffff;--node-background-color-inverse: #000000;--node-border-radius: 2px;--node-border-color: rgba(60, 60, 67, .36);--node-selected-border-color: #3451b2;--node-color: rgba(60, 60, 67, .78);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: var(--p-text-color);--snap-connection-color: var(--p-text-muted-color);--connection-gradient-1: #b8272c;--connection-gradient-2: #30a46c;--outlet-color: #3451b2;--input-output-color: rgba(60, 60, 67, .78);--minimap-background-color: #ffffff;--minimap-node-color: rgba(60, 60, 67);--minimap-node-selected-color: var(--p-primary-color);--minimap-view-color: rgba(100, 108, 255, .14)}::ng-deep :root.dark{--background-element-color: rgba(255, 255, 255, .1);--selection-area-color: rgba(100, 108, 255, .16);--disabled-color: #2c2c2e;--node-background-color: #000000;--node-background-color-inverse: #ffffff;--node-border-radius: 2px;--node-border-color: rgba(235, 235, 245, .38);--node-selected-border-color: #a8b1ff;--node-color: rgba(235, 235, 245, .6);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: rgba(235, 235, 245, 1);--snap-connection-color: rgba(235, 235, 245, .2);--connection-gradient-1: #f66f81;--connection-gradient-2: #298459;--outlet-color: #a8b1ff;--input-output-color: rgba(235, 235, 245, .6);--minimap-background-color: #1b1b1f;--minimap-node-color: rgba(255, 255, 245, .86);--minimap-node-selected-color: #a8b1ff;--minimap-view-color: rgba(100, 108, 255, .16)}::ng-deep :root{--form-field-text-color: var(--node-color);--form-field-background: var(--minimap-view-color);--form-field-panel-shadow: var(--shadow-4);--form-field-panel-background: var(--node-background-color);--form-field-active-color: var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection{cursor:pointer}::ng-deep f-flow .f-connection .f-connection-drag-handle{fill:transparent}::ng-deep f-flow .f-connection .f-connection-selection{fill:none}::ng-deep f-flow .f-connection .f-connection-path{fill:none;stroke:var(--connection-color);stroke-width:2}::ng-deep f-flow .f-connection .f-connection-marker{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-marker path,::ng-deep f-flow .f-connection .f-marker circle{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-connection-text,::ng-deep f-flow .f-connection .f-connection-center{fill:var(--connection-color);color:var(--connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color)}::ng-deep f-flow .f-connection .f-connection-center{display:none}::ng-deep f-flow .f-connection.connection-loading .f-connection-center{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-center{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-path{stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection.f-selected .f-marker path,::ng-deep f-flow .f-connection.f-selected .f-marker circle{fill:var(--p-primary-color);stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection .f-connection-selection{fill:none;stroke:transparent;stroke-width:20;cursor:pointer}::ng-deep f-flow .f-connection:hover .f-connection-selection{stroke:var(--p-primary-color);opacity:.1}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:2px}::ng-deep f-flow .f-connection.f-snap-connection .f-marker path,::ng-deep f-flow .f-connection.f-snap-connection .f-marker circle{fill:var(--snap-connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection.f-connection-for-create .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection-for-create{pointer-events:none}::ng-deep f-flow .f-connection-for-create .f-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:3px;stroke-dasharray:8,4;animation:connection-dash 1s linear infinite}::ng-deep f-flow .f-connection-for-create .f-connection .f-marker path,::ng-deep f-flow .f-connection-for-create .f-connection .f-marker circle{fill:var(--snap-connection-color)}@keyframes connection-dash{to{stroke-dashoffset:-12}}::ng-deep f-flow{direction:ltr}.f-node-input:not(.f-node),.f-node-output:not(.f-node){position:absolute;border-radius:0 0 1rem 1rem}.f-node-input:not(.f-node):hover,.f-node-output:not(.f-node):hover{border:.5px dashed var(--p-primary-color)}.f-node-input:not(.f-node).top,.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).top,.f-node-output:not(.f-node).bottom{width:100%;height:16px;left:0}.f-node-input:not(.f-node).top,.f-node-output:not(.f-node).top{top:0}.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).bottom{bottom:0}.f-node-input:not(.f-node).left,.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).left,.f-node-output:not(.f-node).right{width:16px;height:100%;top:0}.f-node-input:not(.f-node).left,.f-node-output:not(.f-node).left{left:0;border-radius:1rem 0 0 1rem}.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).right{right:0;border-radius:0 1rem 1rem 0}.f-node-input:not(.f-node).f-node-output-not-connectable,.f-node-input:not(.f-node).f-node-input-not-connectable,.f-node-output:not(.f-node).f-node-output-not-connectable,.f-node-output:not(.f-node).f-node-input-not-connectable{background-color:var(--disabled-color)}.f-node-input:not(.f-node){border-radius:4px}.f-node-input,.f-node-output{z-index:10;pointer-events:all}.examples-toolbar{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:8px;position:absolute;right:16px;top:16px}.examples-toolbar button{font-weight:500;border:none;border-radius:2px;padding:4px 8px;line-height:normal}.f-node:before{content:\"\";position:absolute;width:100%;height:4rem;border-radius:var(--radius-2xl);z-index:-1;top:-.25rem;background-color:var(--node-data-border-color)}.connection-center{display:flex;gap:8px;background:var(--node-background-color);border:1px solid var(--node-border-color);border-radius:4px;padding:4px;box-shadow:var(--node-shadow)}.connection-center .connection-edit-btn,.connection-center .connection-delete-btn{background:none;border:none;width:24px;height:24px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.connection-center .connection-edit-btn:hover,.connection-center .connection-delete-btn:hover{background-color:var(--minimap-view-color)}.connection-center .connection-edit-btn{color:var(--minimap-node-selected-color)}.connection-center .connection-delete-btn{color:#ef4444}.node-edit-btn,.node-delete-btn{background:none;border:none;width:32px;height:32px;border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.node-edit-btn:hover,.node-delete-btn:hover{background-color:var(--minimap-view-color)}.node-edit-btn{color:var(--minimap-node-selected-color)}.node-delete-btn{color:#ef4444}.node-properties{max-height:200px;overflow-y:auto}.node-properties .property-item{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--node-border-color);font-size:12px}.node-properties .property-item .property-key{font-weight:600;color:var(--node-color);margin-right:8px}.node-properties .property-item .property-value{color:var(--minimap-node-selected-color);word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: FFlowModule }, { kind: "component", type: i2$1.FFlowComponent, selector: "f-flow", inputs: ["fFlowId"], outputs: ["fLoaded"] }, { kind: "component", type: i2$1.FCanvasComponent, selector: "f-canvas", inputs: ["position", "scale", "debounceTime"], outputs: ["fCanvasChange"] }, { kind: "component", type: i2$1.FBackgroundComponent, selector: "f-background" }, { kind: "component", type: i2$1.FCirclePatternComponent, selector: "f-circle-pattern", inputs: ["id", "color", "radius"] }, { kind: "directive", type: i2$1.FZoomDirective, selector: "f-canvas[fZoom]", inputs: ["fZoom", "fWheelTrigger", "fDblClickTrigger", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "fZoomDblClickStep"], exportAs: ["fComponent"] }, { kind: "directive", type: i2$1.FExternalItemDirective, selector: "[fExternalItem]", inputs: ["fExternalItemId", "fData", "fDisabled", "fPreview", "fPreviewMatchSize", "fPlaceholder"] }, { kind: "component", type: i2$1.FConnectionComponent, selector: "f-connection", inputs: ["fConnectionId", "fText", "fTextStartOffset", "fOutputId", "fInputId", "fRadius", "fOffset", "fBehavior", "fType", "fSelectionDisabled", "fReassignableStart", "fReassignDisabled", "fInputSide", "fOutputSide"], exportAs: ["fComponent"] }, { kind: "directive", type: i2$1.FConnectionCenterDirective, selector: "[fConnectionCenter]", inputs: ["fConnectionCenter"] }, { kind: "component", type: i2$1.FConnectionForCreateComponent, selector: "f-connection-for-create", inputs: ["fRadius", "fOffset", "fBehavior", "fType", "fInputSide", "fOutputSide"] }, { kind: "directive", type: i2$1.FMarkerDirective, selector: "svg[fMarker]", inputs: ["width", "height", "refX", "refY", "type", "orient", "markerUnits"] }, { kind: "component", type: i2$1.FSnapConnectionComponent, selector: "f-snap-connection", inputs: ["fSnapThreshold", "fRadius", "fOffset", "fBehavior", "fType", "fInputSide", "fOutputSide"] }, { kind: "directive", type: i2$1.FNodeInputDirective, selector: "[fNodeInput]", inputs: ["fInputId", "fInputCategory", "fInputMultiple", "fInputDisabled", "fInputConnectableSide"], exportAs: ["fNodeInput"] }, { kind: "directive", type: i2$1.FNodeOutputDirective, selector: "[fNodeOutput]", inputs: ["fOutputId", "fOutputMultiple", "fOutputDisabled", "fOutputConnectableSide", "isSelfConnectable", "fCanBeConnectedInputs"], exportAs: ["fNodeOutput"] }, { kind: "directive", type: i2$1.FNodeDirective, selector: "[fNode]", inputs: ["fNodeId", "fNodeParentId", "fNodePosition", "fNodeSize", "fNodeRotate", "fConnectOnNode", "fMinimapClass", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fIncludePadding", "fAutoExpandOnChildHit", "fAutoSizeToFitChildren"], outputs: ["fNodePositionChange", "fNodeSizeChange", "fNodeRotateChange"], exportAs: ["fComponent"] }, { kind: "directive", type: i2$1.FDragHandleDirective, selector: "[fDragHandle]" }, { kind: "directive", type: i2$1.FDraggableDirective, selector: "f-flow[fDraggable]", inputs: ["fDraggableDisabled", "fMultiSelectTrigger", "fReassignConnectionTrigger", "fCreateConnectionTrigger", "fNodeResizeTrigger", "fNodeRotateTrigger", "fNodeMoveTrigger", "fCanvasMoveTrigger", "fExternalItemTrigger", "fEmitOnNodeIntersect", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], outputs: ["fSelectionChange", "fNodeIntersectedWithConnections", "fCreateNode", "fMoveNodes", "fReassignConnection", "fCreateConnection", "fDropToGroup", "fDragStarted", "fDragEnded"], exportAs: ["fDraggable"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i3$1.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i3$1.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i3$1.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i3$1.TabList, selector: "p-tablist" }, { kind: "component", type: i3$1.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Toolbar, selector: "mt-toolbar", inputs: ["size"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i3.TranslocoPipe, name: "transloco" }] });
|
|
647
|
+
extractNodeId(connectionEndId) {
|
|
648
|
+
return (connectionEndId || '')
|
|
649
|
+
.replace(STRUCTURE_BUILDER_CONNECTOR_SUFFIX, '')
|
|
650
|
+
.replace(/-(in|out)$/, '');
|
|
651
|
+
}
|
|
652
|
+
resolveConnectionConnectorSides(connection) {
|
|
653
|
+
const sourcePosition = this.nodePositionsById()[connection.from];
|
|
654
|
+
const targetPosition = this.nodePositionsById()[connection.to];
|
|
655
|
+
const direction = this.effectiveDirection();
|
|
656
|
+
if (!sourcePosition || !targetPosition) {
|
|
657
|
+
return {
|
|
658
|
+
inputSide: this.configuration().inputSide,
|
|
659
|
+
outputSide: this.configuration().outputSide,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
if (direction === Direction.TOP_TO_BOTTOM) {
|
|
663
|
+
return sourcePosition.y <= targetPosition.y
|
|
664
|
+
? { inputSide: 'top', outputSide: 'bottom' }
|
|
665
|
+
: { inputSide: 'bottom', outputSide: 'top' };
|
|
666
|
+
}
|
|
667
|
+
return sourcePosition.x >= targetPosition.x
|
|
668
|
+
? { inputSide: 'right', outputSide: 'left' }
|
|
669
|
+
: { inputSide: 'left', outputSide: 'right' };
|
|
670
|
+
}
|
|
671
|
+
resolveLayoutEdge(connection, direction, nodePositions) {
|
|
672
|
+
const sourcePosition = nodePositions[connection.from];
|
|
673
|
+
const targetPosition = nodePositions[connection.to];
|
|
674
|
+
if (!sourcePosition || !targetPosition) {
|
|
675
|
+
return [connection.from, connection.to];
|
|
676
|
+
}
|
|
677
|
+
if (direction === Direction.TOP_TO_BOTTOM) {
|
|
678
|
+
return sourcePosition.y <= targetPosition.y
|
|
679
|
+
? [connection.from, connection.to]
|
|
680
|
+
: [connection.to, connection.from];
|
|
681
|
+
}
|
|
682
|
+
if (direction === Direction.RIGHT_TO_LEFT) {
|
|
683
|
+
return sourcePosition.x >= targetPosition.x
|
|
684
|
+
? [connection.from, connection.to]
|
|
685
|
+
: [connection.to, connection.from];
|
|
686
|
+
}
|
|
687
|
+
return sourcePosition.x <= targetPosition.x
|
|
688
|
+
? [connection.from, connection.to]
|
|
689
|
+
: [connection.to, connection.from];
|
|
690
|
+
}
|
|
691
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StructureBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
692
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: StructureBuilder, isStandalone: true, selector: "mt-structure-builder", inputs: { availableNodes: { classPropertyName: "availableNodes", publicName: "availableNodes", isSignal: true, isRequired: false, transformFunction: null }, nodeForm: { classPropertyName: "nodeForm", publicName: "nodeForm", isSignal: true, isRequired: false, transformFunction: null }, nodeDialogFooterConfig: { classPropertyName: "nodeDialogFooterConfig", publicName: "nodeDialogFooterConfig", isSignal: true, isRequired: false, transformFunction: null }, connectionForm: { classPropertyName: "connectionForm", publicName: "connectionForm", isSignal: true, isRequired: false, transformFunction: null }, connectionFormulaSchemaId: { classPropertyName: "connectionFormulaSchemaId", publicName: "connectionFormulaSchemaId", isSignal: true, isRequired: false, transformFunction: null }, connectionFormulaConfig: { classPropertyName: "connectionFormulaConfig", publicName: "connectionFormulaConfig", isSignal: true, isRequired: false, transformFunction: null }, nodeActions: { classPropertyName: "nodeActions", publicName: "nodeActions", isSignal: true, isRequired: false, transformFunction: null }, nodeFields: { classPropertyName: "nodeFields", publicName: "nodeFields", isSignal: true, isRequired: false, transformFunction: null }, isAutoLayout: { classPropertyName: "isAutoLayout", publicName: "isAutoLayout", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, addModalType: { classPropertyName: "addModalType", publicName: "addModalType", isSignal: true, isRequired: false, transformFunction: null }, updateModalType: { classPropertyName: "updateModalType", publicName: "updateModalType", isSignal: true, isRequired: false, transformFunction: null }, addModalStyleClass: { classPropertyName: "addModalStyleClass", publicName: "addModalStyleClass", isSignal: true, isRequired: false, transformFunction: null }, updateModalStyleClass: { classPropertyName: "updateModalStyleClass", publicName: "updateModalStyleClass", isSignal: true, isRequired: false, transformFunction: null }, addModalHeader: { classPropertyName: "addModalHeader", publicName: "addModalHeader", isSignal: true, isRequired: false, transformFunction: null }, updateModalHeader: { classPropertyName: "updateModalHeader", publicName: "updateModalHeader", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, availableTabsClass: { classPropertyName: "availableTabsClass", publicName: "availableTabsClass", isSignal: true, isRequired: false, transformFunction: null }, layoutDirection: { classPropertyName: "layoutDirection", publicName: "layoutDirection", isSignal: true, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, connections: { classPropertyName: "connections", publicName: "connections", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeActionsEvent: "nodeActionsEvent", action: "action", nodes: "nodesChange", connections: "connectionsChange" }, host: { classAttribute: "flex h-full bg-surface-200 dark:bg-surface-700 relative rounded-2xl overflow-hidden" }, providers: [DialogService], queries: [{ propertyName: "nodeDialogTemplate", first: true, predicate: ["nodeDialog"], descendants: true, isSignal: true }, { propertyName: "nodeTemplateContent", first: true, predicate: ["nodeTemplate"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "fCanvas", first: true, predicate: FCanvasComponent, descendants: true, isSignal: true }, { propertyName: "fFlowComponent", first: true, predicate: FFlowComponent, descendants: true, isSignal: true }, { propertyName: "fCanvasComponent", first: true, predicate: FCanvasComponent, descendants: true, isSignal: true }, { propertyName: "fZoomDirective", first: true, predicate: FZoomDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- structure-builder.html -->\r\n@if (!readonly() && availableTabs().length > 0) {\r\n <mt-card\r\n class=\"absolute ms-4 mt-4 z-1 h-[calc(100%---spacing(8))] w-1/5 min-w-xs\"\r\n >\r\n <ng-template #headless>\r\n <!-- Header -->\r\n <div class=\"flex items-center justify-between px-4 pt-5\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"structureBuilder.levelTemplates\" | transloco }}\r\n </h3>\r\n </div>\r\n\r\n <!-- Tabs using PrimeNG -->\r\n <p-tabs\r\n [(value)]=\"activeTab\"\r\n styleClass=\"structure-tabs \"\r\n class=\"h-full overflow-hidden\"\r\n >\r\n <p-tablist>\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tab [value]=\"i.toString()\">{{ tab | titlecase }}</p-tab>\r\n }\r\n </p-tablist>\r\n <p-tabpanels class=\"bg-transparent! p-0! overflow-auto\">\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tabpanel [value]=\"i.toString()\">\r\n <p class=\"text-xs text-muted py-3 px-4\">\r\n {{ \"structureBuilder.dragToAdd\" | transloco }}\r\n </p>\r\n\r\n <!-- Node List -->\r\n <div class=\"space-y-1 px-4\">\r\n @for (node of currentTabNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n style=\"display: flex\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move transition-colors\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{\r\n node.label\r\n }}</span>\r\n <mt-icon class=\"text-lg\" icon=\"general.menu-05\"></mt-icon>\r\n </div>\r\n }\r\n\r\n @if (currentTabNodes().length === 0) {\r\n <div class=\"text-center py-8 text-gray-400\">\r\n <p class=\"text-sm\">\r\n {{\r\n \"structureBuilder.allItemsInUse\"\r\n | transloco: { tab: tab }\r\n }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </p-tabpanel>\r\n }\r\n </p-tabpanels>\r\n </p-tabs>\r\n </ng-template>\r\n </mt-card>\r\n} @else if (!readonly() && availableNodes().length > 0) {\r\n <div [ngClass]=\"availableTabsClass() || 'absolute top-4 start-4 z-1 w-64'\">\r\n <mt-card [title]=\"'structureBuilder.steps' | transloco\">\r\n <div class=\"flex flex-col gap-2\">\r\n @for (node of availableNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n style=\"display: flex\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move bg-content\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{ node.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n </div>\r\n}\r\n<!-- Left Sidebar -->\r\n\r\n<!-- Main Canvas Area -->\r\n<div class=\"flex-1 z-0 relative\">\r\n <ng-content select=\"[flowContent]\"></ng-content>\r\n\r\n <f-flow\r\n fDraggable\r\n dir=\"ltr\"\r\n (fLoaded)=\"onLoaded()\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n class=\"size-full\"\r\n >\r\n <f-background>\r\n <f-circle-pattern color=\"#b5b5b5\"></f-circle-pattern>\r\n </f-background>\r\n <f-canvas fZoom [fZoomMinimum]=\"0.1\" [fZoomMaximum]=\"2\">\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"straight\">\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-connection-for-create>\r\n <f-snap-connection\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n class=\"z-1\"\r\n [fSnapThreshold]=\"100\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-snap-connection>\r\n\r\n <f-connection-for-create></f-connection-for-create>\r\n\r\n <!-- Enhanced Connections with Edit Button -->\r\n @for (connection of renderedConnections(); track connection.id) {\r\n <f-connection\r\n [fReassignDisabled]=\"true\"\r\n [fOutputId]=\"connection._outputConnectorId\"\r\n [fInputId]=\"connection._inputConnectorId\"\r\n [fOutputSide]=\"connection._outputSide\"\r\n [fInputSide]=\"connection._inputSide\"\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n [ngClass]=\"{ 'connection-loading': connection.loading, 'z-1': true }\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n @if (!readonly()) {\r\n <div\r\n fConnectionContent\r\n class=\"flex items-center gap-1 bg-content rounded-md p-1 shadow-sm\"\r\n >\r\n @if (!connection.loading) {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.edit-05'\"\r\n (click)=\"openConnectionDialog(connection)\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n severity=\"danger\"\r\n [icon]=\"'general.trash-01'\"\r\n (click)=\"removeConnection(connection)\"\r\n >\r\n </mt-button>\r\n } @else {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.loading-01'\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n <!-- Enhanced Nodes with Edit Button -->\r\n @for (node of nodesWithComputedProps(); track node._computedId) {\r\n <mt-card\r\n fNode\r\n fDragHandle\r\n [fNodePosition]=\"{\r\n x: node.configuration?.x || 200,\r\n y: node.configuration?.y || 100,\r\n }\"\r\n (fNodePositionChange)=\"onNodePositionChange($event, node._computedId)\"\r\n [style.--node-data-border-color]=\"node._computedColor\"\r\n >\r\n <ng-template #headless>\r\n @if (!node.loading) {\r\n <div [attr.dir]=\"contentDirection()\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"\r\n effectiveNodeTemplate() || defaultNodeTemplate\r\n \"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: node,\r\n node: node,\r\n actions: getFilteredNodeActions(node),\r\n onAction: nodeActionHandler,\r\n dir: contentDirection(),\r\n }\"\r\n >\r\n </ng-container>\r\n </div>\r\n @for (side of nodeConnectorSides(); track side) {\r\n <div\r\n fNodeInput\r\n [fInputId]=\"\r\n createConnectorId(node._computedId, 'input', side)\r\n \"\r\n [fInputConnectableSide]=\"side\"\r\n [fInputMultiple]=\"true\"\r\n class=\"sb-connector sb-connector-input\"\r\n [class.top]=\"side === 'top'\"\r\n [class.bottom]=\"side === 'bottom'\"\r\n [class.left]=\"side === 'left'\"\r\n [class.right]=\"side === 'right'\"\r\n ></div>\r\n\r\n <div\r\n fNodeOutput\r\n [fOutputId]=\"\r\n createConnectorId(node._computedId, 'output', side)\r\n \"\r\n [fOutputConnectableSide]=\"side\"\r\n [isSelfConnectable]=\"false\"\r\n [fOutputMultiple]=\"true\"\r\n class=\"sb-connector sb-connector-output bg-surface-50 dark:bg-surface-900\"\r\n [class.top]=\"side === 'top'\"\r\n [class.bottom]=\"side === 'bottom'\"\r\n [class.left]=\"side === 'left'\"\r\n [class.right]=\"side === 'right'\"\r\n ></div>\r\n }\r\n } @else {\r\n <p-skeleton height=\"10rem\" width=\"15rem\" />\r\n }\r\n\r\n <!-- Node Header with Edit Button -->\r\n </ng-template>\r\n </mt-card>\r\n }\r\n\r\n <ng-template\r\n #defaultNodeTemplate\r\n let-node\r\n let-actions=\"actions\"\r\n let-onAction=\"onAction\"\r\n >\r\n <div\r\n class=\"flex flex-col items-center min-w-3xs gap-2 px-3 py-4 rounded-t-2xl bg-white dark:bg-surface-800 border-(--p-content-border-color)\"\r\n >\r\n @if (node._computedIcon) {\r\n <mt-icon\r\n class=\"text-2xl text-primary\"\r\n [icon]=\"node._computedIcon\"\r\n />\r\n }\r\n <div>{{ node._computedName }}</div>\r\n </div>\r\n <div\r\n class=\"flex justify-center pt-3 mb-4 gap-2 bg-surface-50 dark:bg-surface-900\"\r\n >\r\n @for (action of actions; track action.key) {\r\n <mt-button\r\n [size]=\"action?.size || 'small'\"\r\n [variant]=\"action?.variant\"\r\n [icon]=\"action?.icon\"\r\n [tooltip]=\"action?.tooltip\"\r\n [severity]=\"action?.severity\"\r\n (onClick)=\"onAction(action, node)\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n </ng-template>\r\n </f-canvas>\r\n </f-flow>\r\n</div>\r\n@if (!readonly()) {\r\n <mt-toolbar />\r\n}\r\n", styles: ["::ng-deep :root{--background-element-color: rgba(0, 0, 0, .1);--selection-area-color: rgba(100, 108, 255, .14);--disabled-color: #e2e2e2;--node-background-color: #ffffff;--node-background-color-inverse: #000000;--node-border-radius: 2px;--node-border-color: rgba(60, 60, 67, .36);--node-selected-border-color: #3451b2;--node-color: rgba(60, 60, 67, .78);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: var(--p-text-color);--snap-connection-color: var(--p-text-muted-color);--connection-gradient-1: #b8272c;--connection-gradient-2: #30a46c;--outlet-color: #3451b2;--input-output-color: rgba(60, 60, 67, .78);--minimap-background-color: #ffffff;--minimap-node-color: rgba(60, 60, 67);--minimap-node-selected-color: var(--p-primary-color);--minimap-view-color: rgba(100, 108, 255, .14)}::ng-deep :root.dark{--background-element-color: rgba(255, 255, 255, .1);--selection-area-color: rgba(100, 108, 255, .16);--disabled-color: #2c2c2e;--node-background-color: #000000;--node-background-color-inverse: #ffffff;--node-border-radius: 2px;--node-border-color: rgba(235, 235, 245, .38);--node-selected-border-color: #a8b1ff;--node-color: rgba(235, 235, 245, .6);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: rgba(235, 235, 245, 1);--snap-connection-color: rgba(235, 235, 245, .2);--connection-gradient-1: #f66f81;--connection-gradient-2: #298459;--outlet-color: #a8b1ff;--input-output-color: rgba(235, 235, 245, .6);--minimap-background-color: #1b1b1f;--minimap-node-color: rgba(255, 255, 245, .86);--minimap-node-selected-color: #a8b1ff;--minimap-view-color: rgba(100, 108, 255, .16)}::ng-deep :root{--form-field-text-color: var(--node-color);--form-field-background: var(--minimap-view-color);--form-field-panel-shadow: var(--shadow-4);--form-field-panel-background: var(--node-background-color);--form-field-active-color: var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection{cursor:pointer}::ng-deep f-flow .f-connection .f-connection-drag-handle{fill:transparent}::ng-deep f-flow .f-connection .f-connection-selection{fill:none}::ng-deep f-flow .f-connection .f-connection-path{fill:none;stroke:var(--connection-color);stroke-width:2}::ng-deep f-flow .f-connection .f-connection-marker{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-marker path,::ng-deep f-flow .f-connection .f-marker circle{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-connection-text,::ng-deep f-flow .f-connection .f-connection-center,::ng-deep f-flow .f-connection .f-connection-content{fill:var(--connection-color);color:var(--connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color)}::ng-deep f-flow .f-connection .f-connection-center,::ng-deep f-flow .f-connection .f-connection-content{display:none}::ng-deep f-flow .f-connection.connection-loading .f-connection-center,::ng-deep f-flow .f-connection.connection-loading .f-connection-content{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-center,::ng-deep f-flow .f-connection.f-selected .f-connection-content{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-path{stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection.f-selected .f-marker path,::ng-deep f-flow .f-connection.f-selected .f-marker circle{fill:var(--p-primary-color);stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection .f-connection-selection{fill:none;stroke:transparent;stroke-width:20;cursor:pointer}::ng-deep f-flow .f-connection:hover .f-connection-selection{stroke:var(--p-primary-color);opacity:.1}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:2px}::ng-deep f-flow .f-connection.f-snap-connection .f-marker path,::ng-deep f-flow .f-connection.f-snap-connection .f-marker circle{fill:var(--snap-connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection.f-connection-for-create .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection-for-create{pointer-events:none}::ng-deep f-flow .f-connection-for-create .f-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:3px;stroke-dasharray:8,4;animation:connection-dash 1s linear infinite}::ng-deep f-flow .f-connection-for-create .f-connection .f-marker path,::ng-deep f-flow .f-connection-for-create .f-connection .f-marker circle{fill:var(--snap-connection-color)}@keyframes connection-dash{to{stroke-dashoffset:-12}}::ng-deep f-flow{direction:ltr}.f-node-input:not(.f-node),.f-node-output:not(.f-node){position:absolute}.f-node-input:not(.f-node):hover,.f-node-output:not(.f-node):hover{border:.5px dashed var(--p-primary-color)}.f-node-input:not(.f-node).top,.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).top,.f-node-output:not(.f-node).bottom{width:100%;height:16px;left:0}.f-node-input:not(.f-node).top,.f-node-output:not(.f-node).top{top:0;border-radius:1rem 1rem 0 0}.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).bottom{bottom:0;border-radius:0 0 1rem 1rem}.f-node-input:not(.f-node).left,.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).left,.f-node-output:not(.f-node).right{width:16px;height:100%;top:0}.f-node-input:not(.f-node).left,.f-node-output:not(.f-node).left{left:0;border-radius:1rem 0 0 1rem}.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).right{right:0;border-radius:0 1rem 1rem 0}.f-node-input:not(.f-node).f-node-output-not-connectable,.f-node-input:not(.f-node).f-node-input-not-connectable,.f-node-output:not(.f-node).f-node-output-not-connectable,.f-node-output:not(.f-node).f-node-input-not-connectable{background-color:var(--disabled-color)}.sb-connector-input,.sb-connector-output{background-color:transparent!important}.f-node-input:not(.f-node){border-radius:4px}.f-node-input,.f-node-output{z-index:10;pointer-events:all}.examples-toolbar{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:8px;position:absolute;right:16px;top:16px}.examples-toolbar button{font-weight:500;border:none;border-radius:2px;padding:4px 8px;line-height:normal}.f-node:before{content:\"\";position:absolute;width:100%;height:4rem;border-radius:var(--radius-2xl);z-index:-1;top:-.25rem;background-color:var(--node-data-border-color)}.connection-center{display:flex;gap:8px;background:var(--node-background-color);border:1px solid var(--node-border-color);border-radius:4px;padding:4px;box-shadow:var(--node-shadow)}.connection-center .connection-edit-btn,.connection-center .connection-delete-btn{background:none;border:none;width:24px;height:24px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.connection-center .connection-edit-btn:hover,.connection-center .connection-delete-btn:hover{background-color:var(--minimap-view-color)}.connection-center .connection-edit-btn{color:var(--minimap-node-selected-color)}.connection-center .connection-delete-btn{color:#ef4444}.node-edit-btn,.node-delete-btn{background:none;border:none;width:32px;height:32px;border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.node-edit-btn:hover,.node-delete-btn:hover{background-color:var(--minimap-view-color)}.node-edit-btn{color:var(--minimap-node-selected-color)}.node-delete-btn{color:#ef4444}.node-properties{max-height:200px;overflow-y:auto}.node-properties .property-item{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--node-border-color);font-size:12px}.node-properties .property-item .property-key{font-weight:600;color:var(--node-color);margin-right:8px}.node-properties .property-item .property-value{color:var(--minimap-node-selected-color);word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: FFlowModule }, { kind: "component", type: i2$1.FFlowComponent, selector: "f-flow", inputs: ["fFlowId", "fCache"], outputs: ["fLoaded"] }, { kind: "component", type: i2$1.FCanvasComponent, selector: "f-canvas", inputs: ["position", "scale", "debounceTime"], outputs: ["fCanvasChange"] }, { kind: "component", type: i2$1.FBackgroundComponent, selector: "f-background" }, { kind: "component", type: i2$1.FCirclePatternComponent, selector: "f-circle-pattern", inputs: ["id", "color", "radius"] }, { kind: "directive", type: i2$1.FZoomDirective, selector: "f-canvas[fZoom]", inputs: ["fZoom", "fWheelTrigger", "fDblClickTrigger", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "fZoomDblClickStep"] }, { kind: "directive", type: i2$1.FExternalItem, selector: "[fExternalItem]", inputs: ["fExternalItemId", "fData", "fDisabled", "fPreview", "fPreviewMatchSize", "fPlaceholder"], outputs: ["fPreviewChange", "fPlaceholderChange"] }, { kind: "directive", type: i2$1.FConnectionContent, selector: "[fConnectionContent]", inputs: ["position", "offset", "align"] }, { kind: "directive", type: i2$1.FConnectionMarker, selector: "svg[fMarker]", inputs: ["width", "height", "refX", "refY", "type", "orient", "markerUnits"] }, { kind: "component", type: i2$1.FConnectionComponent, selector: "f-connection", inputs: ["fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fBehavior", "fType", "fSelectionDisabled", "fReassignableStart", "fReassignDisabled", "fInputSide", "fOutputSide"], exportAs: ["fComponent"] }, { kind: "component", type: i2$1.FConnectionForCreateComponent, selector: "f-connection-for-create", inputs: ["fRadius", "fOffset", "fBehavior", "fType", "fInputSide", "fOutputSide"] }, { kind: "component", type: i2$1.FSnapConnectionComponent, selector: "f-snap-connection", inputs: ["fSnapThreshold", "fRadius", "fOffset", "fBehavior", "fType", "fInputSide", "fOutputSide"] }, { kind: "directive", type: i2$1.FNodeInputDirective, selector: "[fNodeInput]", inputs: ["fInputId", "fInputCategory", "fInputMultiple", "fInputDisabled", "fInputConnectableSide"], exportAs: ["fNodeInput"] }, { kind: "directive", type: i2$1.FNodeOutputDirective, selector: "[fNodeOutput]", inputs: ["fOutputId", "fOutputMultiple", "fOutputDisabled", "fOutputConnectableSide", "isSelfConnectable", "fCanBeConnectedInputs"], exportAs: ["fNodeOutput"] }, { kind: "directive", type: i2$1.FNodeDirective, selector: "[fNode]", inputs: ["fNodeId", "fNodeParentId", "fNodePosition", "fNodeSize", "fNodeRotate", "fConnectOnNode", "fMinimapClass", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fIncludePadding", "fAutoExpandOnChildHit", "fAutoSizeToFitChildren"], outputs: ["fNodePositionChange", "fNodeSizeChange", "fNodeRotateChange"], exportAs: ["fComponent"] }, { kind: "directive", type: i2$1.FDragHandleDirective, selector: "[fDragHandle]" }, { kind: "directive", type: i2$1.FDraggableDirective, selector: "f-flow[fDraggable]", inputs: ["fDraggableDisabled", "fMultiSelectTrigger", "fReassignConnectionTrigger", "fCreateConnectionTrigger", "fConnectionWaypointsTrigger", "fMoveControlPointTrigger", "fNodeResizeTrigger", "fNodeRotateTrigger", "fNodeMoveTrigger", "fCanvasMoveTrigger", "fExternalItemTrigger", "fEmitOnNodeIntersect", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], outputs: ["fSelectionChange", "fNodeIntersectedWithConnections", "fNodeConnectionsIntersection", "fCreateNode", "fMoveNodes", "fReassignConnection", "fCreateConnection", "fConnectionWaypointsChanged", "fDropToGroup", "fDragStarted", "fDragEnded"], exportAs: ["fDraggable"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i3$1.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i3$1.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i3$1.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i3$1.TabList, selector: "p-tablist" }, { kind: "component", type: i3$1.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Toolbar, selector: "mt-toolbar", inputs: ["size"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i3.TranslocoPipe, name: "transloco" }] });
|
|
621
693
|
}
|
|
622
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
694
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StructureBuilder, decorators: [{
|
|
623
695
|
type: Component,
|
|
624
696
|
args: [{ selector: 'mt-structure-builder', standalone: true, imports: [
|
|
625
697
|
CommonModule,
|
|
@@ -634,7 +706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
634
706
|
TranslocoModule,
|
|
635
707
|
], providers: [DialogService], host: {
|
|
636
708
|
class: 'flex h-full bg-surface-200 dark:bg-surface-700 relative rounded-2xl overflow-hidden',
|
|
637
|
-
}, template: "<!-- structure-builder.html -->\r\n@if (!readonly() && availableTabs().length > 0) {\r\n <mt-card\r\n class=\"absolute ms-4 mt-4 z-1 h-[calc(100%---spacing(8))] w-1/5 min-w-xs\"\r\n >\r\n <ng-template #headless>\r\n <!-- Header -->\r\n <div class=\"flex items-center justify-between px-4 pt-5\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"structureBuilder.levelTemplates\" | transloco }}\r\n </h3>\r\n </div>\r\n\r\n <!-- Tabs using PrimeNG -->\r\n <p-tabs\r\n [(value)]=\"activeTab\"\r\n styleClass=\"structure-tabs \"\r\n class=\"h-full overflow-hidden\"\r\n >\r\n <p-tablist>\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tab [value]=\"i.toString()\">{{ tab | titlecase }}</p-tab>\r\n }\r\n </p-tablist>\r\n <p-tabpanels class=\"bg-transparent! p-0! overflow-auto\">\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tabpanel [value]=\"i.toString()\">\r\n <p class=\"text-xs text-muted py-3 px-4\">\r\n {{ \"structureBuilder.dragToAdd\" | transloco }}\r\n </p>\r\n\r\n <!-- Node List -->\r\n <div class=\"space-y-1 px-4\">\r\n @for (node of currentTabNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move transition-colors\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{\r\n node.label\r\n }}</span>\r\n <mt-icon class=\"text-lg\" icon=\"general.menu-05\"></mt-icon>\r\n </div>\r\n }\r\n\r\n @if (currentTabNodes().length === 0) {\r\n <div class=\"text-center py-8 text-gray-400\">\r\n <p class=\"text-sm\">\r\n {{\r\n \"structureBuilder.allItemsInUse\"\r\n | transloco: { tab: tab }\r\n }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </p-tabpanel>\r\n }\r\n </p-tabpanels>\r\n </p-tabs>\r\n </ng-template>\r\n </mt-card>\r\n} @else if (!readonly() && availableNodes().length > 0) {\r\n <div [ngClass]=\"availableTabsClass() || 'absolute top-4 start-4 z-1 w-64'\">\r\n <mt-card [title]=\"'structureBuilder.steps' | transloco\">\r\n <div class=\"flex flex-col gap-2\">\r\n @for (node of availableNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move bg-content\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{ node.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n </div>\r\n}\r\n<!-- Left Sidebar -->\r\n\r\n<!-- Main Canvas Area -->\r\n<div class=\"flex-1 z-0 relative\">\r\n <ng-content select=\"[flowContent]\"></ng-content>\r\n\r\n <f-flow\r\n fDraggable\r\n dir=\"ltr\"\r\n (fLoaded)=\"onLoaded()\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n class=\"size-full\"\r\n >\r\n <f-background>\r\n <f-circle-pattern color=\"#b5b5b5\"></f-circle-pattern>\r\n </f-background>\r\n <f-canvas fZoom [fZoomMinimum]=\"0.1\" [fZoomMaximum]=\"2\">\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"straight\">\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-connection-for-create>\r\n <f-snap-connection\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n class=\"z-1\"\r\n [fSnapThreshold]=\"100\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-snap-connection>\r\n\r\n <f-connection-for-create></f-connection-for-create>\r\n\r\n <!-- Enhanced Connections with Edit Button -->\r\n @for (connection of connectionsComputed(); track connection.id) {\r\n <f-connection\r\n [fReassignDisabled]=\"true\"\r\n [fOutputId]=\"connection.from\"\r\n [fInputId]=\"connection.to\"\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n [ngClass]=\"{ 'connection-loading': connection.loading, 'z-1': true }\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n @if (!readonly()) {\r\n <div\r\n fConnectionCenter\r\n class=\"flex items-center gap-1 bg-content rounded-md p-1 shadow-sm\"\r\n >\r\n @if (!connection.loading) {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.edit-05'\"\r\n (click)=\"openConnectionDialog(connection)\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n severity=\"danger\"\r\n [icon]=\"'general.trash-01'\"\r\n (click)=\"removeConnection(connection)\"\r\n >\r\n </mt-button>\r\n } @else {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.loading-01'\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n <!-- Enhanced Nodes with Edit Button -->\r\n @for (node of nodesWithComputedProps(); track node._computedId) {\r\n <mt-card\r\n fNode\r\n fDragHandle\r\n [fNodePosition]=\"{\r\n x: node.configuration?.x || 200,\r\n y: node.configuration?.y || 100,\r\n }\"\r\n (fNodePositionChange)=\"onNodePositionChange($event, node._computedId)\"\r\n [style.--node-data-border-color]=\"node._computedColor\"\r\n >\r\n <ng-template #headless>\r\n @if (!node.loading) {\r\n <div [attr.dir]=\"contentDirection()\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"\r\n effectiveNodeTemplate() || defaultNodeTemplate\r\n \"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: node,\r\n node: node,\r\n actions: getFilteredNodeActions(node),\r\n onAction: nodeActionHandler,\r\n dir: contentDirection(),\r\n }\"\r\n >\r\n </ng-container>\r\n </div>\r\n <div\r\n fNodeInput\r\n [fInputId]=\"node._computedId\"\r\n [fInputConnectableSide]=\"configuration().inputSide\"\r\n [fInputMultiple]=\"true\"\r\n [ngClass]=\"configuration().inputSide\"\r\n ></div>\r\n\r\n <div\r\n fNodeOutput\r\n [fOutputId]=\"node._computedId\"\r\n [fOutputConnectableSide]=\"configuration().outputSide\"\r\n [isSelfConnectable]=\"false\"\r\n [fOutputMultiple]=\"true\"\r\n [ngClass]=\"configuration().outputSide\"\r\n class=\"bg-surface-50 dark:bg-surface-900\"\r\n ></div>\r\n } @else {\r\n <p-skeleton height=\"10rem\" width=\"15rem\" />\r\n }\r\n\r\n <!-- Node Header with Edit Button -->\r\n </ng-template>\r\n </mt-card>\r\n }\r\n\r\n <ng-template\r\n #defaultNodeTemplate\r\n let-node\r\n let-actions=\"actions\"\r\n let-onAction=\"onAction\"\r\n >\r\n <div\r\n class=\"flex flex-col items-center min-w-3xs gap-2 px-3 py-4 rounded-t-2xl bg-white dark:bg-surface-800 border-(--p-content-border-color)\"\r\n >\r\n @if (node._computedIcon) {\r\n <mt-icon\r\n class=\"text-2xl text-primary\"\r\n [icon]=\"node._computedIcon\"\r\n />\r\n }\r\n <div>{{ node._computedName }}</div>\r\n </div>\r\n <div\r\n class=\"flex justify-center pt-3 mb-4 gap-2 bg-surface-50 dark:bg-surface-900\"\r\n >\r\n @for (action of actions; track action.key) {\r\n <mt-button\r\n [size]=\"action?.size || 'small'\"\r\n [variant]=\"action?.variant\"\r\n [icon]=\"action?.icon\"\r\n [tooltip]=\"action?.tooltip\"\r\n [severity]=\"action?.severity\"\r\n (onClick)=\"onAction(action, node)\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n </ng-template>\r\n </f-canvas>\r\n </f-flow>\r\n</div>\r\n@if (!readonly()) {\r\n <mt-toolbar />\r\n}\r\n", styles: ["::ng-deep :root{--background-element-color: rgba(0, 0, 0, .1);--selection-area-color: rgba(100, 108, 255, .14);--disabled-color: #e2e2e2;--node-background-color: #ffffff;--node-background-color-inverse: #000000;--node-border-radius: 2px;--node-border-color: rgba(60, 60, 67, .36);--node-selected-border-color: #3451b2;--node-color: rgba(60, 60, 67, .78);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: var(--p-text-color);--snap-connection-color: var(--p-text-muted-color);--connection-gradient-1: #b8272c;--connection-gradient-2: #30a46c;--outlet-color: #3451b2;--input-output-color: rgba(60, 60, 67, .78);--minimap-background-color: #ffffff;--minimap-node-color: rgba(60, 60, 67);--minimap-node-selected-color: var(--p-primary-color);--minimap-view-color: rgba(100, 108, 255, .14)}::ng-deep :root.dark{--background-element-color: rgba(255, 255, 255, .1);--selection-area-color: rgba(100, 108, 255, .16);--disabled-color: #2c2c2e;--node-background-color: #000000;--node-background-color-inverse: #ffffff;--node-border-radius: 2px;--node-border-color: rgba(235, 235, 245, .38);--node-selected-border-color: #a8b1ff;--node-color: rgba(235, 235, 245, .6);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: rgba(235, 235, 245, 1);--snap-connection-color: rgba(235, 235, 245, .2);--connection-gradient-1: #f66f81;--connection-gradient-2: #298459;--outlet-color: #a8b1ff;--input-output-color: rgba(235, 235, 245, .6);--minimap-background-color: #1b1b1f;--minimap-node-color: rgba(255, 255, 245, .86);--minimap-node-selected-color: #a8b1ff;--minimap-view-color: rgba(100, 108, 255, .16)}::ng-deep :root{--form-field-text-color: var(--node-color);--form-field-background: var(--minimap-view-color);--form-field-panel-shadow: var(--shadow-4);--form-field-panel-background: var(--node-background-color);--form-field-active-color: var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection{cursor:pointer}::ng-deep f-flow .f-connection .f-connection-drag-handle{fill:transparent}::ng-deep f-flow .f-connection .f-connection-selection{fill:none}::ng-deep f-flow .f-connection .f-connection-path{fill:none;stroke:var(--connection-color);stroke-width:2}::ng-deep f-flow .f-connection .f-connection-marker{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-marker path,::ng-deep f-flow .f-connection .f-marker circle{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-connection-text,::ng-deep f-flow .f-connection .f-connection-center{fill:var(--connection-color);color:var(--connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color)}::ng-deep f-flow .f-connection .f-connection-center{display:none}::ng-deep f-flow .f-connection.connection-loading .f-connection-center{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-center{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-path{stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection.f-selected .f-marker path,::ng-deep f-flow .f-connection.f-selected .f-marker circle{fill:var(--p-primary-color);stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection .f-connection-selection{fill:none;stroke:transparent;stroke-width:20;cursor:pointer}::ng-deep f-flow .f-connection:hover .f-connection-selection{stroke:var(--p-primary-color);opacity:.1}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:2px}::ng-deep f-flow .f-connection.f-snap-connection .f-marker path,::ng-deep f-flow .f-connection.f-snap-connection .f-marker circle{fill:var(--snap-connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection.f-connection-for-create .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection-for-create{pointer-events:none}::ng-deep f-flow .f-connection-for-create .f-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:3px;stroke-dasharray:8,4;animation:connection-dash 1s linear infinite}::ng-deep f-flow .f-connection-for-create .f-connection .f-marker path,::ng-deep f-flow .f-connection-for-create .f-connection .f-marker circle{fill:var(--snap-connection-color)}@keyframes connection-dash{to{stroke-dashoffset:-12}}::ng-deep f-flow{direction:ltr}.f-node-input:not(.f-node),.f-node-output:not(.f-node){position:absolute;border-radius:0 0 1rem 1rem}.f-node-input:not(.f-node):hover,.f-node-output:not(.f-node):hover{border:.5px dashed var(--p-primary-color)}.f-node-input:not(.f-node).top,.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).top,.f-node-output:not(.f-node).bottom{width:100%;height:16px;left:0}.f-node-input:not(.f-node).top,.f-node-output:not(.f-node).top{top:0}.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).bottom{bottom:0}.f-node-input:not(.f-node).left,.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).left,.f-node-output:not(.f-node).right{width:16px;height:100%;top:0}.f-node-input:not(.f-node).left,.f-node-output:not(.f-node).left{left:0;border-radius:1rem 0 0 1rem}.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).right{right:0;border-radius:0 1rem 1rem 0}.f-node-input:not(.f-node).f-node-output-not-connectable,.f-node-input:not(.f-node).f-node-input-not-connectable,.f-node-output:not(.f-node).f-node-output-not-connectable,.f-node-output:not(.f-node).f-node-input-not-connectable{background-color:var(--disabled-color)}.f-node-input:not(.f-node){border-radius:4px}.f-node-input,.f-node-output{z-index:10;pointer-events:all}.examples-toolbar{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:8px;position:absolute;right:16px;top:16px}.examples-toolbar button{font-weight:500;border:none;border-radius:2px;padding:4px 8px;line-height:normal}.f-node:before{content:\"\";position:absolute;width:100%;height:4rem;border-radius:var(--radius-2xl);z-index:-1;top:-.25rem;background-color:var(--node-data-border-color)}.connection-center{display:flex;gap:8px;background:var(--node-background-color);border:1px solid var(--node-border-color);border-radius:4px;padding:4px;box-shadow:var(--node-shadow)}.connection-center .connection-edit-btn,.connection-center .connection-delete-btn{background:none;border:none;width:24px;height:24px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.connection-center .connection-edit-btn:hover,.connection-center .connection-delete-btn:hover{background-color:var(--minimap-view-color)}.connection-center .connection-edit-btn{color:var(--minimap-node-selected-color)}.connection-center .connection-delete-btn{color:#ef4444}.node-edit-btn,.node-delete-btn{background:none;border:none;width:32px;height:32px;border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.node-edit-btn:hover,.node-delete-btn:hover{background-color:var(--minimap-view-color)}.node-edit-btn{color:var(--minimap-node-selected-color)}.node-delete-btn{color:#ef4444}.node-properties{max-height:200px;overflow-y:auto}.node-properties .property-item{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--node-border-color);font-size:12px}.node-properties .property-item .property-key{font-weight:600;color:var(--node-color);margin-right:8px}.node-properties .property-item .property-value{color:var(--minimap-node-selected-color);word-break:break-word}\n"] }]
|
|
709
|
+
}, template: "<!-- structure-builder.html -->\r\n@if (!readonly() && availableTabs().length > 0) {\r\n <mt-card\r\n class=\"absolute ms-4 mt-4 z-1 h-[calc(100%---spacing(8))] w-1/5 min-w-xs\"\r\n >\r\n <ng-template #headless>\r\n <!-- Header -->\r\n <div class=\"flex items-center justify-between px-4 pt-5\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"structureBuilder.levelTemplates\" | transloco }}\r\n </h3>\r\n </div>\r\n\r\n <!-- Tabs using PrimeNG -->\r\n <p-tabs\r\n [(value)]=\"activeTab\"\r\n styleClass=\"structure-tabs \"\r\n class=\"h-full overflow-hidden\"\r\n >\r\n <p-tablist>\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tab [value]=\"i.toString()\">{{ tab | titlecase }}</p-tab>\r\n }\r\n </p-tablist>\r\n <p-tabpanels class=\"bg-transparent! p-0! overflow-auto\">\r\n @for (tab of availableTabs(); track tab; let i = $index) {\r\n <p-tabpanel [value]=\"i.toString()\">\r\n <p class=\"text-xs text-muted py-3 px-4\">\r\n {{ \"structureBuilder.dragToAdd\" | transloco }}\r\n </p>\r\n\r\n <!-- Node List -->\r\n <div class=\"space-y-1 px-4\">\r\n @for (node of currentTabNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n style=\"display: flex\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move transition-colors\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{\r\n node.label\r\n }}</span>\r\n <mt-icon class=\"text-lg\" icon=\"general.menu-05\"></mt-icon>\r\n </div>\r\n }\r\n\r\n @if (currentTabNodes().length === 0) {\r\n <div class=\"text-center py-8 text-gray-400\">\r\n <p class=\"text-sm\">\r\n {{\r\n \"structureBuilder.allItemsInUse\"\r\n | transloco: { tab: tab }\r\n }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </p-tabpanel>\r\n }\r\n </p-tabpanels>\r\n </p-tabs>\r\n </ng-template>\r\n </mt-card>\r\n} @else if (!readonly() && availableNodes().length > 0) {\r\n <div [ngClass]=\"availableTabsClass() || 'absolute top-4 start-4 z-1 w-64'\">\r\n <mt-card [title]=\"'structureBuilder.steps' | transloco\">\r\n <div class=\"flex flex-col gap-2\">\r\n @for (node of availableNodes(); track node.id) {\r\n <div\r\n fExternalItem\r\n [fData]=\"node\"\r\n style=\"display: flex\"\r\n class=\"group select-none relative flex items-center gap-3 py-3 px-4 hover:bg-emphasis hover:border-solid transition-colors rounded-lg border-1 border-dashed border-color border-surface-300 dark:border-surface-500 cursor-move bg-content\"\r\n >\r\n <!-- Node Icon with color -->\r\n <div class=\"text-primary text-lg\">\r\n <mt-icon [icon]=\"node.icon || 'general.box'\"></mt-icon>\r\n </div>\r\n\r\n <!-- Node Name -->\r\n <span class=\"text-base font-medium flex-1\">{{ node.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n </div>\r\n}\r\n<!-- Left Sidebar -->\r\n\r\n<!-- Main Canvas Area -->\r\n<div class=\"flex-1 z-0 relative\">\r\n <ng-content select=\"[flowContent]\"></ng-content>\r\n\r\n <f-flow\r\n fDraggable\r\n dir=\"ltr\"\r\n (fLoaded)=\"onLoaded()\"\r\n (fCreateNode)=\"onCreateNode($event)\"\r\n (fCreateConnection)=\"onCreateConnection($event)\"\r\n class=\"size-full\"\r\n >\r\n <f-background>\r\n <f-circle-pattern color=\"#b5b5b5\"></f-circle-pattern>\r\n </f-background>\r\n <f-canvas fZoom [fZoomMinimum]=\"0.1\" [fZoomMaximum]=\"2\">\r\n <f-connection-for-create fBehavior=\"floating\" fType=\"straight\">\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-connection-for-create>\r\n <f-snap-connection\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n class=\"z-1\"\r\n [fSnapThreshold]=\"100\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n </f-snap-connection>\r\n\r\n <f-connection-for-create></f-connection-for-create>\r\n\r\n <!-- Enhanced Connections with Edit Button -->\r\n @for (connection of renderedConnections(); track connection.id) {\r\n <f-connection\r\n [fReassignDisabled]=\"true\"\r\n [fOutputId]=\"connection._outputConnectorId\"\r\n [fInputId]=\"connection._inputConnectorId\"\r\n [fOutputSide]=\"connection._outputSide\"\r\n [fInputSide]=\"connection._inputSide\"\r\n fBehavior=\"fixed\"\r\n fType=\"segment\"\r\n [ngClass]=\"{ 'connection-loading': connection.loading, 'z-1': true }\"\r\n >\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_START\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n <svg\r\n viewBox=\"0 0 12 12\"\r\n fMarker\r\n [type]=\"eMarkerType.SELECTED_END\"\r\n [height]=\"12\"\r\n [width]=\"12\"\r\n [refX]=\"6\"\r\n [refY]=\"6\"\r\n >\r\n <circle\r\n cx=\"6\"\r\n cy=\"6\"\r\n r=\"3\"\r\n stroke=\"none\"\r\n fill=\"currentColor\"\r\n ></circle>\r\n </svg>\r\n @if (!readonly()) {\r\n <div\r\n fConnectionContent\r\n class=\"flex items-center gap-1 bg-content rounded-md p-1 shadow-sm\"\r\n >\r\n @if (!connection.loading) {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.edit-05'\"\r\n (click)=\"openConnectionDialog(connection)\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n severity=\"danger\"\r\n [icon]=\"'general.trash-01'\"\r\n (click)=\"removeConnection(connection)\"\r\n >\r\n </mt-button>\r\n } @else {\r\n <mt-button\r\n size=\"small\"\r\n variant=\"text\"\r\n [icon]=\"'general.loading-01'\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n }\r\n </f-connection>\r\n }\r\n\r\n <!-- Enhanced Nodes with Edit Button -->\r\n @for (node of nodesWithComputedProps(); track node._computedId) {\r\n <mt-card\r\n fNode\r\n fDragHandle\r\n [fNodePosition]=\"{\r\n x: node.configuration?.x || 200,\r\n y: node.configuration?.y || 100,\r\n }\"\r\n (fNodePositionChange)=\"onNodePositionChange($event, node._computedId)\"\r\n [style.--node-data-border-color]=\"node._computedColor\"\r\n >\r\n <ng-template #headless>\r\n @if (!node.loading) {\r\n <div [attr.dir]=\"contentDirection()\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"\r\n effectiveNodeTemplate() || defaultNodeTemplate\r\n \"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: node,\r\n node: node,\r\n actions: getFilteredNodeActions(node),\r\n onAction: nodeActionHandler,\r\n dir: contentDirection(),\r\n }\"\r\n >\r\n </ng-container>\r\n </div>\r\n @for (side of nodeConnectorSides(); track side) {\r\n <div\r\n fNodeInput\r\n [fInputId]=\"\r\n createConnectorId(node._computedId, 'input', side)\r\n \"\r\n [fInputConnectableSide]=\"side\"\r\n [fInputMultiple]=\"true\"\r\n class=\"sb-connector sb-connector-input\"\r\n [class.top]=\"side === 'top'\"\r\n [class.bottom]=\"side === 'bottom'\"\r\n [class.left]=\"side === 'left'\"\r\n [class.right]=\"side === 'right'\"\r\n ></div>\r\n\r\n <div\r\n fNodeOutput\r\n [fOutputId]=\"\r\n createConnectorId(node._computedId, 'output', side)\r\n \"\r\n [fOutputConnectableSide]=\"side\"\r\n [isSelfConnectable]=\"false\"\r\n [fOutputMultiple]=\"true\"\r\n class=\"sb-connector sb-connector-output bg-surface-50 dark:bg-surface-900\"\r\n [class.top]=\"side === 'top'\"\r\n [class.bottom]=\"side === 'bottom'\"\r\n [class.left]=\"side === 'left'\"\r\n [class.right]=\"side === 'right'\"\r\n ></div>\r\n }\r\n } @else {\r\n <p-skeleton height=\"10rem\" width=\"15rem\" />\r\n }\r\n\r\n <!-- Node Header with Edit Button -->\r\n </ng-template>\r\n </mt-card>\r\n }\r\n\r\n <ng-template\r\n #defaultNodeTemplate\r\n let-node\r\n let-actions=\"actions\"\r\n let-onAction=\"onAction\"\r\n >\r\n <div\r\n class=\"flex flex-col items-center min-w-3xs gap-2 px-3 py-4 rounded-t-2xl bg-white dark:bg-surface-800 border-(--p-content-border-color)\"\r\n >\r\n @if (node._computedIcon) {\r\n <mt-icon\r\n class=\"text-2xl text-primary\"\r\n [icon]=\"node._computedIcon\"\r\n />\r\n }\r\n <div>{{ node._computedName }}</div>\r\n </div>\r\n <div\r\n class=\"flex justify-center pt-3 mb-4 gap-2 bg-surface-50 dark:bg-surface-900\"\r\n >\r\n @for (action of actions; track action.key) {\r\n <mt-button\r\n [size]=\"action?.size || 'small'\"\r\n [variant]=\"action?.variant\"\r\n [icon]=\"action?.icon\"\r\n [tooltip]=\"action?.tooltip\"\r\n [severity]=\"action?.severity\"\r\n (onClick)=\"onAction(action, node)\"\r\n >\r\n </mt-button>\r\n }\r\n </div>\r\n </ng-template>\r\n </f-canvas>\r\n </f-flow>\r\n</div>\r\n@if (!readonly()) {\r\n <mt-toolbar />\r\n}\r\n", styles: ["::ng-deep :root{--background-element-color: rgba(0, 0, 0, .1);--selection-area-color: rgba(100, 108, 255, .14);--disabled-color: #e2e2e2;--node-background-color: #ffffff;--node-background-color-inverse: #000000;--node-border-radius: 2px;--node-border-color: rgba(60, 60, 67, .36);--node-selected-border-color: #3451b2;--node-color: rgba(60, 60, 67, .78);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: var(--p-text-color);--snap-connection-color: var(--p-text-muted-color);--connection-gradient-1: #b8272c;--connection-gradient-2: #30a46c;--outlet-color: #3451b2;--input-output-color: rgba(60, 60, 67, .78);--minimap-background-color: #ffffff;--minimap-node-color: rgba(60, 60, 67);--minimap-node-selected-color: var(--p-primary-color);--minimap-view-color: rgba(100, 108, 255, .14)}::ng-deep :root.dark{--background-element-color: rgba(255, 255, 255, .1);--selection-area-color: rgba(100, 108, 255, .16);--disabled-color: #2c2c2e;--node-background-color: #000000;--node-background-color-inverse: #ffffff;--node-border-radius: 2px;--node-border-color: rgba(235, 235, 245, .38);--node-selected-border-color: #a8b1ff;--node-color: rgba(235, 235, 245, .6);--node-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--connection-color: rgba(235, 235, 245, 1);--snap-connection-color: rgba(235, 235, 245, .2);--connection-gradient-1: #f66f81;--connection-gradient-2: #298459;--outlet-color: #a8b1ff;--input-output-color: rgba(235, 235, 245, .6);--minimap-background-color: #1b1b1f;--minimap-node-color: rgba(255, 255, 245, .86);--minimap-node-selected-color: #a8b1ff;--minimap-view-color: rgba(100, 108, 255, .16)}::ng-deep :root{--form-field-text-color: var(--node-color);--form-field-background: var(--minimap-view-color);--form-field-panel-shadow: var(--shadow-4);--form-field-panel-background: var(--node-background-color);--form-field-active-color: var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection{cursor:pointer}::ng-deep f-flow .f-connection .f-connection-drag-handle{fill:transparent}::ng-deep f-flow .f-connection .f-connection-selection{fill:none}::ng-deep f-flow .f-connection .f-connection-path{fill:none;stroke:var(--connection-color);stroke-width:2}::ng-deep f-flow .f-connection .f-connection-marker{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-marker path,::ng-deep f-flow .f-connection .f-marker circle{fill:var(--connection-color)}::ng-deep f-flow .f-connection .f-connection-text,::ng-deep f-flow .f-connection .f-connection-center,::ng-deep f-flow .f-connection .f-connection-content{fill:var(--connection-color);color:var(--connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color)}::ng-deep f-flow .f-connection .f-connection-center,::ng-deep f-flow .f-connection .f-connection-content{display:none}::ng-deep f-flow .f-connection.connection-loading .f-connection-center,::ng-deep f-flow .f-connection.connection-loading .f-connection-content{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-center,::ng-deep f-flow .f-connection.f-selected .f-connection-content{display:block}::ng-deep f-flow .f-connection.f-selected .f-connection-path{stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection.f-selected .f-marker path,::ng-deep f-flow .f-connection.f-selected .f-marker circle{fill:var(--p-primary-color);stroke:var(--minimap-node-selected-color)}::ng-deep f-flow .f-connection .f-connection-selection{fill:none;stroke:transparent;stroke-width:20;cursor:pointer}::ng-deep f-flow .f-connection:hover .f-connection-selection{stroke:var(--p-primary-color);opacity:.1}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:2px}::ng-deep f-flow .f-connection.f-snap-connection .f-marker path,::ng-deep f-flow .f-connection.f-snap-connection .f-marker circle{fill:var(--snap-connection-color)}::ng-deep f-flow .f-connection.f-snap-connection .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection.f-connection-for-create .f-connection-selection{fill:transparent!important;stroke:transparent!important}::ng-deep f-flow .f-connection-for-create{pointer-events:none}::ng-deep f-flow .f-connection-for-create .f-connection .f-connection-path{stroke:var(--snap-connection-color);stroke-width:3px;stroke-dasharray:8,4;animation:connection-dash 1s linear infinite}::ng-deep f-flow .f-connection-for-create .f-connection .f-marker path,::ng-deep f-flow .f-connection-for-create .f-connection .f-marker circle{fill:var(--snap-connection-color)}@keyframes connection-dash{to{stroke-dashoffset:-12}}::ng-deep f-flow{direction:ltr}.f-node-input:not(.f-node),.f-node-output:not(.f-node){position:absolute}.f-node-input:not(.f-node):hover,.f-node-output:not(.f-node):hover{border:.5px dashed var(--p-primary-color)}.f-node-input:not(.f-node).top,.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).top,.f-node-output:not(.f-node).bottom{width:100%;height:16px;left:0}.f-node-input:not(.f-node).top,.f-node-output:not(.f-node).top{top:0;border-radius:1rem 1rem 0 0}.f-node-input:not(.f-node).bottom,.f-node-output:not(.f-node).bottom{bottom:0;border-radius:0 0 1rem 1rem}.f-node-input:not(.f-node).left,.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).left,.f-node-output:not(.f-node).right{width:16px;height:100%;top:0}.f-node-input:not(.f-node).left,.f-node-output:not(.f-node).left{left:0;border-radius:1rem 0 0 1rem}.f-node-input:not(.f-node).right,.f-node-output:not(.f-node).right{right:0;border-radius:0 1rem 1rem 0}.f-node-input:not(.f-node).f-node-output-not-connectable,.f-node-input:not(.f-node).f-node-input-not-connectable,.f-node-output:not(.f-node).f-node-output-not-connectable,.f-node-output:not(.f-node).f-node-input-not-connectable{background-color:var(--disabled-color)}.sb-connector-input,.sb-connector-output{background-color:transparent!important}.f-node-input:not(.f-node){border-radius:4px}.f-node-input,.f-node-output{z-index:10;pointer-events:all}.examples-toolbar{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:8px;position:absolute;right:16px;top:16px}.examples-toolbar button{font-weight:500;border:none;border-radius:2px;padding:4px 8px;line-height:normal}.f-node:before{content:\"\";position:absolute;width:100%;height:4rem;border-radius:var(--radius-2xl);z-index:-1;top:-.25rem;background-color:var(--node-data-border-color)}.connection-center{display:flex;gap:8px;background:var(--node-background-color);border:1px solid var(--node-border-color);border-radius:4px;padding:4px;box-shadow:var(--node-shadow)}.connection-center .connection-edit-btn,.connection-center .connection-delete-btn{background:none;border:none;width:24px;height:24px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.connection-center .connection-edit-btn:hover,.connection-center .connection-delete-btn:hover{background-color:var(--minimap-view-color)}.connection-center .connection-edit-btn{color:var(--minimap-node-selected-color)}.connection-center .connection-delete-btn{color:#ef4444}.node-edit-btn,.node-delete-btn{background:none;border:none;width:32px;height:32px;border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.node-edit-btn:hover,.node-delete-btn:hover{background-color:var(--minimap-view-color)}.node-edit-btn{color:var(--minimap-node-selected-color)}.node-delete-btn{color:#ef4444}.node-properties{max-height:200px;overflow-y:auto}.node-properties .property-item{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--node-border-color);font-size:12px}.node-properties .property-item .property-key{font-weight:600;color:var(--node-color);margin-right:8px}.node-properties .property-item .property-value{color:var(--minimap-node-selected-color);word-break:break-word}\n"] }]
|
|
638
710
|
}], ctorParameters: () => [], propDecorators: { nodeActionsEvent: [{ type: i0.Output, args: ["nodeActionsEvent"] }], action: [{ type: i0.Output, args: ["action"] }], availableNodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableNodes", required: false }] }], fCanvas: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FCanvasComponent), { isSignal: true }] }], fFlowComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FFlowComponent), { isSignal: true }] }], fCanvasComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FCanvasComponent), { isSignal: true }] }], fZoomDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FZoomDirective), { isSignal: true }] }], nodeForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeForm", required: false }] }], nodeDialogFooterConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeDialogFooterConfig", required: false }] }], connectionForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionForm", required: false }] }], connectionFormulaSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionFormulaSchemaId", required: false }] }], connectionFormulaConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionFormulaConfig", required: false }] }], nodeActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeActions", required: false }] }], nodeFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeFields", required: false }] }], isAutoLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAutoLayout", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], addModalType: [{ type: i0.Input, args: [{ isSignal: true, alias: "addModalType", required: false }] }], updateModalType: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateModalType", required: false }] }], addModalStyleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "addModalStyleClass", required: false }] }], updateModalStyleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateModalStyleClass", required: false }] }], addModalHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "addModalHeader", required: false }] }], updateModalHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "updateModalHeader", required: false }] }], appendTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendTo", required: false }] }], availableTabsClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableTabsClass", required: false }] }], layoutDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "layoutDirection", required: false }] }], nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }, { type: i0.Output, args: ["nodesChange"] }], connections: [{ type: i0.Input, args: [{ isSignal: true, alias: "connections", required: false }] }, { type: i0.Output, args: ["connectionsChange"] }], nodeDialogTemplate: [{ type: i0.ContentChild, args: ['nodeDialog', { isSignal: true }] }], nodeTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeTemplate", required: false }] }], nodeTemplateContent: [{ type: i0.ContentChild, args: ['nodeTemplate', { isSignal: true }] }] } });
|
|
639
711
|
|
|
640
712
|
/*
|