@memberjunction/ng-flow-editor 6.1.0-edge.0 → 6.1.0-edge.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/agent-editor/agent-flow-transformer.service.d.ts +31 -0
- package/dist/lib/agent-editor/agent-flow-transformer.service.d.ts.map +1 -1
- package/dist/lib/agent-editor/agent-flow-transformer.service.js +85 -22
- package/dist/lib/agent-editor/agent-flow-transformer.service.js.map +1 -1
- package/dist/lib/agent-editor/flow-agent-editor.component.d.ts +46 -1
- package/dist/lib/agent-editor/flow-agent-editor.component.d.ts.map +1 -1
- package/dist/lib/agent-editor/flow-agent-editor.component.js +160 -97
- package/dist/lib/agent-editor/flow-agent-editor.component.js.map +1 -1
- package/dist/lib/components/flow-editor.component.d.ts +26 -1
- package/dist/lib/components/flow-editor.component.d.ts.map +1 -1
- package/dist/lib/components/flow-editor.component.js +202 -149
- package/dist/lib/components/flow-editor.component.js.map +1 -1
- package/dist/lib/components/flow-palette.component.d.ts +22 -3
- package/dist/lib/components/flow-palette.component.d.ts.map +1 -1
- package/dist/lib/components/flow-palette.component.js +48 -23
- package/dist/lib/components/flow-palette.component.js.map +1 -1
- package/dist/lib/flow-editor.module.d.ts +7 -6
- package/dist/lib/flow-editor.module.d.ts.map +1 -1
- package/dist/lib/flow-editor.module.js +6 -2
- package/dist/lib/flow-editor.module.js.map +1 -1
- package/package.json +13 -12
|
@@ -15,10 +15,11 @@ import * as i7 from "./flow-palette.component";
|
|
|
15
15
|
import * as i8 from "./flow-toolbar.component";
|
|
16
16
|
import * as i9 from "./flow-status-bar.component";
|
|
17
17
|
const _c0 = ["fZoomRef"];
|
|
18
|
-
const _c1 =
|
|
18
|
+
const _c1 = ["canvasArea"];
|
|
19
|
+
const _c2 = (a0, a1) => ({ x: a0, y: a1 });
|
|
19
20
|
function FlowEditorComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
20
21
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
21
|
-
i0.ɵɵelementStart(0, "div",
|
|
22
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "mj-flow-toolbar", 18);
|
|
22
23
|
i0.ɵɵlistener("ZoomInClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomInClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomIn()); })("ZoomOutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomOutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomOut()); })("FitToScreenClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_FitToScreenClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomToFit()); })("AutoLayoutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_AutoLayoutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.AutoArrange()); })("GridToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_GridToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridToggled($event)); })("MinimapToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_MinimapToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMinimapToggled($event)); })("LegendToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_LegendToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLegendToggled($event)); })("PanModeToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_PanModeToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPanModeToggled($event)); });
|
|
23
24
|
i0.ɵɵelementEnd()();
|
|
24
25
|
} if (rf & 2) {
|
|
@@ -27,196 +28,199 @@ function FlowEditorComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
|
27
28
|
i0.ɵɵproperty("ZoomLevel", ctx_r2.zoomLevel)("ShowGrid", ctx_r2.ShowGrid)("ShowMinimap", ctx_r2.ShowMinimap)("ShowLegend", ctx_r2.ShowLegend)("ReadOnly", ctx_r2.ReadOnly)("PanMode", ctx_r2.panMode);
|
|
28
29
|
} }
|
|
29
30
|
function FlowEditorComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
30
|
-
i0.ɵɵ
|
|
31
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
32
|
+
i0.ɵɵelementStart(0, "mj-flow-palette", 19);
|
|
33
|
+
i0.ɵɵlistener("NodeTypeActivated", function FlowEditorComponent_Conditional_3_Template_mj_flow_palette_NodeTypeActivated_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPaletteNodeTypeActivated($event)); });
|
|
34
|
+
i0.ɵɵelementEnd();
|
|
31
35
|
} if (rf & 2) {
|
|
32
36
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
33
37
|
i0.ɵɵproperty("NodeTypes", ctx_r2.NodeTypes);
|
|
34
38
|
} }
|
|
35
|
-
function
|
|
39
|
+
function FlowEditorComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
36
40
|
i0.ɵɵelementStart(0, "f-background");
|
|
37
|
-
i0.ɵɵelement(1, "f-circle-pattern",
|
|
41
|
+
i0.ɵɵelement(1, "f-circle-pattern", 20);
|
|
38
42
|
i0.ɵɵelementEnd();
|
|
39
43
|
} if (rf & 2) {
|
|
40
44
|
i0.ɵɵadvance();
|
|
41
45
|
i0.ɵɵproperty("color", "#94a3b8")("radius", 24);
|
|
42
46
|
} }
|
|
43
|
-
function
|
|
44
|
-
i0.ɵɵelement(0, "f-line-alignment",
|
|
47
|
+
function FlowEditorComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
i0.ɵɵelement(0, "f-line-alignment", 8);
|
|
45
49
|
} if (rf & 2) {
|
|
46
50
|
i0.ɵɵproperty("fAlignThreshold", 10);
|
|
47
51
|
} }
|
|
48
|
-
function
|
|
49
|
-
i0.ɵɵelementStart(0, "f-connection-for-create",
|
|
52
|
+
function FlowEditorComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
53
|
+
i0.ɵɵelementStart(0, "f-connection-for-create", 10);
|
|
50
54
|
i0.ɵɵnamespaceSVG();
|
|
51
|
-
i0.ɵɵelementStart(1, "svg",
|
|
52
|
-
i0.ɵɵelement(2, "path",
|
|
55
|
+
i0.ɵɵelementStart(1, "svg", 21);
|
|
56
|
+
i0.ɵɵelement(2, "path", 22);
|
|
53
57
|
i0.ɵɵelementEnd()();
|
|
54
58
|
} if (rf & 2) {
|
|
55
59
|
i0.ɵɵproperty("fRadius", 8)("fOffset", 12);
|
|
56
60
|
i0.ɵɵadvance();
|
|
57
61
|
i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
|
|
58
62
|
} }
|
|
59
|
-
function
|
|
60
|
-
i0.ɵɵelement(0, "i",
|
|
63
|
+
function FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
+
i0.ɵɵelement(0, "i", 28);
|
|
61
65
|
} if (rf & 2) {
|
|
62
|
-
const
|
|
63
|
-
i0.ɵɵstyleProp("color",
|
|
64
|
-
i0.ɵɵproperty("ngClass",
|
|
66
|
+
const conn_r6 = i0.ɵɵnextContext(2).$implicit;
|
|
67
|
+
i0.ɵɵstyleProp("color", conn_r6.LabelIconColor || "inherit");
|
|
68
|
+
i0.ɵɵproperty("ngClass", conn_r6.LabelIcon);
|
|
65
69
|
} }
|
|
66
|
-
function
|
|
67
|
-
i0.ɵɵelementStart(0, "div",
|
|
68
|
-
i0.ɵɵconditionalCreate(1,
|
|
70
|
+
function FlowEditorComponent_For_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
71
|
+
i0.ɵɵelementStart(0, "div", 26);
|
|
72
|
+
i0.ɵɵconditionalCreate(1, FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template, 1, 3, "i", 27);
|
|
69
73
|
i0.ɵɵtext(2);
|
|
70
74
|
i0.ɵɵelementEnd();
|
|
71
75
|
} if (rf & 2) {
|
|
72
|
-
const
|
|
76
|
+
const conn_r6 = i0.ɵɵnextContext().$implicit;
|
|
73
77
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
74
78
|
i0.ɵɵstyleProp("background-color", ctx_r2.ConnectionLabelBackground)("border-color", ctx_r2.ConnectionLabelBorderColor)("color", ctx_r2.ConnectionLabelTextColor);
|
|
75
|
-
i0.ɵɵproperty("position", 0.5)("title",
|
|
79
|
+
i0.ɵɵproperty("position", 0.5)("title", conn_r6.LabelDetail || conn_r6.Label || "");
|
|
76
80
|
i0.ɵɵadvance();
|
|
77
|
-
i0.ɵɵconditional(
|
|
81
|
+
i0.ɵɵconditional(conn_r6.LabelIcon ? 1 : -1);
|
|
78
82
|
i0.ɵɵadvance();
|
|
79
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
83
|
+
i0.ɵɵtextInterpolate1(" ", conn_r6.Label, " ");
|
|
80
84
|
} }
|
|
81
|
-
function
|
|
82
|
-
const
|
|
83
|
-
i0.ɵɵelementStart(0, "f-connection",
|
|
84
|
-
i0.ɵɵlistener("click", function
|
|
85
|
+
function FlowEditorComponent_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
86
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
87
|
+
i0.ɵɵelementStart(0, "f-connection", 23);
|
|
88
|
+
i0.ɵɵlistener("click", function FlowEditorComponent_For_13_Template_f_connection_click_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionClicked($event, conn_r6)); })("contextmenu", function FlowEditorComponent_For_13_Template_f_connection_contextmenu_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionContextMenu($event, conn_r6)); });
|
|
85
89
|
i0.ɵɵnamespaceSVG();
|
|
86
|
-
i0.ɵɵelementStart(1, "svg",
|
|
87
|
-
i0.ɵɵelement(2, "path",
|
|
90
|
+
i0.ɵɵelementStart(1, "svg", 21);
|
|
91
|
+
i0.ɵɵelement(2, "path", 24);
|
|
88
92
|
i0.ɵɵelementEnd();
|
|
89
|
-
i0.ɵɵconditionalCreate(3,
|
|
93
|
+
i0.ɵɵconditionalCreate(3, FlowEditorComponent_For_13_Conditional_3_Template, 3, 10, "div", 25);
|
|
90
94
|
i0.ɵɵelementEnd();
|
|
91
95
|
} if (rf & 2) {
|
|
92
|
-
const
|
|
96
|
+
const conn_r6 = ctx.$implicit;
|
|
93
97
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
94
|
-
i0.ɵɵstyleProp("--connection-color",
|
|
95
|
-
i0.ɵɵclassProp("mj-flow-connection-colored", !!
|
|
96
|
-
i0.ɵɵproperty("fConnectionId",
|
|
98
|
+
i0.ɵɵstyleProp("--connection-color", conn_r6.Color || "#94a3b8");
|
|
99
|
+
i0.ɵɵclassProp("mj-flow-connection-colored", !!conn_r6.Color)("mj-flow-connection-dashed", conn_r6.Style === "dashed")("mj-flow-connection-dotted", conn_r6.Style === "dotted");
|
|
100
|
+
i0.ɵɵproperty("fConnectionId", conn_r6.ID)("fOutputId", conn_r6.SourcePortID)("fInputId", conn_r6.TargetPortID)("fRadius", 8)("fOffset", 12)("fSelectionDisabled", false)("fReassignDisabled", ctx_r2.ReadOnly);
|
|
97
101
|
i0.ɵɵadvance();
|
|
98
102
|
i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
|
|
99
103
|
i0.ɵɵadvance();
|
|
100
|
-
i0.ɵɵattribute("fill",
|
|
104
|
+
i0.ɵɵattribute("fill", conn_r6.Color || "#94a3b8");
|
|
101
105
|
i0.ɵɵadvance();
|
|
102
|
-
i0.ɵɵconditional(
|
|
106
|
+
i0.ɵɵconditional(conn_r6.Label ? 3 : -1);
|
|
103
107
|
} }
|
|
104
|
-
function
|
|
105
|
-
const
|
|
106
|
-
i0.ɵɵelementStart(0, "mj-flow-node",
|
|
107
|
-
i0.ɵɵlistener("contextmenu", function
|
|
108
|
+
function FlowEditorComponent_For_15_Template(rf, ctx) { if (rf & 1) {
|
|
109
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
110
|
+
i0.ɵɵelementStart(0, "mj-flow-node", 29);
|
|
111
|
+
i0.ɵɵlistener("contextmenu", function FlowEditorComponent_For_15_Template_mj_flow_node_contextmenu_0_listener($event) { const node_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeContextMenu($event, node_r8)); });
|
|
108
112
|
i0.ɵɵelementEnd();
|
|
109
113
|
} if (rf & 2) {
|
|
110
|
-
const
|
|
114
|
+
const node_r8 = ctx.$implicit;
|
|
111
115
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
112
|
-
i0.ɵɵproperty("fNodeId",
|
|
116
|
+
i0.ɵɵproperty("fNodeId", node_r8.ID)("fNodePosition", i0.ɵɵpureFunction2(8, _c2, node_r8.Position.X, node_r8.Position.Y))("fNodeDraggingDisabled", ctx_r2.ReadOnly || ctx_r2.panMode || node_r8.Locked === true)("fNodeSelectionDisabled", ctx_r2.panMode)("fConnectOnNode", !ctx_r2.ReadOnly && !ctx_r2.panMode)("Node", node_r8)("TypeConfig", ctx_r2.GetTypeConfig(node_r8.Type))("ReadOnly", ctx_r2.ReadOnly);
|
|
113
117
|
} }
|
|
114
|
-
function
|
|
118
|
+
function FlowEditorComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
115
119
|
i0.ɵɵelement(0, "f-selection-area");
|
|
116
120
|
} }
|
|
117
|
-
function
|
|
118
|
-
i0.ɵɵelementStart(0, "div",
|
|
119
|
-
i0.ɵɵelement(1, "f-minimap",
|
|
121
|
+
function FlowEditorComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
122
|
+
i0.ɵɵelementStart(0, "div", 13);
|
|
123
|
+
i0.ɵɵelement(1, "f-minimap", 30);
|
|
120
124
|
i0.ɵɵelementEnd();
|
|
121
125
|
} if (rf & 2) {
|
|
122
126
|
i0.ɵɵadvance();
|
|
123
127
|
i0.ɵɵproperty("fMinSize", 1500);
|
|
124
128
|
} }
|
|
125
|
-
function
|
|
126
|
-
i0.ɵɵelementStart(0, "div",
|
|
129
|
+
function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "div", 31);
|
|
127
131
|
i0.ɵɵtext(2, "Legend");
|
|
128
132
|
i0.ɵɵelementEnd();
|
|
129
|
-
i0.ɵɵelementStart(3, "div",
|
|
133
|
+
i0.ɵɵelementStart(3, "div", 32)(4, "div", 33);
|
|
130
134
|
i0.ɵɵtext(5, "Connections");
|
|
131
135
|
i0.ɵɵelementEnd();
|
|
132
|
-
i0.ɵɵelementStart(6, "div",
|
|
136
|
+
i0.ɵɵelementStart(6, "div", 34);
|
|
133
137
|
i0.ɵɵnamespaceSVG();
|
|
134
|
-
i0.ɵɵelementStart(7, "svg",
|
|
135
|
-
i0.ɵɵelement(8, "line",
|
|
138
|
+
i0.ɵɵelementStart(7, "svg", 35);
|
|
139
|
+
i0.ɵɵelement(8, "line", 36);
|
|
136
140
|
i0.ɵɵelementEnd();
|
|
137
141
|
i0.ɵɵnamespaceHTML();
|
|
138
142
|
i0.ɵɵelementStart(9, "span");
|
|
139
143
|
i0.ɵɵtext(10, "Only exit path");
|
|
140
144
|
i0.ɵɵelementEnd()();
|
|
141
|
-
i0.ɵɵelementStart(11, "div",
|
|
145
|
+
i0.ɵɵelementStart(11, "div", 34);
|
|
142
146
|
i0.ɵɵnamespaceSVG();
|
|
143
|
-
i0.ɵɵelementStart(12, "svg",
|
|
144
|
-
i0.ɵɵelement(13, "line",
|
|
147
|
+
i0.ɵɵelementStart(12, "svg", 35);
|
|
148
|
+
i0.ɵɵelement(13, "line", 37);
|
|
145
149
|
i0.ɵɵelementEnd();
|
|
146
150
|
i0.ɵɵnamespaceHTML();
|
|
147
|
-
i0.ɵɵelement(14, "i",
|
|
151
|
+
i0.ɵɵelement(14, "i", 38);
|
|
148
152
|
i0.ɵɵelementStart(15, "span");
|
|
149
153
|
i0.ɵɵtext(16, "Default (fallback)");
|
|
150
154
|
i0.ɵɵelementEnd()();
|
|
151
|
-
i0.ɵɵelementStart(17, "div",
|
|
155
|
+
i0.ɵɵelementStart(17, "div", 34);
|
|
152
156
|
i0.ɵɵnamespaceSVG();
|
|
153
|
-
i0.ɵɵelementStart(18, "svg",
|
|
154
|
-
i0.ɵɵelement(19, "line",
|
|
157
|
+
i0.ɵɵelementStart(18, "svg", 35);
|
|
158
|
+
i0.ɵɵelement(19, "line", 39);
|
|
155
159
|
i0.ɵɵelementEnd();
|
|
156
160
|
i0.ɵɵnamespaceHTML();
|
|
157
161
|
i0.ɵɵelementStart(20, "span");
|
|
158
162
|
i0.ɵɵtext(21, "Conditional");
|
|
159
163
|
i0.ɵɵelementEnd()();
|
|
160
|
-
i0.ɵɵelementStart(22, "div",
|
|
164
|
+
i0.ɵɵelementStart(22, "div", 34);
|
|
161
165
|
i0.ɵɵnamespaceSVG();
|
|
162
|
-
i0.ɵɵelementStart(23, "svg",
|
|
163
|
-
i0.ɵɵelement(24, "line",
|
|
166
|
+
i0.ɵɵelementStart(23, "svg", 35);
|
|
167
|
+
i0.ɵɵelement(24, "line", 40);
|
|
164
168
|
i0.ɵɵelementEnd();
|
|
165
169
|
i0.ɵɵnamespaceHTML();
|
|
166
|
-
i0.ɵɵelement(25, "i",
|
|
170
|
+
i0.ɵɵelement(25, "i", 41);
|
|
167
171
|
i0.ɵɵelementStart(26, "span");
|
|
168
172
|
i0.ɵɵtext(27, "Duplicate defaults");
|
|
169
173
|
i0.ɵɵelementEnd()()();
|
|
170
|
-
i0.ɵɵelementStart(28, "div",
|
|
174
|
+
i0.ɵɵelementStart(28, "div", 32)(29, "div", 33);
|
|
171
175
|
i0.ɵɵtext(30, "Step Types");
|
|
172
176
|
i0.ɵɵelementEnd();
|
|
173
|
-
i0.ɵɵelementStart(31, "div",
|
|
174
|
-
i0.ɵɵelement(32, "span",
|
|
177
|
+
i0.ɵɵelementStart(31, "div", 34);
|
|
178
|
+
i0.ɵɵelement(32, "span", 42);
|
|
175
179
|
i0.ɵɵelementStart(33, "span");
|
|
176
180
|
i0.ɵɵtext(34, "Action");
|
|
177
181
|
i0.ɵɵelementEnd()();
|
|
178
|
-
i0.ɵɵelementStart(35, "div",
|
|
179
|
-
i0.ɵɵelement(36, "span",
|
|
182
|
+
i0.ɵɵelementStart(35, "div", 34);
|
|
183
|
+
i0.ɵɵelement(36, "span", 43);
|
|
180
184
|
i0.ɵɵelementStart(37, "span");
|
|
181
185
|
i0.ɵɵtext(38, "Prompt");
|
|
182
186
|
i0.ɵɵelementEnd()();
|
|
183
|
-
i0.ɵɵelementStart(39, "div",
|
|
184
|
-
i0.ɵɵelement(40, "span",
|
|
187
|
+
i0.ɵɵelementStart(39, "div", 34);
|
|
188
|
+
i0.ɵɵelement(40, "span", 44);
|
|
185
189
|
i0.ɵɵelementStart(41, "span");
|
|
186
190
|
i0.ɵɵtext(42, "Sub-Agent");
|
|
187
191
|
i0.ɵɵelementEnd()();
|
|
188
|
-
i0.ɵɵelementStart(43, "div",
|
|
189
|
-
i0.ɵɵelement(44, "span",
|
|
192
|
+
i0.ɵɵelementStart(43, "div", 34);
|
|
193
|
+
i0.ɵɵelement(44, "span", 45);
|
|
190
194
|
i0.ɵɵelementStart(45, "span");
|
|
191
195
|
i0.ɵɵtext(46, "For Each");
|
|
192
196
|
i0.ɵɵelementEnd()();
|
|
193
|
-
i0.ɵɵelementStart(47, "div",
|
|
194
|
-
i0.ɵɵelement(48, "span",
|
|
197
|
+
i0.ɵɵelementStart(47, "div", 34);
|
|
198
|
+
i0.ɵɵelement(48, "span", 46);
|
|
195
199
|
i0.ɵɵelementStart(49, "span");
|
|
196
200
|
i0.ɵɵtext(50, "While");
|
|
197
201
|
i0.ɵɵelementEnd()()();
|
|
198
|
-
i0.ɵɵelementStart(51, "div",
|
|
202
|
+
i0.ɵɵelementStart(51, "div", 32)(52, "div", 33);
|
|
199
203
|
i0.ɵɵtext(53, "Borders");
|
|
200
204
|
i0.ɵɵelementEnd();
|
|
201
|
-
i0.ɵɵelementStart(54, "div",
|
|
202
|
-
i0.ɵɵelement(55, "span",
|
|
205
|
+
i0.ɵɵelementStart(54, "div", 34);
|
|
206
|
+
i0.ɵɵelement(55, "span", 47);
|
|
203
207
|
i0.ɵɵelementStart(56, "span");
|
|
204
208
|
i0.ɵɵtext(57, "Start node");
|
|
205
209
|
i0.ɵɵelementEnd()();
|
|
206
|
-
i0.ɵɵelementStart(58, "div",
|
|
207
|
-
i0.ɵɵelement(59, "span",
|
|
210
|
+
i0.ɵɵelementStart(58, "div", 34);
|
|
211
|
+
i0.ɵɵelement(59, "span", 48)(60, "i", 49);
|
|
208
212
|
i0.ɵɵelementStart(61, "span");
|
|
209
213
|
i0.ɵɵtext(62, "Missing config");
|
|
210
214
|
i0.ɵɵelementEnd()()()();
|
|
211
215
|
} }
|
|
212
|
-
function
|
|
213
|
-
i0.ɵɵelementStart(0, "p",
|
|
216
|
+
function FlowEditorComponent_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
217
|
+
i0.ɵɵelementStart(0, "p", 51);
|
|
214
218
|
i0.ɵɵtext(1, " Or use auto-layout after adding steps to arrange them automatically ");
|
|
215
219
|
i0.ɵɵelementEnd();
|
|
216
220
|
} }
|
|
217
|
-
function
|
|
218
|
-
i0.ɵɵelementStart(0, "div",
|
|
219
|
-
i0.ɵɵconditionalCreate(2,
|
|
221
|
+
function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
222
|
+
i0.ɵɵelementStart(0, "div", 15)(1, "mj-empty-state", 50);
|
|
223
|
+
i0.ɵɵconditionalCreate(2, FlowEditorComponent_Conditional_19_Conditional_2_Template, 2, 0, "p", 51);
|
|
220
224
|
i0.ɵɵelementEnd()();
|
|
221
225
|
} if (rf & 2) {
|
|
222
226
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
@@ -225,20 +229,20 @@ function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
|
225
229
|
i0.ɵɵadvance();
|
|
226
230
|
i0.ɵɵconditional(!ctx_r2.ReadOnly ? 2 : -1);
|
|
227
231
|
} }
|
|
228
|
-
function
|
|
229
|
-
const
|
|
230
|
-
i0.ɵɵelementStart(0, "div",
|
|
231
|
-
i0.ɵɵlistener("click", function
|
|
232
|
-
i0.ɵɵelementStart(1, "button",
|
|
233
|
-
i0.ɵɵlistener("click", function
|
|
234
|
-
i0.ɵɵelement(2, "i",
|
|
232
|
+
function FlowEditorComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
233
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
234
|
+
i0.ɵɵelementStart(0, "div", 52);
|
|
235
|
+
i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
236
|
+
i0.ɵɵelementStart(1, "button", 53);
|
|
237
|
+
i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("edit")); });
|
|
238
|
+
i0.ɵɵelement(2, "i", 54);
|
|
235
239
|
i0.ɵɵelementStart(3, "span");
|
|
236
240
|
i0.ɵɵtext(4);
|
|
237
241
|
i0.ɵɵelementEnd()();
|
|
238
|
-
i0.ɵɵelement(5, "div",
|
|
239
|
-
i0.ɵɵelementStart(6, "button",
|
|
240
|
-
i0.ɵɵlistener("click", function
|
|
241
|
-
i0.ɵɵelement(7, "i",
|
|
242
|
+
i0.ɵɵelement(5, "div", 55);
|
|
243
|
+
i0.ɵɵelementStart(6, "button", 56);
|
|
244
|
+
i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("remove")); });
|
|
245
|
+
i0.ɵɵelement(7, "i", 57);
|
|
242
246
|
i0.ɵɵelementStart(8, "span");
|
|
243
247
|
i0.ɵɵtext(9);
|
|
244
248
|
i0.ɵɵelementEnd()()();
|
|
@@ -250,8 +254,8 @@ function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
|
250
254
|
i0.ɵɵadvance(5);
|
|
251
255
|
i0.ɵɵtextInterpolate1("Remove ", ctx_r2.contextMenuTargetType === "node" ? "Node" : "Connection");
|
|
252
256
|
} }
|
|
253
|
-
function
|
|
254
|
-
i0.ɵɵelement(0, "mj-flow-status-bar",
|
|
257
|
+
function FlowEditorComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
258
|
+
i0.ɵɵelement(0, "mj-flow-status-bar", 17);
|
|
255
259
|
} if (rf & 2) {
|
|
256
260
|
const ctx_r2 = i0.ɵɵnextContext();
|
|
257
261
|
i0.ɵɵproperty("NodeCount", ctx_r2.Nodes.length)("ConnectionCount", ctx_r2.Connections.length)("SelectedCount", ctx_r2.selectedCount)("ZoomLevel", ctx_r2.zoomLevel);
|
|
@@ -289,16 +293,18 @@ export class FlowEditorComponent {
|
|
|
289
293
|
GridSize = 20;
|
|
290
294
|
AutoLayoutDirection = 'vertical';
|
|
291
295
|
/** Background color for connection labels */
|
|
292
|
-
|
|
296
|
+
// Design tokens, not literals — the canvas renders on both themes, and a near-white pill on a
|
|
297
|
+
// dark canvas made the least important element the most visually dominant thing on screen.
|
|
298
|
+
ConnectionLabelBackground = 'var(--mj-bg-surface)';
|
|
293
299
|
/** Border color for connection labels */
|
|
294
|
-
ConnectionLabelBorderColor = '
|
|
300
|
+
ConnectionLabelBorderColor = 'var(--mj-border-default)';
|
|
295
301
|
/** Text color for connection labels */
|
|
296
|
-
ConnectionLabelTextColor = '
|
|
302
|
+
ConnectionLabelTextColor = 'var(--mj-text-secondary)';
|
|
297
303
|
/** Title for the canvas empty-state overlay — depends on read-only mode. */
|
|
298
304
|
get EmptyStateTitle() {
|
|
299
305
|
return this.ReadOnly
|
|
300
306
|
? 'No steps defined for this flow'
|
|
301
|
-
: '
|
|
307
|
+
: 'Click a step in the palette — or drag one onto the canvas — to start building your flow';
|
|
302
308
|
}
|
|
303
309
|
// ── Outputs ─────────────────────────────────────────────────
|
|
304
310
|
NodeSelected = new EventEmitter();
|
|
@@ -322,6 +328,7 @@ export class FlowEditorComponent {
|
|
|
322
328
|
fFlow;
|
|
323
329
|
fCanvas;
|
|
324
330
|
fZoom;
|
|
331
|
+
canvasArea;
|
|
325
332
|
// ── Internal State ──────────────────────────────────────────
|
|
326
333
|
zoomLevel = 100;
|
|
327
334
|
canvasPosition = { x: 0, y: 0 };
|
|
@@ -343,6 +350,11 @@ export class FlowEditorComponent {
|
|
|
343
350
|
destroy$ = new Subject();
|
|
344
351
|
initialized = false;
|
|
345
352
|
lastConnectionClickTime = 0;
|
|
353
|
+
/** How many click-placed nodes are cascaded before the offset wraps back to the viewport centre. */
|
|
354
|
+
static CLICK_CASCADE_STEPS = 6;
|
|
355
|
+
/** Pixels (canvas units) each cascaded click-placed node is offset by. */
|
|
356
|
+
static CLICK_CASCADE_OFFSET = 40;
|
|
357
|
+
clickPlacementIndex = 0;
|
|
346
358
|
constructor(cdr, stateService, layoutService) {
|
|
347
359
|
this.cdr = cdr;
|
|
348
360
|
this.stateService = stateService;
|
|
@@ -607,11 +619,7 @@ export class FlowEditorComponent {
|
|
|
607
619
|
}
|
|
608
620
|
/** External item dropped from palette */
|
|
609
621
|
onCreateNode(event) {
|
|
610
|
-
|
|
611
|
-
return;
|
|
612
|
-
this.pushUndoState();
|
|
613
|
-
const nodeType = event.data;
|
|
614
|
-
const config = this.NodeTypes.find(nt => nt.Type === nodeType);
|
|
622
|
+
const config = this.NodeTypes.find(nt => nt.Type === event.data);
|
|
615
623
|
if (!config)
|
|
616
624
|
return;
|
|
617
625
|
// event.rect is already normalized to canvas coordinates by Foblex's
|
|
@@ -619,13 +627,45 @@ export class FlowEditorComponent {
|
|
|
619
627
|
// Do NOT pass it through getPositionInFlow() again — that double-normalizes
|
|
620
628
|
// and places the node far from the actual drop point.
|
|
621
629
|
// Use the center of the preview rect (≈ cursor position at drop time).
|
|
622
|
-
|
|
630
|
+
this.addNodeFromPalette(config, {
|
|
623
631
|
X: event.rect.x + event.rect.width / 2,
|
|
624
632
|
Y: event.rect.y + event.rect.height / 2
|
|
625
|
-
};
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* A palette entry was clicked (or activated from the keyboard) rather than dragged.
|
|
637
|
+
*
|
|
638
|
+
* Deliberately routed into the SAME `addNodeFromPalette` the drop path uses. A separate
|
|
639
|
+
* click-only creation path would be a second way for a node to come into existence, and the two
|
|
640
|
+
* would drift — which is exactly the failure this fixes, one level up.
|
|
641
|
+
*/
|
|
642
|
+
onPaletteNodeTypeActivated(config) {
|
|
643
|
+
this.addNodeFromPalette(config, this.nextClickDropPosition());
|
|
644
|
+
}
|
|
645
|
+
/** The one place a palette-originated node is created and announced. */
|
|
646
|
+
addNodeFromPalette(config, dropPosition) {
|
|
647
|
+
if (this.ReadOnly)
|
|
648
|
+
return;
|
|
649
|
+
this.pushUndoState();
|
|
626
650
|
const newNode = this.createDefaultNode(config, dropPosition);
|
|
627
651
|
this.NodeAdded.emit({ Node: newNode, DropPosition: dropPosition });
|
|
628
652
|
}
|
|
653
|
+
/**
|
|
654
|
+
* Where a clicked step lands: the middle of what the author is currently looking at, cascaded so
|
|
655
|
+
* consecutive clicks don't bury each other under one box.
|
|
656
|
+
*
|
|
657
|
+
* A click carries no coordinates, so *some* position has to be invented. The viewport centre is
|
|
658
|
+
* the only choice that is guaranteed on screen at any zoom or pan — placing at the canvas origin
|
|
659
|
+
* would drop steps off-screen the moment the author has scrolled anywhere.
|
|
660
|
+
*/
|
|
661
|
+
nextClickDropPosition() {
|
|
662
|
+
const rect = this.canvasArea?.nativeElement.getBoundingClientRect();
|
|
663
|
+
const scale = this.canvasScale || 1;
|
|
664
|
+
const centerX = ((rect?.width ?? 800) / 2 - this.canvasPosition.x) / scale;
|
|
665
|
+
const centerY = ((rect?.height ?? 600) / 2 - this.canvasPosition.y) / scale;
|
|
666
|
+
const step = (this.clickPlacementIndex++ % FlowEditorComponent.CLICK_CASCADE_STEPS) * FlowEditorComponent.CLICK_CASCADE_OFFSET;
|
|
667
|
+
return { X: Math.round(centerX + step), Y: Math.round(centerY + step) };
|
|
668
|
+
}
|
|
629
669
|
/** Selection changed in Foblex */
|
|
630
670
|
onSelectionChange(event) {
|
|
631
671
|
const timeSinceClick = Date.now() - this.lastConnectionClickTime;
|
|
@@ -725,23 +765,32 @@ export class FlowEditorComponent {
|
|
|
725
765
|
this.showContextMenu(event, 'connection', null, conn);
|
|
726
766
|
}
|
|
727
767
|
onContextMenuAction(action) {
|
|
768
|
+
// Capture the target BEFORE closing: hideContextMenu() nulls contextMenuNode and
|
|
769
|
+
// contextMenuConnection, so reading them afterwards found nothing and every branch below fell
|
|
770
|
+
// through — the menu closed and neither Remove nor Edit did anything, for nodes or connections.
|
|
771
|
+
const targetType = this.contextMenuTargetType;
|
|
772
|
+
const node = this.contextMenuNode;
|
|
773
|
+
const connection = this.contextMenuConnection;
|
|
728
774
|
this.hideContextMenu();
|
|
729
775
|
if (action === 'edit') {
|
|
730
|
-
if (
|
|
731
|
-
this.NodeEditRequested.emit(
|
|
776
|
+
if (targetType === 'node' && node) {
|
|
777
|
+
this.NodeEditRequested.emit(node);
|
|
732
778
|
}
|
|
733
|
-
else if (
|
|
734
|
-
this.ConnectionEditRequested.emit(
|
|
779
|
+
else if (targetType === 'connection' && connection) {
|
|
780
|
+
this.ConnectionEditRequested.emit(connection);
|
|
735
781
|
}
|
|
736
782
|
}
|
|
737
783
|
else if (action === 'remove') {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
this.removeNodeById(
|
|
784
|
+
if (targetType === 'node' && node) {
|
|
785
|
+
this.pushUndoState();
|
|
786
|
+
this.removeNodeById(node.ID);
|
|
741
787
|
}
|
|
742
|
-
else if (
|
|
743
|
-
this.
|
|
788
|
+
else if (targetType === 'connection' && connection) {
|
|
789
|
+
this.pushUndoState();
|
|
790
|
+
this.removeConnectionById(connection.ID);
|
|
744
791
|
}
|
|
792
|
+
// pushUndoState moved inside the branches: pushing before knowing there IS a target left an
|
|
793
|
+
// undo entry for an action that never happened, so the next Ctrl+Z did nothing visible.
|
|
745
794
|
}
|
|
746
795
|
}
|
|
747
796
|
onDocumentClick() {
|
|
@@ -927,38 +976,39 @@ export class FlowEditorComponent {
|
|
|
927
976
|
}
|
|
928
977
|
static ɵfac = function FlowEditorComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FlowEditorComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.FlowStateService), i0.ɵɵdirectiveInject(i2.FlowLayoutService)); };
|
|
929
978
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FlowEditorComponent, selectors: [["mj-flow-editor"]], viewQuery: function FlowEditorComponent_Query(rf, ctx) { if (rf & 1) {
|
|
930
|
-
i0.ɵɵviewQuery(FFlowComponent, 5)(FCanvasComponent, 5)(_c0, 5);
|
|
979
|
+
i0.ɵɵviewQuery(FFlowComponent, 5)(FCanvasComponent, 5)(_c0, 5)(_c1, 5);
|
|
931
980
|
} if (rf & 2) {
|
|
932
981
|
let _t;
|
|
933
982
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fFlow = _t.first);
|
|
934
983
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fCanvas = _t.first);
|
|
935
984
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fZoom = _t.first);
|
|
985
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.canvasArea = _t.first);
|
|
936
986
|
} }, hostBindings: function FlowEditorComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
937
987
|
i0.ɵɵlistener("click", function FlowEditorComponent_click_HostBindingHandler() { return ctx.onDocumentClick(); }, i0.ɵɵresolveDocument)("keydown", function FlowEditorComponent_keydown_HostBindingHandler($event) { return ctx.onKeyDown($event); });
|
|
938
|
-
} }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls:
|
|
988
|
+
} }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls: 22, vars: 25, consts: [["canvasArea", ""], ["fZoomRef", "fComponent"], ["tabindex", "0", 1, "mj-flow-editor"], [1, "mj-flow-editor-toolbar-area"], [1, "mj-flow-editor-canvas-area"], [3, "NodeTypes"], [1, "mj-flow-editor-canvas"], ["fDraggable", "", 3, "fLoaded", "fCreateConnection", "fReassignConnection", "fCreateNode", "fSelectionChange", "fMoveNodes", "fDraggableDisabled", "fCanvasMoveTrigger", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], [3, "fAlignThreshold"], ["fZoom", "", 3, "fCanvasChange", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "position", "scale"], ["fType", "bezier", 3, "fRadius", "fOffset"], ["fType", "bezier", "fBehavior", "fixed", 3, "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled", "--connection-color", "mj-flow-connection-colored", "mj-flow-connection-dashed", "mj-flow-connection-dotted"], ["fNode", "", "fDragHandle", "", 3, "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], ["fDragBlocker", "", 1, "mj-flow-editor-minimap"], [1, "mj-flow-editor-legend"], [1, "mj-flow-editor-empty"], [1, "mj-flow-context-menu", 3, "left", "top"], [3, "NodeCount", "ConnectionCount", "SelectedCount", "ZoomLevel"], [3, "ZoomInClicked", "ZoomOutClicked", "FitToScreenClicked", "AutoLayoutClicked", "GridToggled", "MinimapToggled", "LegendToggled", "PanModeToggled", "ZoomLevel", "ShowGrid", "ShowMinimap", "ShowLegend", "ReadOnly", "PanMode"], [3, "NodeTypeActivated", "NodeTypes"], [3, "color", "radius"], ["viewBox", "0 0 10 10", "fMarker", "", "type", "end", "orient", "auto", 3, "refX", "refY", "height", "width"], ["d", "M0 0L10 5L0 10Z", "fill", "#94a3b8"], ["fType", "bezier", "fBehavior", "fixed", 3, "click", "contextmenu", "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled"], ["d", "M0 0L10 5L0 10Z"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "backgroundColor", "borderColor", "color", "title"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "title"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass", "color"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass"], ["fNode", "", "fDragHandle", "", 3, "contextmenu", "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], [3, "fMinSize"], [1, "mj-flow-editor-legend-title"], [1, "mj-flow-editor-legend-section"], [1, "mj-flow-editor-legend-heading"], [1, "mj-flow-editor-legend-item"], ["width", "28", "height", "10", 1, "mj-flow-editor-legend-line-svg"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#64748b", "stroke-width", "2"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#16a34a", "stroke-width", "2"], [1, "fa-solid", "fa-circle-check", 2, "color", "#16a34a", "font-size", "10px"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#f59e0b", "stroke-width", "2", "stroke-dasharray", "5 3"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#ef4444", "stroke-width", "2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ef4444", "font-size", "10px"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#3B82F6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#8B5CF6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#10B981"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F59E0B"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F97316"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#16a34a", "background", "#f0fdf4"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#ef4444", "background", "#fef2f2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ea580c", "font-size", "10px"], ["Icon", "fa-solid fa-diagram-project", 3, "Title"], [1, "mj-flow-editor-empty-subtitle"], [1, "mj-flow-context-menu", 3, "click"], [1, "mj-flow-context-menu-item", 3, "click"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-flow-context-menu-divider"], [1, "mj-flow-context-menu-item", "mj-flow-context-menu-item--danger", 3, "click"], [1, "fa-solid", "fa-trash-can"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
|
|
939
989
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
940
|
-
i0.ɵɵelementStart(0, "div",
|
|
941
|
-
i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 6, "div",
|
|
942
|
-
i0.ɵɵelementStart(2, "div",
|
|
943
|
-
i0.ɵɵconditionalCreate(3, FlowEditorComponent_Conditional_3_Template, 1, 1, "mj-flow-palette",
|
|
944
|
-
i0.ɵɵelementStart(4, "div",
|
|
945
|
-
i0.ɵɵlistener("fLoaded", function
|
|
946
|
-
i0.ɵɵconditionalCreate(
|
|
947
|
-
i0.ɵɵconditionalCreate(
|
|
948
|
-
i0.ɵɵelementStart(
|
|
949
|
-
i0.ɵɵlistener("fCanvasChange", function
|
|
950
|
-
i0.ɵɵconditionalCreate(
|
|
951
|
-
i0.ɵɵrepeaterCreate(
|
|
952
|
-
i0.ɵɵrepeaterCreate(
|
|
990
|
+
i0.ɵɵelementStart(0, "div", 2);
|
|
991
|
+
i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 6, "div", 3);
|
|
992
|
+
i0.ɵɵelementStart(2, "div", 4);
|
|
993
|
+
i0.ɵɵconditionalCreate(3, FlowEditorComponent_Conditional_3_Template, 1, 1, "mj-flow-palette", 5);
|
|
994
|
+
i0.ɵɵelementStart(4, "div", 6, 0)(6, "f-flow", 7);
|
|
995
|
+
i0.ɵɵlistener("fLoaded", function FlowEditorComponent_Template_f_flow_fLoaded_6_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFlowLoaded()); })("fCreateConnection", function FlowEditorComponent_Template_f_flow_fCreateConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateConnection($event)); })("fReassignConnection", function FlowEditorComponent_Template_f_flow_fReassignConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReassignConnection($event)); })("fCreateNode", function FlowEditorComponent_Template_f_flow_fCreateNode_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateNode($event)); })("fSelectionChange", function FlowEditorComponent_Template_f_flow_fSelectionChange_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSelectionChange($event)); })("fMoveNodes", function FlowEditorComponent_Template_f_flow_fMoveNodes_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNodesMoved($event)); });
|
|
996
|
+
i0.ɵɵconditionalCreate(7, FlowEditorComponent_Conditional_7_Template, 2, 2, "f-background");
|
|
997
|
+
i0.ɵɵconditionalCreate(8, FlowEditorComponent_Conditional_8_Template, 1, 1, "f-line-alignment", 8);
|
|
998
|
+
i0.ɵɵelementStart(9, "f-canvas", 9, 1);
|
|
999
|
+
i0.ɵɵlistener("fCanvasChange", function FlowEditorComponent_Template_f_canvas_fCanvasChange_9_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCanvasChange($event)); });
|
|
1000
|
+
i0.ɵɵconditionalCreate(11, FlowEditorComponent_Conditional_11_Template, 3, 6, "f-connection-for-create", 10);
|
|
1001
|
+
i0.ɵɵrepeaterCreate(12, FlowEditorComponent_For_13_Template, 4, 21, "f-connection", 11, ctx.trackConnectionById, true);
|
|
1002
|
+
i0.ɵɵrepeaterCreate(14, FlowEditorComponent_For_15_Template, 1, 11, "mj-flow-node", 12, ctx.trackNodeById, true);
|
|
953
1003
|
i0.ɵɵelementEnd();
|
|
954
|
-
i0.ɵɵconditionalCreate(
|
|
955
|
-
i0.ɵɵconditionalCreate(
|
|
1004
|
+
i0.ɵɵconditionalCreate(16, FlowEditorComponent_Conditional_16_Template, 1, 0, "f-selection-area");
|
|
1005
|
+
i0.ɵɵconditionalCreate(17, FlowEditorComponent_Conditional_17_Template, 2, 1, "div", 13);
|
|
956
1006
|
i0.ɵɵelementEnd();
|
|
957
|
-
i0.ɵɵconditionalCreate(
|
|
958
|
-
i0.ɵɵconditionalCreate(
|
|
1007
|
+
i0.ɵɵconditionalCreate(18, FlowEditorComponent_Conditional_18_Template, 63, 0, "div", 14);
|
|
1008
|
+
i0.ɵɵconditionalCreate(19, FlowEditorComponent_Conditional_19_Template, 3, 2, "div", 15);
|
|
959
1009
|
i0.ɵɵelementEnd()();
|
|
960
|
-
i0.ɵɵconditionalCreate(
|
|
961
|
-
i0.ɵɵconditionalCreate(
|
|
1010
|
+
i0.ɵɵconditionalCreate(20, FlowEditorComponent_Conditional_20_Template, 10, 6, "div", 16);
|
|
1011
|
+
i0.ɵɵconditionalCreate(21, FlowEditorComponent_Conditional_21_Template, 1, 4, "mj-flow-status-bar", 17);
|
|
962
1012
|
i0.ɵɵelementEnd();
|
|
963
1013
|
} if (rf & 2) {
|
|
964
1014
|
i0.ɵɵclassProp("mj-flow-editor--readonly", ctx.ReadOnly);
|
|
@@ -968,37 +1018,37 @@ export class FlowEditorComponent {
|
|
|
968
1018
|
i0.ɵɵconditional(ctx.ShowPalette && !ctx.ReadOnly ? 3 : -1);
|
|
969
1019
|
i0.ɵɵadvance();
|
|
970
1020
|
i0.ɵɵclassProp("mj-flow-editor-canvas--pan-mode", ctx.panMode);
|
|
971
|
-
i0.ɵɵadvance();
|
|
1021
|
+
i0.ɵɵadvance(2);
|
|
972
1022
|
i0.ɵɵproperty("fDraggableDisabled", false)("fCanvasMoveTrigger", ctx.canvasMoveTriggerFn)("vCellSize", ctx.GridSize)("hCellSize", ctx.GridSize)("fCellSizeWhileDragging", ctx.ShowGrid);
|
|
973
1023
|
i0.ɵɵadvance();
|
|
974
|
-
i0.ɵɵconditional(ctx.ShowGrid ?
|
|
1024
|
+
i0.ɵɵconditional(ctx.ShowGrid ? 7 : -1);
|
|
975
1025
|
i0.ɵɵadvance();
|
|
976
|
-
i0.ɵɵconditional(!ctx.ReadOnly ?
|
|
1026
|
+
i0.ɵɵconditional(!ctx.ReadOnly ? 8 : -1);
|
|
977
1027
|
i0.ɵɵadvance();
|
|
978
1028
|
i0.ɵɵproperty("fZoomMinimum", 0.15)("fZoomMaximum", 3)("fZoomStep", 0.1)("position", ctx.canvasPosition)("scale", ctx.canvasScale);
|
|
979
1029
|
i0.ɵɵadvance(2);
|
|
980
|
-
i0.ɵɵconditional(!ctx.ReadOnly ?
|
|
1030
|
+
i0.ɵɵconditional(!ctx.ReadOnly ? 11 : -1);
|
|
981
1031
|
i0.ɵɵadvance();
|
|
982
1032
|
i0.ɵɵrepeater(ctx.Connections);
|
|
983
1033
|
i0.ɵɵadvance(2);
|
|
984
1034
|
i0.ɵɵrepeater(ctx.Nodes);
|
|
985
1035
|
i0.ɵɵadvance(2);
|
|
986
|
-
i0.ɵɵconditional(!ctx.ReadOnly ?
|
|
1036
|
+
i0.ɵɵconditional(!ctx.ReadOnly ? 16 : -1);
|
|
987
1037
|
i0.ɵɵadvance();
|
|
988
|
-
i0.ɵɵconditional(ctx.ShowMinimap ?
|
|
1038
|
+
i0.ɵɵconditional(ctx.ShowMinimap ? 17 : -1);
|
|
989
1039
|
i0.ɵɵadvance();
|
|
990
|
-
i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ?
|
|
1040
|
+
i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ? 18 : -1);
|
|
991
1041
|
i0.ɵɵadvance();
|
|
992
|
-
i0.ɵɵconditional(ctx.Nodes.length === 0 ?
|
|
1042
|
+
i0.ɵɵconditional(ctx.Nodes.length === 0 ? 19 : -1);
|
|
993
1043
|
i0.ɵɵadvance();
|
|
994
|
-
i0.ɵɵconditional(ctx.contextMenuVisible ?
|
|
1044
|
+
i0.ɵɵconditional(ctx.contextMenuVisible ? 20 : -1);
|
|
995
1045
|
i0.ɵɵadvance();
|
|
996
|
-
i0.ɵɵconditional(ctx.ShowStatusBar ?
|
|
1046
|
+
i0.ɵɵconditional(ctx.ShowStatusBar ? 21 : -1);
|
|
997
1047
|
} }, dependencies: [i3.NgClass, i4.FFlowComponent, i4.FCanvasComponent, i4.FBackgroundComponent, i4.FCirclePatternComponent, i4.FZoomDirective, i4.FConnectionContent, i4.FConnectionMarker, i4.FConnectionComponent, i4.FConnectionForCreateComponent, i4.FLineAlignmentComponent, i4.FMinimapComponent, i4.FNodeDirective, i4.FDragHandleDirective, i4.FSelectionAreaComponent, i4.FDragBlockerDirective, i4.FDraggableDirective, i5.MJEmptyStateComponent, i6.FlowNodeComponent, i7.FlowPaletteComponent, i8.FlowToolbarComponent, i9.FlowStatusBarComponent], styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"], encapsulation: 2 });
|
|
998
1048
|
}
|
|
999
1049
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlowEditorComponent, [{
|
|
1000
1050
|
type: Component,
|
|
1001
|
-
args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-flow-editor-toolbar-area\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\">\n </mj-flow-toolbar>\n </div>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\"\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"mj-flow-context-menu-item\" (click)=\"onContextMenuAction('edit')\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span>Edit {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n <div class=\"mj-flow-context-menu-divider\"></div>\n <button class=\"mj-flow-context-menu-item mj-flow-context-menu-item--danger\" (click)=\"onContextMenuAction('remove')\">\n <i class=\"fa-solid fa-trash-can\"></i>\n <span>Remove {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
|
|
1051
|
+
args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-flow-editor-toolbar-area\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\">\n </mj-flow-toolbar>\n </div>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\"\n (NodeTypeActivated)=\"onPaletteNodeTypeActivated($event)\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\" #canvasArea\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"mj-flow-context-menu-item\" (click)=\"onContextMenuAction('edit')\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span>Edit {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n <div class=\"mj-flow-context-menu-divider\"></div>\n <button class=\"mj-flow-context-menu-item mj-flow-context-menu-item--danger\" (click)=\"onContextMenuAction('remove')\">\n <i class=\"fa-solid fa-trash-can\"></i>\n <span>Remove {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
|
|
1002
1052
|
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.FlowStateService }, { type: i2.FlowLayoutService }], { Nodes: [{
|
|
1003
1053
|
type: Input
|
|
1004
1054
|
}], Connections: [{
|
|
@@ -1072,6 +1122,9 @@ export class FlowEditorComponent {
|
|
|
1072
1122
|
}], fZoom: [{
|
|
1073
1123
|
type: ViewChild,
|
|
1074
1124
|
args: ['fZoomRef']
|
|
1125
|
+
}], canvasArea: [{
|
|
1126
|
+
type: ViewChild,
|
|
1127
|
+
args: ['canvasArea']
|
|
1075
1128
|
}], onDocumentClick: [{
|
|
1076
1129
|
type: HostListener,
|
|
1077
1130
|
args: ['document:click']
|