@memberjunction/ng-core-entity-forms 2.86.0 → 2.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.d.ts.map +1 -1
  2. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -7
  3. package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
  4. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/condition-editor/condition-editor.component.d.ts +29 -0
  5. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/condition-editor/condition-editor.component.d.ts.map +1 -0
  6. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/condition-editor/condition-editor.component.js +198 -0
  7. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/condition-editor/condition-editor.component.js.map +1 -0
  8. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/confirmation-dialog/confirmation-dialog.component.d.ts +14 -0
  9. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/confirmation-dialog/confirmation-dialog.component.d.ts.map +1 -0
  10. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/confirmation-dialog/confirmation-dialog.component.js +98 -0
  11. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/confirmation-dialog/confirmation-dialog.component.js.map +1 -0
  12. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/custom-node/custom-node.component.d.ts +44 -0
  13. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/custom-node/custom-node.component.d.ts.map +1 -0
  14. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/custom-node/custom-node.component.js +282 -0
  15. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/custom-node/custom-node.component.js.map +1 -0
  16. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/execution-panel/execution-panel.component.d.ts +35 -0
  17. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/execution-panel/execution-panel.component.d.ts.map +1 -0
  18. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/execution-panel/execution-panel.component.js +287 -0
  19. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/execution-panel/execution-panel.component.js.map +1 -0
  20. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/flow-editor/flow-editor.component.d.ts +106 -0
  21. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/flow-editor/flow-editor.component.d.ts.map +1 -0
  22. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/flow-editor/flow-editor.component.js +951 -0
  23. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/flow-editor/flow-editor.component.js.map +1 -0
  24. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/prompt-editor/prompt-editor.component.d.ts +30 -0
  25. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/prompt-editor/prompt-editor.component.d.ts.map +1 -0
  26. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/prompt-editor/prompt-editor.component.js +450 -0
  27. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/prompt-editor/prompt-editor.component.js.map +1 -0
  28. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/properties-panel/properties-panel.component.d.ts +25 -0
  29. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/properties-panel/properties-panel.component.d.ts.map +1 -0
  30. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/properties-panel/properties-panel.component.js +423 -0
  31. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/properties-panel/properties-panel.component.js.map +1 -0
  32. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/simple-condition-editor/simple-condition-editor.component.d.ts +21 -0
  33. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/simple-condition-editor/simple-condition-editor.component.d.ts.map +1 -0
  34. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/simple-condition-editor/simple-condition-editor.component.js +182 -0
  35. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/simple-condition-editor/simple-condition-editor.component.js.map +1 -0
  36. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/step/step.component.d.ts +34 -0
  37. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/step/step.component.d.ts.map +1 -0
  38. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/step/step.component.js +171 -0
  39. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/step/step.component.js.map +1 -0
  40. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/toolbar/toolbar.component.d.ts +17 -0
  41. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/toolbar/toolbar.component.d.ts.map +1 -0
  42. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/toolbar/toolbar.component.js +78 -0
  43. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/toolbar/toolbar.component.js.map +1 -0
  44. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/connection.model.d.ts +17 -0
  45. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/connection.model.d.ts.map +1 -0
  46. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/connection.model.js +11 -0
  47. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/connection.model.js.map +1 -0
  48. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/mj-extended.model.d.ts +21 -0
  49. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/mj-extended.model.d.ts.map +1 -0
  50. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/mj-extended.model.js +2 -0
  51. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/mj-extended.model.js.map +1 -0
  52. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/module.model.d.ts +33 -0
  53. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/module.model.d.ts.map +1 -0
  54. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/module.model.js +2 -0
  55. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/module.model.js.map +1 -0
  56. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/step.model.d.ts +44 -0
  57. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/step.model.d.ts.map +1 -0
  58. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/step.model.js +166 -0
  59. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/models/step.model.js.map +1 -0
  60. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-editor.service.d.ts +14 -0
  61. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-editor.service.d.ts.map +1 -0
  62. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-editor.service.js +31 -0
  63. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-editor.service.js.map +1 -0
  64. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-executor.service.d.ts +63 -0
  65. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-executor.service.d.ts.map +1 -0
  66. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-executor.service.js +294 -0
  67. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/flow-executor.service.js.map +1 -0
  68. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/mj-flow-transformer.service.d.ts +77 -0
  69. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/mj-flow-transformer.service.d.ts.map +1 -0
  70. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/mj-flow-transformer.service.js +408 -0
  71. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/mj-flow-transformer.service.js.map +1 -0
  72. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/module-manager.service.d.ts +19 -0
  73. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/module-manager.service.d.ts.map +1 -0
  74. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/module-manager.service.js +116 -0
  75. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/module-manager.service.js.map +1 -0
  76. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/prompt-manager.service.d.ts +25 -0
  77. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/prompt-manager.service.d.ts.map +1 -0
  78. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/prompt-manager.service.js +90 -0
  79. package/dist/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/services/prompt-manager.service.js.map +1 -0
  80. package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.d.ts +52 -0
  81. package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.d.ts.map +1 -0
  82. package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.js +500 -0
  83. package/dist/lib/custom/AIAgents/FlowAgentType/mj-integrated-flow-editor.component.js.map +1 -0
  84. package/dist/lib/custom/custom-forms.module.d.ts +2 -1
  85. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  86. package/dist/lib/custom/custom-forms.module.js +10 -4
  87. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  88. package/dist/lib/generated/Entities/Component/sections/details.component.d.ts.map +1 -1
  89. package/dist/lib/generated/Entities/Component/sections/details.component.js +40 -4
  90. package/dist/lib/generated/Entities/Component/sections/details.component.js.map +1 -1
  91. package/package.json +16 -16
@@ -0,0 +1,951 @@
1
+ import { Component, ViewChild, Output, EventEmitter } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { StepComponent } from '../step/step.component';
4
+ import { SimpleConditionEditorComponent } from '../simple-condition-editor/simple-condition-editor.component';
5
+ import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component';
6
+ import { STEP_CONFIGS } from '../../models/step.model';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../../services/flow-editor.service";
9
+ import * as i2 from "../../services/flow-executor.service";
10
+ import * as i3 from "@angular/common";
11
+ const _c0 = ["reteEditor"];
12
+ function FlowEditorComponent_div_7_Template(rf, ctx) { if (rf & 1) {
13
+ i0.ɵɵelementStart(0, "div", 29)(1, "div", 30);
14
+ i0.ɵɵnamespaceSVG();
15
+ i0.ɵɵelementStart(2, "svg", 31);
16
+ i0.ɵɵelement(3, "line", 32);
17
+ i0.ɵɵelementEnd();
18
+ i0.ɵɵnamespaceHTML();
19
+ i0.ɵɵelementStart(4, "span");
20
+ i0.ɵɵtext(5, "First output from a step");
21
+ i0.ɵɵelementEnd()();
22
+ i0.ɵɵelementStart(6, "div", 30);
23
+ i0.ɵɵnamespaceSVG();
24
+ i0.ɵɵelementStart(7, "svg", 31);
25
+ i0.ɵɵelement(8, "line", 33);
26
+ i0.ɵɵelementEnd();
27
+ i0.ɵɵnamespaceHTML();
28
+ i0.ɵɵelementStart(9, "span");
29
+ i0.ɵɵtext(10, "Second output from a step");
30
+ i0.ɵɵelementEnd()();
31
+ i0.ɵɵelementStart(11, "div", 30);
32
+ i0.ɵɵnamespaceSVG();
33
+ i0.ɵɵelementStart(12, "svg", 31);
34
+ i0.ɵɵelement(13, "line", 34);
35
+ i0.ɵɵelementEnd();
36
+ i0.ɵɵnamespaceHTML();
37
+ i0.ɵɵelementStart(14, "span");
38
+ i0.ɵɵtext(15, "Third output from a step");
39
+ i0.ɵɵelementEnd()();
40
+ i0.ɵɵelementStart(16, "div", 30);
41
+ i0.ɵɵnamespaceSVG();
42
+ i0.ɵɵelementStart(17, "svg", 31);
43
+ i0.ɵɵelement(18, "line", 35);
44
+ i0.ɵɵelementEnd();
45
+ i0.ɵɵnamespaceHTML();
46
+ i0.ɵɵelementStart(19, "span");
47
+ i0.ɵɵtext(20, "Backward connection (loop)");
48
+ i0.ɵɵelementEnd()();
49
+ i0.ɵɵelementStart(21, "div", 36);
50
+ i0.ɵɵtext(22, " Colors help distinguish multiple paths from the same source step ");
51
+ i0.ɵɵelementEnd()();
52
+ } }
53
+ function FlowEditorComponent__svg_g_36__svg_g_3_Template(rf, ctx) { if (rf & 1) {
54
+ const _r5 = i0.ɵɵgetCurrentView();
55
+ i0.ɵɵnamespaceSVG();
56
+ i0.ɵɵelementStart(0, "g");
57
+ i0.ɵɵelement(1, "rect", 40);
58
+ i0.ɵɵelementStart(2, "rect", 41);
59
+ i0.ɵɵlistener("click", function FlowEditorComponent__svg_g_36__svg_g_3_Template_rect_click_2_listener($event) { i0.ɵɵrestoreView(_r5); const connection_r3 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onConnectionClick($event, connection_r3)); });
60
+ i0.ɵɵelementEnd();
61
+ i0.ɵɵelementStart(3, "text", 42);
62
+ i0.ɵɵtext(4);
63
+ i0.ɵɵelementEnd()();
64
+ } if (rf & 2) {
65
+ const connection_r3 = i0.ɵɵnextContext().$implicit;
66
+ const ctx_r3 = i0.ɵɵnextContext();
67
+ i0.ɵɵadvance();
68
+ i0.ɵɵattribute("x", ctx_r3.getConnectionMidpoint(connection_r3).x - ctx_r3.getConditionBoxWidth(connection_r3) / 2)("y", ctx_r3.getConnectionMidpoint(connection_r3).y - 15)("width", ctx_r3.getConditionBoxWidth(connection_r3))("transform", "translate(2, 2)");
69
+ i0.ɵɵadvance();
70
+ i0.ɵɵattribute("x", ctx_r3.getConnectionMidpoint(connection_r3).x - ctx_r3.getConditionBoxWidth(connection_r3) / 2)("y", ctx_r3.getConnectionMidpoint(connection_r3).y - 15)("width", ctx_r3.getConditionBoxWidth(connection_r3));
71
+ i0.ɵɵadvance();
72
+ i0.ɵɵattribute("x", ctx_r3.getConnectionMidpoint(connection_r3).x)("y", ctx_r3.getConnectionMidpoint(connection_r3).y + 4);
73
+ i0.ɵɵadvance();
74
+ i0.ɵɵtextInterpolate1(" ", ctx_r3.getConditionLabel(connection_r3), " ");
75
+ } }
76
+ function FlowEditorComponent__svg_g_36_Template(rf, ctx) { if (rf & 1) {
77
+ const _r2 = i0.ɵɵgetCurrentView();
78
+ i0.ɵɵnamespaceSVG();
79
+ i0.ɵɵelementStart(0, "g")(1, "path", 37);
80
+ i0.ɵɵlistener("click", function FlowEditorComponent__svg_g_36_Template_path_click_1_listener($event) { const connection_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onConnectionClick($event, connection_r3)); });
81
+ i0.ɵɵelementEnd();
82
+ i0.ɵɵelementStart(2, "path", 38);
83
+ i0.ɵɵlistener("click", function FlowEditorComponent__svg_g_36_Template_path_click_2_listener($event) { const connection_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onConnectionClick($event, connection_r3)); });
84
+ i0.ɵɵelementEnd();
85
+ i0.ɵɵtemplate(3, FlowEditorComponent__svg_g_36__svg_g_3_Template, 5, 10, "g", 39);
86
+ i0.ɵɵelementEnd();
87
+ } if (rf & 2) {
88
+ const connection_r3 = ctx.$implicit;
89
+ const ctx_r3 = i0.ɵɵnextContext();
90
+ i0.ɵɵadvance();
91
+ i0.ɵɵattribute("d", ctx_r3.getConnectionPath(connection_r3))("stroke", ctx_r3.getConnectionColor(connection_r3))("stroke-dasharray", ctx_r3.getConnectionDashArray(connection_r3))("marker-end", ctx_r3.getConnectionMarker(connection_r3));
92
+ i0.ɵɵadvance();
93
+ i0.ɵɵattribute("d", ctx_r3.getConnectionPath(connection_r3));
94
+ i0.ɵɵadvance();
95
+ i0.ɵɵproperty("ngIf", connection_r3.condition);
96
+ } }
97
+ function FlowEditorComponent__svg_path_37_Template(rf, ctx) { if (rf & 1) {
98
+ i0.ɵɵnamespaceSVG();
99
+ i0.ɵɵelement(0, "path", 43);
100
+ } if (rf & 2) {
101
+ const ctx_r3 = i0.ɵɵnextContext();
102
+ i0.ɵɵattribute("d", ctx_r3.getTempConnectionPath());
103
+ } }
104
+ function FlowEditorComponent_app_step_39_Template(rf, ctx) { if (rf & 1) {
105
+ const _r6 = i0.ɵɵgetCurrentView();
106
+ i0.ɵɵelementStart(0, "app-step", 44);
107
+ i0.ɵɵlistener("stepSelected", function FlowEditorComponent_app_step_39_Template_app_step_stepSelected_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.selectStep($event)); })("stepDeleted", function FlowEditorComponent_app_step_39_Template_app_step_stepDeleted_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.deleteStep($event)); })("stepUpdated", function FlowEditorComponent_app_step_39_Template_app_step_stepUpdated_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.updateStep($event)); })("socketMouseDown", function FlowEditorComponent_app_step_39_Template_app_step_socketMouseDown_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSocketMouseDown($event)); })("socketMouseEnter", function FlowEditorComponent_app_step_39_Template_app_step_socketMouseEnter_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSocketMouseEnter($event)); })("socketMouseLeave", function FlowEditorComponent_app_step_39_Template_app_step_socketMouseLeave_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onSocketMouseLeave($event)); })("mousedown", function FlowEditorComponent_app_step_39_Template_app_step_mousedown_0_listener($event) { const step_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onStepDragStart($event, step_r7)); });
108
+ i0.ɵɵelementEnd();
109
+ } if (rf & 2) {
110
+ const step_r7 = ctx.$implicit;
111
+ const ctx_r3 = i0.ɵɵnextContext();
112
+ i0.ɵɵstyleProp("left", step_r7.position[0], "px")("top", step_r7.position[1], "px")("position", "absolute");
113
+ i0.ɵɵproperty("step", step_r7)("selected", ctx_r3.selectedStepId === step_r7.id)("executing", ctx_r3.executingStepId === step_r7.id);
114
+ i0.ɵɵattribute("data-step-id", step_r7.id);
115
+ } }
116
+ function FlowEditorComponent_div_40_Template(rf, ctx) { if (rf & 1) {
117
+ const _r8 = i0.ɵɵgetCurrentView();
118
+ i0.ɵɵelementStart(0, "div", 45);
119
+ i0.ɵɵlistener("click", function FlowEditorComponent_div_40_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeConditionEditor()); });
120
+ i0.ɵɵelementStart(1, "div", 46);
121
+ i0.ɵɵlistener("click", function FlowEditorComponent_div_40_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r8); return i0.ɵɵresetView($event.stopPropagation()); });
122
+ i0.ɵɵelementStart(2, "app-simple-condition-editor", 47);
123
+ i0.ɵɵlistener("save", function FlowEditorComponent_div_40_Template_app_simple_condition_editor_save_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.saveConnectionConditions($event)); })("cancel", function FlowEditorComponent_div_40_Template_app_simple_condition_editor_cancel_2_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeConditionEditor()); });
124
+ i0.ɵɵelementEnd()()();
125
+ } if (rf & 2) {
126
+ const ctx_r3 = i0.ɵɵnextContext();
127
+ i0.ɵɵadvance(2);
128
+ i0.ɵɵproperty("connection", ctx_r3.editingConnection);
129
+ } }
130
+ function FlowEditorComponent_app_confirmation_dialog_41_Template(rf, ctx) { if (rf & 1) {
131
+ const _r9 = i0.ɵɵgetCurrentView();
132
+ i0.ɵɵelementStart(0, "app-confirmation-dialog", 48);
133
+ i0.ɵɵlistener("confirm", function FlowEditorComponent_app_confirmation_dialog_41_Template_app_confirmation_dialog_confirm_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.confirmDeleteStep()); })("cancel", function FlowEditorComponent_app_confirmation_dialog_41_Template_app_confirmation_dialog_cancel_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.cancelDeleteStep()); });
134
+ i0.ɵɵelementEnd();
135
+ } if (rf & 2) {
136
+ const ctx_r3 = i0.ɵɵnextContext();
137
+ i0.ɵɵproperty("title", "Delete Step")("message", "Are you sure you want to delete this " + ctx_r3.stepToDelete.config.name + " step? This action cannot be undone.")("confirmText", "Delete");
138
+ } }
139
+ function FlowEditorComponent_app_confirmation_dialog_42_Template(rf, ctx) { if (rf & 1) {
140
+ const _r10 = i0.ɵɵgetCurrentView();
141
+ i0.ɵɵelementStart(0, "app-confirmation-dialog", 48);
142
+ i0.ɵɵlistener("confirm", function FlowEditorComponent_app_confirmation_dialog_42_Template_app_confirmation_dialog_confirm_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.confirmDeleteConnection()); })("cancel", function FlowEditorComponent_app_confirmation_dialog_42_Template_app_confirmation_dialog_cancel_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.cancelDeleteConnection()); });
143
+ i0.ɵɵelementEnd();
144
+ } if (rf & 2) {
145
+ i0.ɵɵproperty("title", "Delete Connection")("message", "Are you sure you want to delete this connection? This action cannot be undone.")("confirmText", "Delete");
146
+ } }
147
+ export class FlowEditorComponent {
148
+ constructor(flowEditorService, flowExecutor, changeDetector) {
149
+ this.flowEditorService = flowEditorService;
150
+ this.flowExecutor = flowExecutor;
151
+ this.changeDetector = changeDetector;
152
+ this.toggleExecution = new EventEmitter();
153
+ this.stepMoved = new EventEmitter();
154
+ this.steps = [];
155
+ this.connections = [];
156
+ this.selectedStepId = null;
157
+ this.executingStepId = null;
158
+ this.showExecutionPanel = false;
159
+ this.legendCollapsed = true;
160
+ // Fixed dimensions for all steps
161
+ this.STEP_WIDTH = 320;
162
+ this.STEP_HEIGHT = 140;
163
+ this.nextStepId = 1;
164
+ this.isDragging = false;
165
+ this.dragOffset = { x: 0, y: 0 };
166
+ this.currentScale = 1;
167
+ this.canvasOffset = { x: 50, y: 50 };
168
+ // Connection creation state
169
+ this.tempConnection = null;
170
+ this.isCreatingConnection = false;
171
+ // Condition editing
172
+ this.editingConnection = null;
173
+ // Deletion confirmation
174
+ this.stepToDelete = null;
175
+ this.connectionToDelete = null;
176
+ this.currentDraggedStep = null;
177
+ this.handleMouseMove = (event) => {
178
+ if (this.isDragging && this.currentDraggedStep) {
179
+ const rect = this.reteEditor.nativeElement.getBoundingClientRect();
180
+ const mouseX = (event.clientX - rect.left - this.canvasOffset.x) / this.currentScale;
181
+ const mouseY = (event.clientY - rect.top - this.canvasOffset.y) / this.currentScale;
182
+ // Update position by subtracting the initial offset
183
+ this.currentDraggedStep.position[0] = mouseX - this.dragOffset.x;
184
+ this.currentDraggedStep.position[1] = mouseY - this.dragOffset.y;
185
+ }
186
+ };
187
+ this.handleMouseUp = () => {
188
+ if (this.isDragging && this.currentDraggedStep) {
189
+ // Emit an event that the step position has changed
190
+ this.stepMoved.emit(this.currentDraggedStep);
191
+ }
192
+ this.isDragging = false;
193
+ this.currentDraggedStep = null;
194
+ document.removeEventListener('mousemove', this.handleMouseMove);
195
+ document.removeEventListener('mouseup', this.handleMouseUp);
196
+ };
197
+ this.handleConnectionMouseMove = (event) => {
198
+ if (this.isCreatingConnection && this.tempConnection) {
199
+ const rect = this.reteEditor.nativeElement.getBoundingClientRect();
200
+ this.tempConnection.mouseX = (event.clientX - rect.left - this.canvasOffset.x) / this.currentScale;
201
+ this.tempConnection.mouseY = (event.clientY - rect.top - this.canvasOffset.y) / this.currentScale;
202
+ }
203
+ };
204
+ this.handleConnectionMouseUp = (event) => {
205
+ if (this.isCreatingConnection && this.tempConnection) {
206
+ // Check if we're over a socket
207
+ const target = event.target;
208
+ if (target.classList.contains('socket') && target._connectionTarget) {
209
+ const connectionTarget = target._connectionTarget;
210
+ const sourceStep = this.tempConnection.source;
211
+ const targetStep = connectionTarget.step;
212
+ // Create the connection
213
+ if (this.tempConnection.sourceType === 'output') {
214
+ this.createConnection(sourceStep.id, targetStep.id);
215
+ }
216
+ else {
217
+ this.createConnection(targetStep.id, sourceStep.id);
218
+ }
219
+ // Force change detection to show the new connection
220
+ this.changeDetector.detectChanges();
221
+ }
222
+ // Clean up
223
+ this.isCreatingConnection = false;
224
+ this.tempConnection = null;
225
+ document.removeEventListener('mousemove', this.handleConnectionMouseMove);
226
+ document.removeEventListener('mouseup', this.handleConnectionMouseUp);
227
+ }
228
+ };
229
+ }
230
+ ngOnInit() {
231
+ // Subscribe to current executing step to highlight it
232
+ this.flowExecutor.currentStepId.subscribe(stepId => {
233
+ this.executingStepId = stepId;
234
+ this.changeDetector.detectChanges();
235
+ });
236
+ }
237
+ ngAfterViewInit() {
238
+ this.initializeEditor();
239
+ // Load the actual data from the service instead of creating example flow
240
+ this.loadFlowData();
241
+ }
242
+ initializeEditor() {
243
+ // Setup canvas events
244
+ this.setupCanvasEvents();
245
+ }
246
+ loadFlowData() {
247
+ // Load steps and connections from the service
248
+ this.steps = this.flowEditorService.getAllSteps();
249
+ this.connections = this.flowEditorService.connections || [];
250
+ // Log the loaded data
251
+ if (this.steps.length > 0 || this.connections.length > 0) {
252
+ // Auto-arrange steps with proper spacing
253
+ this.autoArrangeSteps();
254
+ // The template will automatically render the steps and connections
255
+ // through Angular's change detection
256
+ this.changeDetector.detectChanges();
257
+ // Fit entire flow in view after DOM is ready
258
+ // Need longer delay to ensure canvas element has dimensions
259
+ setTimeout(() => {
260
+ this.fitToView();
261
+ }, 500);
262
+ }
263
+ }
264
+ centerOnStartingStep() {
265
+ // Find a starting step or the first step
266
+ const startingStep = this.steps.find(s => s.mjData?.startingStep) || this.steps[0];
267
+ if (startingStep) {
268
+ // Center the canvas on this step
269
+ const container = this.reteEditor.nativeElement;
270
+ const rect = container.getBoundingClientRect();
271
+ // Calculate offset to center the step
272
+ this.canvasOffset.x = (rect.width / 2) - (startingStep.position[0] * this.currentScale) - 120; // 120 is half step width
273
+ this.canvasOffset.y = (rect.height / 2) - (startingStep.position[1] * this.currentScale) - 60; // 60 is half step height
274
+ // Ensure we don't go too far up
275
+ this.canvasOffset.y = Math.min(this.canvasOffset.y, 50);
276
+ this.updateCanvasTransform();
277
+ }
278
+ }
279
+ createExampleFlow() {
280
+ // Create example steps with more spacing
281
+ this.createStep('prompt', [100, 200]);
282
+ this.createStep('agent', [500, 200]);
283
+ this.createStep('action', [900, 200]);
284
+ this.createStep('prompt', [1300, 100]);
285
+ this.createStep('action', [1300, 300]);
286
+ // Create connections
287
+ this.createConnection(1, 2);
288
+ this.createConnection(2, 3);
289
+ this.createConnection(3, 4);
290
+ this.createConnection(3, 5);
291
+ }
292
+ createStep(type, position) {
293
+ const config = STEP_CONFIGS[type];
294
+ const step = {
295
+ id: this.nextStepId++,
296
+ type: type,
297
+ name: config.name,
298
+ position: position,
299
+ config: config
300
+ };
301
+ this.steps.push(step);
302
+ // console.log('Step created:', step);
303
+ // console.log('Total steps:', this.steps.length);
304
+ // console.log('Current steps array:', this.steps);
305
+ // Update the service with all steps
306
+ this.flowEditorService.setAllSteps(this.steps);
307
+ // Force Angular change detection
308
+ this.changeDetector.detectChanges();
309
+ // Log the DOM elements after change detection
310
+ setTimeout(() => {
311
+ // Step elements have been created
312
+ }, 0);
313
+ return step;
314
+ }
315
+ createConnection(sourceId, targetId) {
316
+ const connection = {
317
+ id: `${sourceId}-${targetId}`,
318
+ source: sourceId,
319
+ target: targetId,
320
+ sourceOutput: 'out',
321
+ targetInput: 'in',
322
+ condition: {
323
+ expression: 'success',
324
+ label: 'Success'
325
+ }
326
+ };
327
+ this.connections.push(connection);
328
+ // console.log('Connection created:', connection);
329
+ // console.log('Total connections:', this.connections.length);
330
+ this.changeDetector.detectChanges();
331
+ }
332
+ setupCanvasEvents() {
333
+ const container = this.reteEditor.nativeElement;
334
+ // Click on empty canvas to deselect
335
+ container.addEventListener('click', (e) => {
336
+ // Only deselect if clicking on the canvas itself or the SVG
337
+ const target = e.target;
338
+ if (target === container || target.tagName === 'svg' || target.classList.contains('canvas-wrapper')) {
339
+ this.selectedStepId = null;
340
+ this.flowEditorService.selectNode(null);
341
+ }
342
+ });
343
+ // Setup drop handling on the container itself
344
+ container.addEventListener('dragover', (e) => {
345
+ e.preventDefault();
346
+ e.dataTransfer.dropEffect = 'copy';
347
+ container.classList.add('drag-over');
348
+ });
349
+ container.addEventListener('dragleave', (e) => {
350
+ const rect = container.getBoundingClientRect();
351
+ if (e.clientX < rect.left || e.clientX > rect.right ||
352
+ e.clientY < rect.top || e.clientY > rect.bottom) {
353
+ container.classList.remove('drag-over');
354
+ }
355
+ });
356
+ container.addEventListener('drop', (e) => {
357
+ e.preventDefault();
358
+ e.stopPropagation();
359
+ container.classList.remove('drag-over');
360
+ const plainData = e.dataTransfer?.getData('text/plain') || '';
361
+ const stepType = e.dataTransfer?.getData('stepType');
362
+ // Handle drag and drop of steps
363
+ // Check if this is a step drop
364
+ if (plainData.startsWith('step:')) {
365
+ // Extract the step type from the plain data
366
+ const extractedType = plainData.replace('step:', '');
367
+ const rect = container.getBoundingClientRect();
368
+ let x = (e.clientX - rect.left - this.canvasOffset.x) / this.currentScale;
369
+ let y = (e.clientY - rect.top - this.canvasOffset.y) / this.currentScale;
370
+ // Snap to grid for better alignment (optional)
371
+ const gridSize = 50;
372
+ x = Math.round(x / gridSize) * gridSize;
373
+ y = Math.round(y / gridSize) * gridSize;
374
+ // Create step at calculated position
375
+ this.createStep(extractedType, [x, y]);
376
+ }
377
+ });
378
+ // Pan canvas
379
+ let isPanning = false;
380
+ let startX = 0;
381
+ let startY = 0;
382
+ container.addEventListener('mousedown', (e) => {
383
+ const target = e.target;
384
+ // Only pan if clicking on empty canvas area
385
+ if (target.classList.contains('canvas-wrapper') || target.classList.contains('steps-container') || target.classList.contains('rete-container')) {
386
+ isPanning = true;
387
+ startX = e.clientX - this.canvasOffset.x;
388
+ startY = e.clientY - this.canvasOffset.y;
389
+ container.style.cursor = 'grabbing';
390
+ }
391
+ });
392
+ document.addEventListener('mousemove', (e) => {
393
+ if (isPanning) {
394
+ this.canvasOffset.x = e.clientX - startX;
395
+ this.canvasOffset.y = e.clientY - startY;
396
+ this.updateCanvasTransform();
397
+ }
398
+ });
399
+ document.addEventListener('mouseup', () => {
400
+ isPanning = false;
401
+ container.style.cursor = 'grab';
402
+ });
403
+ // Zoom
404
+ container.addEventListener('wheel', (e) => {
405
+ e.preventDefault();
406
+ const delta = e.deltaY > 0 ? 0.9 : 1.1;
407
+ this.currentScale = Math.max(0.1, Math.min(2, this.currentScale * delta));
408
+ this.updateCanvasTransform();
409
+ });
410
+ }
411
+ updateCanvasTransform() {
412
+ const canvasWrapper = this.reteEditor.nativeElement.querySelector('.canvas-wrapper');
413
+ if (canvasWrapper) {
414
+ canvasWrapper.style.transform = `translate(${this.canvasOffset.x}px, ${this.canvasOffset.y}px) scale(${this.currentScale})`;
415
+ }
416
+ }
417
+ selectStep(step) {
418
+ // Toggle selection if clicking the same step
419
+ if (this.selectedStepId === step.id) {
420
+ this.selectedStepId = null;
421
+ this.flowEditorService.selectNode(null);
422
+ }
423
+ else {
424
+ this.selectedStepId = step.id;
425
+ this.flowEditorService.selectNode(step);
426
+ }
427
+ }
428
+ deleteStep(step) {
429
+ this.stepToDelete = step;
430
+ }
431
+ confirmDeleteStep() {
432
+ if (!this.stepToDelete)
433
+ return;
434
+ const stepId = this.stepToDelete.id;
435
+ this.steps = this.steps.filter(s => s.id !== stepId);
436
+ this.connections = this.connections.filter(c => c.source !== stepId && c.target !== stepId);
437
+ // Update the service with all steps
438
+ this.flowEditorService.setAllSteps(this.steps);
439
+ if (this.selectedStepId === stepId) {
440
+ this.selectedStepId = null;
441
+ this.flowEditorService.selectNode(null);
442
+ }
443
+ this.stepToDelete = null;
444
+ }
445
+ cancelDeleteStep() {
446
+ this.stepToDelete = null;
447
+ }
448
+ deleteConnection(connection) {
449
+ this.connectionToDelete = connection;
450
+ }
451
+ confirmDeleteConnection() {
452
+ if (!this.connectionToDelete)
453
+ return;
454
+ this.connections = this.connections.filter(c => c.id !== this.connectionToDelete.id);
455
+ this.connectionToDelete = null;
456
+ }
457
+ cancelDeleteConnection() {
458
+ this.connectionToDelete = null;
459
+ }
460
+ onConnectionClick(event, connection) {
461
+ event.stopPropagation();
462
+ // Check if Shift key is held for delete
463
+ if (event.shiftKey) {
464
+ this.deleteConnection(connection);
465
+ }
466
+ else {
467
+ // Open condition editor
468
+ this.editingConnection = { ...connection };
469
+ }
470
+ }
471
+ getConnectionMidpoint(connection) {
472
+ const source = this.steps.find(s => s.id === connection.source);
473
+ const target = this.steps.find(s => s.id === connection.target);
474
+ if (!source || !target) {
475
+ return { x: 0, y: 0 };
476
+ }
477
+ // Use fixed dimensions for all steps
478
+ const sourceDimensions = { width: this.STEP_WIDTH, height: this.STEP_HEIGHT };
479
+ const targetDimensions = { width: this.STEP_WIDTH, height: this.STEP_HEIGHT };
480
+ const x1 = source.position[0] + sourceDimensions.width; // Output socket center at edge
481
+ const y1 = source.position[1] + (sourceDimensions.height / 2);
482
+ const x2 = target.position[0]; // Input socket center at edge
483
+ const y2 = target.position[1] + (targetDimensions.height / 2);
484
+ // For backward connections, adjust midpoint to be on the curve
485
+ if (this.isBackwardConnection(connection)) {
486
+ const midX = (x1 + x2) / 2;
487
+ const midY = (y1 + y2) / 2 + 50; // Offset down to match the curve
488
+ return { x: midX, y: midY };
489
+ }
490
+ // Return the midpoint of the connection
491
+ const midpoint = {
492
+ x: (x1 + x2) / 2,
493
+ y: (y1 + y2) / 2
494
+ };
495
+ return midpoint;
496
+ }
497
+ saveConnectionConditions(updatedConnection) {
498
+ const index = this.connections.findIndex(c => c.id === updatedConnection.id);
499
+ if (index !== -1) {
500
+ this.connections[index] = updatedConnection;
501
+ }
502
+ this.closeConditionEditor();
503
+ }
504
+ closeConditionEditor() {
505
+ this.editingConnection = null;
506
+ }
507
+ getConditionPreview(connection) {
508
+ if (!connection.condition) {
509
+ return 'Always';
510
+ }
511
+ return connection.condition.expression;
512
+ }
513
+ getConditionLabel(connection) {
514
+ if (!connection.condition) {
515
+ return 'Always';
516
+ }
517
+ const label = connection.condition.label || connection.condition.expression;
518
+ // Truncate if too long
519
+ const maxLength = 12;
520
+ if (label.length > maxLength) {
521
+ return label.substring(0, maxLength - 2) + '...';
522
+ }
523
+ return label;
524
+ }
525
+ getConditionBoxWidth(connection) {
526
+ const label = this.getConditionLabel(connection);
527
+ // Estimate width based on character count (approx 7px per character + padding)
528
+ const estimatedWidth = Math.max(80, Math.min(140, label.length * 7 + 30));
529
+ return estimatedWidth;
530
+ }
531
+ getConnectionColor(connection) {
532
+ // Check if this is a backward connection
533
+ if (this.isBackwardConnection(connection)) {
534
+ return '#EF4444'; // Red for backward connections
535
+ }
536
+ // Define a palette of distinct colors for forward connections
537
+ const colorPalette = [
538
+ '#3B82F6', // Blue
539
+ '#10B981', // Green
540
+ '#F59E0B', // Amber
541
+ '#8B5CF6', // Purple
542
+ '#EC4899', // Pink
543
+ '#14B8A6', // Teal
544
+ '#F97316', // Orange
545
+ '#06B6D4', // Cyan
546
+ ];
547
+ // Get all forward connections from the same source
548
+ const sourceConnections = this.connections
549
+ .filter(c => c.source === connection.source && !this.isBackwardConnection(c))
550
+ .sort((a, b) => (a.id || '').localeCompare(b.id || '')); // Sort by ID for consistency
551
+ // Find the index of this connection among connections from the same source
552
+ const connectionIndex = sourceConnections.findIndex(c => c.id === connection.id);
553
+ // Use modulo to cycle through colors if there are more connections than colors
554
+ return colorPalette[connectionIndex % colorPalette.length];
555
+ }
556
+ isBackwardConnection(connection) {
557
+ // A connection is backward if the target step is positioned to the left of the source step
558
+ const sourceStep = this.steps.find(s => s.id === connection.source);
559
+ const targetStep = this.steps.find(s => s.id === connection.target);
560
+ if (!sourceStep || !targetStep)
561
+ return false;
562
+ // Check if target is to the left of source (backward in the flow)
563
+ return targetStep.position[0] < sourceStep.position[0];
564
+ }
565
+ getConnectionDashArray(connection) {
566
+ // Return dash array for backward connections, solid for forward
567
+ return this.isBackwardConnection(connection) ? '10,5' : '';
568
+ }
569
+ getConnectionMarker(connection) {
570
+ // Add arrow marker for backward connections
571
+ return this.isBackwardConnection(connection) ? 'url(#backward-arrow)' : '';
572
+ }
573
+ updateStep(step) {
574
+ // Step updated, trigger any necessary updates
575
+ this.flowEditorService.updateNode(step);
576
+ }
577
+ onStepDragStart(event, step) {
578
+ event.preventDefault();
579
+ this.isDragging = true;
580
+ this.currentDraggedStep = step;
581
+ // Calculate the offset between the mouse position and the step position
582
+ // We need to account for the canvas transform (scale and offset)
583
+ const rect = this.reteEditor.nativeElement.getBoundingClientRect();
584
+ const mouseX = (event.clientX - rect.left - this.canvasOffset.x) / this.currentScale;
585
+ const mouseY = (event.clientY - rect.top - this.canvasOffset.y) / this.currentScale;
586
+ // Store the offset between mouse and step position
587
+ this.dragOffset.x = mouseX - step.position[0];
588
+ this.dragOffset.y = mouseY - step.position[1];
589
+ // Add document level mouse move and up listeners
590
+ document.addEventListener('mousemove', this.handleMouseMove);
591
+ document.addEventListener('mouseup', this.handleMouseUp);
592
+ }
593
+ onStepDragEnd() {
594
+ this.handleMouseUp();
595
+ }
596
+ getConnectionPath(connection) {
597
+ const source = this.steps.find(s => s.id === connection.source);
598
+ const target = this.steps.find(s => s.id === connection.target);
599
+ if (!source || !target) {
600
+ return '';
601
+ }
602
+ // Use fixed dimensions for all steps
603
+ const sourceDimensions = { width: this.STEP_WIDTH, height: this.STEP_HEIGHT };
604
+ const targetDimensions = { width: this.STEP_WIDTH, height: this.STEP_HEIGHT };
605
+ // Socket positions - sockets are at 50% of total step height
606
+ // The sockets are 16px diameter circles centered at edges
607
+ // Output socket center is at right edge (the socket extends beyond with right: -8px)
608
+ // Input socket center is at left edge (the socket extends beyond with left: -8px)
609
+ // Socket positioning: sockets are 16px diameter circles
610
+ // With right: -8px, the socket center is at the step edge (not beyond)
611
+ // With left: -8px, the socket center is at the step edge (not beyond)
612
+ const x1 = source.position[0] + sourceDimensions.width; // Output socket center at right edge
613
+ const y1 = source.position[1] + (sourceDimensions.height / 2); // 50% of step height
614
+ const x2 = target.position[0]; // Input socket center at left edge
615
+ const y2 = target.position[1] + (targetDimensions.height / 2); // 50% of step height
616
+ // Check if this is a backward connection
617
+ if (this.isBackwardConnection(connection)) {
618
+ // For backward connections, create a more pronounced curve that goes below
619
+ const dx = x2 - x1;
620
+ // Make the curve go below the steps for better visibility
621
+ const curveOffset = 100; // How far below to curve
622
+ const midX = (x1 + x2) / 2;
623
+ const midY = Math.max(y1, y2) + curveOffset;
624
+ // Create a path that curves below with a smoother quadratic curve
625
+ const cp1x = x1 + 50;
626
+ const cp1y = y1 + curveOffset / 2;
627
+ const cp2x = x2 - 50;
628
+ const cp2y = y2 + curveOffset / 2;
629
+ return `M ${x1} ${y1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${x2} ${y2}`;
630
+ }
631
+ // For forward connections, use the standard bezier curve
632
+ const dx = x2 - x1;
633
+ const controlPointOffset = Math.max(50, Math.min(150, Math.abs(dx) * 0.4));
634
+ const path = `M ${x1} ${y1} C ${x1 + controlPointOffset} ${y1}, ${x2 - controlPointOffset} ${y2}, ${x2} ${y2}`;
635
+ return path;
636
+ }
637
+ onZoomIn() {
638
+ this.currentScale = Math.min(2, this.currentScale * 1.2);
639
+ this.updateCanvasTransform();
640
+ }
641
+ onZoomOut() {
642
+ this.currentScale = Math.max(0.1, this.currentScale * 0.8);
643
+ this.updateCanvasTransform();
644
+ }
645
+ onResetView() {
646
+ // Fit entire flow in view
647
+ this.fitToView();
648
+ }
649
+ onAutoArrange() {
650
+ // Recalculate optimal positions for all steps
651
+ this.autoArrangeSteps();
652
+ // Fit all steps in view
653
+ this.fitToView();
654
+ }
655
+ autoArrangeSteps() {
656
+ if (this.steps.length === 0)
657
+ return;
658
+ // Spacing adjusted for larger step dimensions and condition text
659
+ // Step width is 320px, so we need spacing > 320px to avoid overlap
660
+ const horizontalSpacing = 500; // Balanced spacing - enough room for connections without being too spread out
661
+ const verticalSpacing = 200; // Good vertical separation
662
+ // Build adjacency map for BFS traversal
663
+ const adjacencyMap = new Map();
664
+ const incomingEdges = new Map();
665
+ this.steps.forEach(step => {
666
+ adjacencyMap.set(step.id, []);
667
+ incomingEdges.set(step.id, 0);
668
+ });
669
+ this.connections.forEach(conn => {
670
+ const sourceSteps = adjacencyMap.get(conn.source) || [];
671
+ sourceSteps.push(conn.target);
672
+ adjacencyMap.set(conn.source, sourceSteps);
673
+ const targetCount = incomingEdges.get(conn.target) || 0;
674
+ incomingEdges.set(conn.target, targetCount + 1);
675
+ });
676
+ // Find starting nodes (no incoming edges or marked as starting)
677
+ const startingSteps = this.steps.filter(step => incomingEdges.get(step.id) === 0 || step.mjData?.startingStep);
678
+ // Use BFS to assign levels
679
+ const levels = new Map();
680
+ const queue = [...startingSteps];
681
+ startingSteps.forEach(step => levels.set(step.id, 0));
682
+ while (queue.length > 0) {
683
+ const current = queue.shift();
684
+ const currentLevel = levels.get(current.id) || 0;
685
+ const neighbors = adjacencyMap.get(current.id) || [];
686
+ neighbors.forEach(neighborId => {
687
+ if (!levels.has(neighborId)) {
688
+ levels.set(neighborId, currentLevel + 1);
689
+ const neighborStep = this.steps.find(s => s.id === neighborId);
690
+ if (neighborStep)
691
+ queue.push(neighborStep);
692
+ }
693
+ });
694
+ }
695
+ // Group steps by level
696
+ const stepsByLevel = new Map();
697
+ this.steps.forEach(step => {
698
+ const level = levels.get(step.id) || 0;
699
+ if (!stepsByLevel.has(level)) {
700
+ stepsByLevel.set(level, []);
701
+ }
702
+ stepsByLevel.get(level).push(step);
703
+ });
704
+ // Calculate positions
705
+ const startX = 100;
706
+ const startY = 50;
707
+ stepsByLevel.forEach((stepsInLevel, level) => {
708
+ const x = startX + (level * horizontalSpacing);
709
+ const totalHeight = (stepsInLevel.length - 1) * verticalSpacing;
710
+ const startYForLevel = startY + Math.max(0, (400 - totalHeight) / 2);
711
+ stepsInLevel.forEach((step, index) => {
712
+ const y = startYForLevel + (index * verticalSpacing);
713
+ step.position = [x, y];
714
+ });
715
+ });
716
+ }
717
+ fitToView() {
718
+ if (this.steps.length === 0) {
719
+ // If no steps, just reset to default view
720
+ this.currentScale = 1;
721
+ this.canvasOffset = { x: 0, y: 0 };
722
+ this.updateCanvasTransform();
723
+ return;
724
+ }
725
+ // Get viewport dimensions
726
+ const viewportWidth = this.reteEditor.nativeElement.clientWidth;
727
+ const viewportHeight = this.reteEditor.nativeElement.clientHeight;
728
+ // Check if DOM is ready - if not, retry
729
+ if (viewportWidth === 0 || viewportHeight === 0) {
730
+ setTimeout(() => this.fitToView(), 200);
731
+ return;
732
+ }
733
+ // Find bounds of all steps
734
+ let minX = Infinity, minY = Infinity;
735
+ let maxX = -Infinity, maxY = -Infinity;
736
+ this.steps.forEach(step => {
737
+ minX = Math.min(minX, step.position[0]);
738
+ minY = Math.min(minY, step.position[1]);
739
+ maxX = Math.max(maxX, step.position[0] + this.STEP_WIDTH);
740
+ maxY = Math.max(maxY, step.position[1] + this.STEP_HEIGHT);
741
+ });
742
+ // Calculate content dimensions
743
+ const contentWidth = maxX - minX;
744
+ const contentHeight = maxY - minY;
745
+ // Calculate scale to fit content with padding
746
+ const padding = 100;
747
+ const scaleX = (viewportWidth - padding * 2) / contentWidth;
748
+ const scaleY = (viewportHeight - padding * 2) / contentHeight;
749
+ // Use the smaller scale to ensure everything fits
750
+ // But don't zoom out too much or zoom in too much
751
+ const idealScale = Math.min(scaleX, scaleY);
752
+ this.currentScale = Math.max(0.3, Math.min(idealScale, 1.0));
753
+ // Calculate the center point of the content
754
+ const contentCenterX = minX + contentWidth / 2;
755
+ const contentCenterY = minY + contentHeight / 2;
756
+ // Calculate the center point of the viewport
757
+ const viewportCenterX = viewportWidth / 2;
758
+ const viewportCenterY = viewportHeight / 2;
759
+ // Calculate offset to center the content
760
+ this.canvasOffset.x = viewportCenterX - (contentCenterX * this.currentScale);
761
+ this.canvasOffset.y = viewportCenterY - (contentCenterY * this.currentScale);
762
+ this.updateCanvasTransform();
763
+ }
764
+ toggleExecutionPanel() {
765
+ this.showExecutionPanel = !this.showExecutionPanel;
766
+ this.toggleExecution.emit();
767
+ }
768
+ runFlow() {
769
+ // Run the flow with current steps and connections
770
+ if (this.steps.length === 0) {
771
+ alert('Please add some steps to the flow first!');
772
+ return;
773
+ }
774
+ this.flowExecutor.executeFlow(this.steps, this.connections);
775
+ }
776
+ ngOnDestroy() {
777
+ // Cleanup
778
+ document.removeEventListener('mousemove', this.handleConnectionMouseMove);
779
+ document.removeEventListener('mouseup', this.handleConnectionMouseUp);
780
+ }
781
+ // Socket event handlers
782
+ onSocketMouseDown(event) {
783
+ event.event.stopPropagation();
784
+ event.event.preventDefault();
785
+ this.isCreatingConnection = true;
786
+ const rect = this.reteEditor.nativeElement.getBoundingClientRect();
787
+ this.tempConnection = {
788
+ source: event.step,
789
+ sourceType: event.type,
790
+ mouseX: (event.event.clientX - rect.left - this.canvasOffset.x) / this.currentScale,
791
+ mouseY: (event.event.clientY - rect.top - this.canvasOffset.y) / this.currentScale
792
+ };
793
+ // Add document-level listeners for connection creation
794
+ document.addEventListener('mousemove', this.handleConnectionMouseMove);
795
+ document.addEventListener('mouseup', this.handleConnectionMouseUp);
796
+ }
797
+ onSocketMouseEnter(event) {
798
+ if (this.isCreatingConnection && this.tempConnection) {
799
+ const targetStep = event.step;
800
+ const sourceStep = this.tempConnection.source;
801
+ // Check if we can create a connection
802
+ if (this.canCreateConnection(sourceStep, targetStep, this.tempConnection.sourceType, event.type)) {
803
+ // Highlight the socket
804
+ const socket = event.event.target;
805
+ socket.classList.add('can-connect');
806
+ // Store the potential target for the mouseup event
807
+ socket._connectionTarget = {
808
+ step: targetStep,
809
+ type: event.type
810
+ };
811
+ }
812
+ }
813
+ }
814
+ onSocketMouseLeave(event) {
815
+ const socket = event.target;
816
+ socket.classList.remove('can-connect');
817
+ delete socket._connectionTarget;
818
+ }
819
+ canCreateConnection(source, target, sourceType, targetType) {
820
+ // Don't connect to self
821
+ if (source.id === target.id)
822
+ return false;
823
+ // Only connect output to input
824
+ if (sourceType === 'output' && targetType === 'input') {
825
+ // Check if connection already exists
826
+ return !this.connections.some(c => c.source === source.id && c.target === target.id);
827
+ }
828
+ return false;
829
+ }
830
+ getTempConnectionPath() {
831
+ if (!this.tempConnection)
832
+ return '';
833
+ const source = this.tempConnection.source;
834
+ const sourceType = this.tempConnection.sourceType;
835
+ let x1, y1;
836
+ const socketY = source.position[1] + (this.STEP_HEIGHT / 2);
837
+ if (sourceType === 'output') {
838
+ x1 = source.position[0] + this.STEP_WIDTH; // Output socket center at edge
839
+ y1 = socketY;
840
+ }
841
+ else {
842
+ x1 = source.position[0]; // Input socket center at edge
843
+ y1 = socketY;
844
+ }
845
+ const x2 = this.tempConnection.mouseX;
846
+ const y2 = this.tempConnection.mouseY;
847
+ // Create a smooth bezier curve
848
+ const dx = x2 - x1;
849
+ const controlPointOffset = Math.max(50, Math.min(150, Math.abs(dx) * 0.4));
850
+ if (sourceType === 'output') {
851
+ return `M ${x1} ${y1} C ${x1 + controlPointOffset} ${y1}, ${x2 - controlPointOffset} ${y2}, ${x2} ${y2}`;
852
+ }
853
+ else {
854
+ return `M ${x1} ${y1} C ${x1 - controlPointOffset} ${y1}, ${x2 + controlPointOffset} ${y2}, ${x2} ${y2}`;
855
+ }
856
+ }
857
+ static { this.ɵfac = function FlowEditorComponent_Factory(t) { return new (t || FlowEditorComponent)(i0.ɵɵdirectiveInject(i1.FlowEditorService), i0.ɵɵdirectiveInject(i2.FlowExecutorService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
858
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FlowEditorComponent, selectors: [["app-flow-editor"]], viewQuery: function FlowEditorComponent_Query(rf, ctx) { if (rf & 1) {
859
+ i0.ɵɵviewQuery(_c0, 7);
860
+ } if (rf & 2) {
861
+ let _t;
862
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reteEditor = _t.first);
863
+ } }, outputs: { toggleExecution: "toggleExecution", stepMoved: "stepMoved" }, standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 43, vars: 14, consts: [["reteEditor", ""], [1, "flow-editor"], [1, "canvas-header"], [1, "legend-panel"], [1, "legend-header", 3, "click"], [1, "fas"], ["class", "legend-content", 4, "ngIf"], [1, "canvas-controls"], ["title", "Zoom In", 1, "control-button", 3, "click"], [1, "fas", "fa-search-plus"], ["title", "Zoom Out", 1, "control-button", 3, "click"], [1, "fas", "fa-search-minus"], ["title", "Reset View", 1, "control-button", 3, "click"], [1, "fas", "fa-sync-alt"], ["title", "Auto Arrange Steps", 1, "control-button", 3, "click"], [1, "fas", "fa-project-diagram"], ["title", "Toggle Execution Panel", 1, "control-button", 3, "click"], [1, "fas", "fa-play-circle"], [1, "rete-container"], [1, "canvas-wrapper"], [1, "connections-layer"], ["id", "backward-arrow", "markerWidth", "10", "markerHeight", "10", "refX", "9", "refY", "3", "orient", "auto", "markerUnits", "strokeWidth"], ["d", "M0,0 L0,6 L9,3 z", "fill", "#EF4444"], [4, "ngFor", "ngForOf"], ["class", "temp-connection-path", "fill", "none", "stroke", "#28a745", "stroke-width", "3", "stroke-dasharray", "5,5", 4, "ngIf"], [1, "steps-container"], [3, "step", "selected", "executing", "left", "top", "position", "stepSelected", "stepDeleted", "stepUpdated", "socketMouseDown", "socketMouseEnter", "socketMouseLeave", "mousedown", 4, "ngFor", "ngForOf"], ["class", "modal-backdrop", 3, "click", 4, "ngIf"], [3, "title", "message", "confirmText", "confirm", "cancel", 4, "ngIf"], [1, "legend-content"], [1, "legend-item"], ["width", "30", "height", "2"], ["x1", "0", "y1", "1", "x2", "30", "y2", "1", "stroke", "#3B82F6", "stroke-width", "2"], ["x1", "0", "y1", "1", "x2", "30", "y2", "1", "stroke", "#10B981", "stroke-width", "2"], ["x1", "0", "y1", "1", "x2", "30", "y2", "1", "stroke", "#F59E0B", "stroke-width", "2"], ["x1", "0", "y1", "1", "x2", "30", "y2", "1", "stroke", "#EF4444", "stroke-width", "2"], [1, "legend-note"], ["fill", "none", "stroke-width", "3", 1, "connection-path", 2, "cursor", "pointer", "pointer-events", "stroke", 3, "click"], ["fill", "none", "stroke", "transparent", "stroke-width", "20", 1, "connection-hover", 2, "cursor", "pointer", "pointer-events", "stroke", 3, "click"], [4, "ngIf"], ["height", "30", "rx", "15", "fill", "rgba(0,0,0,0.1)", 2, "pointer-events", "none"], ["height", "30", "rx", "15", "fill", "#FFFFFF", "stroke", "#0076B6", "stroke-width", "2", 2, "cursor", "pointer", 3, "click"], ["text-anchor", "middle", "font-size", "12", "font-weight", "600", "fill", "#0076B6", 2, "cursor", "pointer", "pointer-events", "none"], ["fill", "none", "stroke", "#28a745", "stroke-width", "3", "stroke-dasharray", "5,5", 1, "temp-connection-path"], [3, "stepSelected", "stepDeleted", "stepUpdated", "socketMouseDown", "socketMouseEnter", "socketMouseLeave", "mousedown", "step", "selected", "executing"], [1, "modal-backdrop", 3, "click"], [1, "modal-container", 3, "click"], [3, "save", "cancel", "connection"], [3, "confirm", "cancel", "title", "message", "confirmText"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
864
+ const _r1 = i0.ɵɵgetCurrentView();
865
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "div", 4);
866
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.legendCollapsed = !ctx.legendCollapsed); });
867
+ i0.ɵɵelement(4, "i", 5);
868
+ i0.ɵɵelementStart(5, "span");
869
+ i0.ɵɵtext(6, "Connection Legend");
870
+ i0.ɵɵelementEnd()();
871
+ i0.ɵɵtemplate(7, FlowEditorComponent_div_7_Template, 23, 0, "div", 6);
872
+ i0.ɵɵelementEnd();
873
+ i0.ɵɵelementStart(8, "div", 7)(9, "button", 8);
874
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onZoomIn()); });
875
+ i0.ɵɵelement(10, "i", 9);
876
+ i0.ɵɵelementStart(11, "span");
877
+ i0.ɵɵtext(12, "Zoom In");
878
+ i0.ɵɵelementEnd()();
879
+ i0.ɵɵelementStart(13, "button", 10);
880
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onZoomOut()); });
881
+ i0.ɵɵelement(14, "i", 11);
882
+ i0.ɵɵelementStart(15, "span");
883
+ i0.ɵɵtext(16, "Zoom Out");
884
+ i0.ɵɵelementEnd()();
885
+ i0.ɵɵelementStart(17, "button", 12);
886
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onResetView()); });
887
+ i0.ɵɵelement(18, "i", 13);
888
+ i0.ɵɵelementStart(19, "span");
889
+ i0.ɵɵtext(20, "Reset View");
890
+ i0.ɵɵelementEnd()();
891
+ i0.ɵɵelementStart(21, "button", 14);
892
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAutoArrange()); });
893
+ i0.ɵɵelement(22, "i", 15);
894
+ i0.ɵɵelementStart(23, "span");
895
+ i0.ɵɵtext(24, "Auto Arrange");
896
+ i0.ɵɵelementEnd()();
897
+ i0.ɵɵelementStart(25, "button", 16);
898
+ i0.ɵɵlistener("click", function FlowEditorComponent_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleExecutionPanel()); });
899
+ i0.ɵɵelement(26, "i", 17);
900
+ i0.ɵɵelementStart(27, "span");
901
+ i0.ɵɵtext(28);
902
+ i0.ɵɵelementEnd()()()();
903
+ i0.ɵɵelementStart(29, "div", 18, 0)(31, "div", 19);
904
+ i0.ɵɵnamespaceSVG();
905
+ i0.ɵɵelementStart(32, "svg", 20)(33, "defs")(34, "marker", 21);
906
+ i0.ɵɵelement(35, "path", 22);
907
+ i0.ɵɵelementEnd()();
908
+ i0.ɵɵtemplate(36, FlowEditorComponent__svg_g_36_Template, 4, 6, "g", 23)(37, FlowEditorComponent__svg_path_37_Template, 1, 1, "path", 24);
909
+ i0.ɵɵelementEnd();
910
+ i0.ɵɵnamespaceHTML();
911
+ i0.ɵɵelementStart(38, "div", 25);
912
+ i0.ɵɵtemplate(39, FlowEditorComponent_app_step_39_Template, 1, 10, "app-step", 26);
913
+ i0.ɵɵelementEnd()()();
914
+ i0.ɵɵtemplate(40, FlowEditorComponent_div_40_Template, 3, 1, "div", 27)(41, FlowEditorComponent_app_confirmation_dialog_41_Template, 1, 3, "app-confirmation-dialog", 28)(42, FlowEditorComponent_app_confirmation_dialog_42_Template, 1, 3, "app-confirmation-dialog", 28);
915
+ i0.ɵɵelementEnd();
916
+ } if (rf & 2) {
917
+ i0.ɵɵadvance(2);
918
+ i0.ɵɵclassProp("collapsed", ctx.legendCollapsed);
919
+ i0.ɵɵadvance(2);
920
+ i0.ɵɵclassProp("fa-chevron-down", !ctx.legendCollapsed)("fa-chevron-right", ctx.legendCollapsed);
921
+ i0.ɵɵadvance(3);
922
+ i0.ɵɵproperty("ngIf", !ctx.legendCollapsed);
923
+ i0.ɵɵadvance(21);
924
+ i0.ɵɵtextInterpolate1("", ctx.showExecutionPanel ? "Hide" : "Show", " Execution");
925
+ i0.ɵɵadvance(8);
926
+ i0.ɵɵproperty("ngForOf", ctx.connections);
927
+ i0.ɵɵadvance();
928
+ i0.ɵɵproperty("ngIf", ctx.tempConnection);
929
+ i0.ɵɵadvance(2);
930
+ i0.ɵɵproperty("ngForOf", ctx.steps);
931
+ i0.ɵɵadvance();
932
+ i0.ɵɵproperty("ngIf", ctx.editingConnection);
933
+ i0.ɵɵadvance();
934
+ i0.ɵɵproperty("ngIf", ctx.stepToDelete);
935
+ i0.ɵɵadvance();
936
+ i0.ɵɵproperty("ngIf", ctx.connectionToDelete);
937
+ } }, dependencies: [CommonModule, i3.NgForOf, i3.NgIf, StepComponent, SimpleConditionEditorComponent, ConfirmationDialogComponent], styles: [".flow-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.canvas-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem 1rem;\n background-color: var(--white-color);\n border-bottom: 1px solid var(--gray-700);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.canvas-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n.rete-container[_ngcontent-%COMP%] {\n flex: 1;\n position: relative;\n overflow: hidden;\n cursor: grab;\n background-color: var(--gray-600);\n \n &.grabbing {\n cursor: grabbing;\n }\n \n &.drag-over {\n background-color: rgba(0, 118, 182, 0.05);\n outline: 2px dashed var(--mj-blue);\n outline-offset: -2px;\n }\n}\n\n.canvas-wrapper[_ngcontent-%COMP%] {\n position: relative;\n width: 5000px; // Large area for workflow\n height: 3000px; // Large height for vertical workflows\n min-height: 600px;\n transform-origin: 0 0;\n}\n\n.connections-layer[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 5000px; // Match canvas-wrapper width\n height: 3000px; // Match canvas-wrapper height\n pointer-events: none;\n z-index: 1;\n overflow: visible;\n \n path {\n pointer-events: auto;\n }\n \n text, rect, circle {\n pointer-events: auto;\n }\n \n .temp-connection-path {\n animation: dash 1s linear infinite;\n }\n \n .connection-path {\n transition: stroke 0.2s ease;\n }\n \n .connection-hover:hover + .connection-path,\n .connection-path:hover {\n stroke: #dc3545 !important;\n }\n \n @keyframes dash {\n to {\n stroke-dashoffset: -10;\n }\n }\n}\n\n.steps-container[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 2;\n pointer-events: none;\n \n app-step {\n pointer-events: auto;\n }\n}\n\n.control-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border: 1px solid var(--light-blue);\n background: var(--white-color);\n border-radius: 0.5rem;\n cursor: pointer;\n transition: all var(--transition-time);\n font-size: 0.875rem;\n color: var(--mj-blue);\n \n &:hover {\n background: var(--light-blue);\n color: var(--navy);\n transform: translateY(-2px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 1rem;\n }\n}\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-container[_ngcontent-%COMP%] {\n position: relative;\n animation: _ngcontent-%COMP%_modalSlideIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_modalSlideIn {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.legend-panel[_ngcontent-%COMP%] {\n position: relative;\n background: var(--white-color);\n border: 1px solid var(--gray-700);\n border-radius: var(--border-radius);\n box-shadow: var(--shadow);\n min-width: 150px;\n transition: all 0.3s ease;\n margin-right: auto;\n margin-left: 1rem;\n \n &.collapsed {\n min-width: auto;\n .legend-header {\n border-bottom: none;\n border-radius: var(--border-radius);\n }\n }\n \n .legend-header {\n padding: 0.75rem;\n background: var(--gray-600);\n border-bottom: 1px solid var(--gray-700);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n border-radius: calc(var(--border-radius) - 1px) calc(var(--border-radius) - 1px) 0 0;\n \n &:hover {\n background: var(--gray-650);\n }\n \n i {\n font-size: 0.75rem;\n transition: transform 0.2s;\n }\n \n span {\n font-weight: 600;\n font-size: 0.875rem;\n }\n }\n \n .legend-content {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 0.25rem;\n background: var(--white-color);\n border: 1px solid var(--gray-700);\n border-radius: var(--border-radius);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 1rem;\n min-width: 280px;\n z-index: 1000;\n \n .legend-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.75rem;\n \n svg {\n flex-shrink: 0;\n }\n \n span {\n font-size: 0.813rem;\n color: var(--gray-800);\n }\n }\n \n .legend-note {\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--gray-700);\n font-size: 0.75rem;\n color: var(--gray-750);\n font-style: italic;\n }\n }\n}"] }); }
938
+ }
939
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlowEditorComponent, [{
940
+ type: Component,
941
+ args: [{ selector: 'app-flow-editor', standalone: true, imports: [CommonModule, StepComponent, SimpleConditionEditorComponent, ConfirmationDialogComponent], template: "<div class=\"flow-editor\">\n <div class=\"canvas-header\">\n <!-- Connection Legend -->\n <div class=\"legend-panel\" [class.collapsed]=\"legendCollapsed\">\n <div class=\"legend-header\" (click)=\"legendCollapsed = !legendCollapsed\">\n <i class=\"fas\" [class.fa-chevron-down]=\"!legendCollapsed\" [class.fa-chevron-right]=\"legendCollapsed\"></i>\n <span>Connection Legend</span>\n </div>\n <div class=\"legend-content\" *ngIf=\"!legendCollapsed\">\n <div class=\"legend-item\">\n <svg width=\"30\" height=\"2\">\n <line x1=\"0\" y1=\"1\" x2=\"30\" y2=\"1\" stroke=\"#3B82F6\" stroke-width=\"2\"/>\n </svg>\n <span>First output from a step</span>\n </div>\n <div class=\"legend-item\">\n <svg width=\"30\" height=\"2\">\n <line x1=\"0\" y1=\"1\" x2=\"30\" y2=\"1\" stroke=\"#10B981\" stroke-width=\"2\"/>\n </svg>\n <span>Second output from a step</span>\n </div>\n <div class=\"legend-item\">\n <svg width=\"30\" height=\"2\">\n <line x1=\"0\" y1=\"1\" x2=\"30\" y2=\"1\" stroke=\"#F59E0B\" stroke-width=\"2\"/>\n </svg>\n <span>Third output from a step</span>\n </div>\n <div class=\"legend-item\">\n <svg width=\"30\" height=\"2\">\n <line x1=\"0\" y1=\"1\" x2=\"30\" y2=\"1\" stroke=\"#EF4444\" stroke-width=\"2\"/>\n </svg>\n <span>Backward connection (loop)</span>\n </div>\n <div class=\"legend-note\">\n Colors help distinguish multiple paths from the same source step\n </div>\n </div>\n </div>\n \n <div class=\"canvas-controls\">\n <button \n class=\"control-button\" \n (click)=\"onZoomIn()\"\n title=\"Zoom In\">\n <i class=\"fas fa-search-plus\"></i>\n <span>Zoom In</span>\n </button>\n <button \n class=\"control-button\" \n (click)=\"onZoomOut()\"\n title=\"Zoom Out\">\n <i class=\"fas fa-search-minus\"></i>\n <span>Zoom Out</span>\n </button>\n <button \n class=\"control-button\" \n (click)=\"onResetView()\"\n title=\"Reset View\">\n <i class=\"fas fa-sync-alt\"></i>\n <span>Reset View</span>\n </button>\n <button \n class=\"control-button\" \n (click)=\"onAutoArrange()\"\n title=\"Auto Arrange Steps\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Auto Arrange</span>\n </button>\n <button \n class=\"control-button\" \n (click)=\"toggleExecutionPanel()\"\n title=\"Toggle Execution Panel\">\n <i class=\"fas fa-play-circle\"></i>\n <span>{{ showExecutionPanel ? 'Hide' : 'Show' }} Execution</span>\n </button>\n </div>\n </div>\n \n <div #reteEditor class=\"rete-container\">\n <div class=\"canvas-wrapper\">\n <svg class=\"connections-layer\">\n <!-- Define arrow markers for backward connections -->\n <defs>\n <marker id=\"backward-arrow\" markerWidth=\"10\" markerHeight=\"10\" \n refX=\"9\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">\n <path d=\"M0,0 L0,6 L9,3 z\" fill=\"#EF4444\" />\n </marker>\n </defs>\n <g *ngFor=\"let connection of connections\">\n <path [attr.d]=\"getConnectionPath(connection)\" \n class=\"connection-path\"\n fill=\"none\"\n [attr.stroke]=\"getConnectionColor(connection)\"\n [attr.stroke-dasharray]=\"getConnectionDashArray(connection)\"\n [attr.marker-end]=\"getConnectionMarker(connection)\"\n stroke-width=\"3\"\n style=\"cursor: pointer; pointer-events: stroke\"\n (click)=\"onConnectionClick($event, connection)\"/>\n <path [attr.d]=\"getConnectionPath(connection)\" \n class=\"connection-hover\"\n fill=\"none\"\n stroke=\"transparent\"\n stroke-width=\"20\"\n style=\"cursor: pointer; pointer-events: stroke\"\n (click)=\"onConnectionClick($event, connection)\"/>\n \n <!-- Condition indicator -->\n <g *ngIf=\"connection.condition\">\n <!-- Shadow for condition box -->\n <rect\n [attr.x]=\"getConnectionMidpoint(connection).x - getConditionBoxWidth(connection)/2\"\n [attr.y]=\"getConnectionMidpoint(connection).y - 15\"\n [attr.width]=\"getConditionBoxWidth(connection)\"\n height=\"30\"\n rx=\"15\"\n fill=\"rgba(0,0,0,0.1)\"\n [attr.transform]=\"'translate(2, 2)'\"\n style=\"pointer-events: none\"/>\n <rect\n [attr.x]=\"getConnectionMidpoint(connection).x - getConditionBoxWidth(connection)/2\"\n [attr.y]=\"getConnectionMidpoint(connection).y - 15\"\n [attr.width]=\"getConditionBoxWidth(connection)\"\n height=\"30\"\n rx=\"15\"\n fill=\"#FFFFFF\"\n stroke=\"#0076B6\"\n stroke-width=\"2\"\n style=\"cursor: pointer\"\n (click)=\"onConnectionClick($event, connection)\"/>\n <text \n [attr.x]=\"getConnectionMidpoint(connection).x\"\n [attr.y]=\"getConnectionMidpoint(connection).y + 4\"\n text-anchor=\"middle\"\n font-size=\"12\"\n font-weight=\"600\"\n fill=\"#0076B6\"\n style=\"cursor: pointer; pointer-events: none;\">\n {{ getConditionLabel(connection) }}\n </text>\n </g>\n \n </g>\n <path *ngIf=\"tempConnection\" \n [attr.d]=\"getTempConnectionPath()\" \n class=\"temp-connection-path\"\n fill=\"none\"\n stroke=\"#28a745\"\n stroke-width=\"3\"\n stroke-dasharray=\"5,5\"/>\n </svg>\n \n <div class=\"steps-container\">\n <app-step \n *ngFor=\"let step of steps\"\n [step]=\"step\"\n [selected]=\"selectedStepId === step.id\"\n [executing]=\"executingStepId === step.id\"\n [style.left.px]=\"step.position[0]\"\n [style.top.px]=\"step.position[1]\"\n [style.position]=\"'absolute'\"\n [attr.data-step-id]=\"step.id\"\n (stepSelected)=\"selectStep($event)\"\n (stepDeleted)=\"deleteStep($event)\"\n (stepUpdated)=\"updateStep($event)\"\n (socketMouseDown)=\"onSocketMouseDown($event)\"\n (socketMouseEnter)=\"onSocketMouseEnter($event)\"\n (socketMouseLeave)=\"onSocketMouseLeave($event)\"\n (mousedown)=\"onStepDragStart($event, step)\">\n </app-step>\n </div>\n </div>\n </div>\n \n <!-- Condition Editor Modal -->\n <div class=\"modal-backdrop\" *ngIf=\"editingConnection\" (click)=\"closeConditionEditor()\">\n <div class=\"modal-container\" (click)=\"$event.stopPropagation()\">\n <app-simple-condition-editor\n [connection]=\"editingConnection\"\n (save)=\"saveConnectionConditions($event)\"\n (cancel)=\"closeConditionEditor()\">\n </app-simple-condition-editor>\n </div>\n </div>\n \n <!-- Delete Step Confirmation Dialog -->\n <app-confirmation-dialog\n *ngIf=\"stepToDelete\"\n [title]=\"'Delete Step'\"\n [message]=\"'Are you sure you want to delete this ' + stepToDelete.config.name + ' step? This action cannot be undone.'\"\n [confirmText]=\"'Delete'\"\n (confirm)=\"confirmDeleteStep()\"\n (cancel)=\"cancelDeleteStep()\">\n </app-confirmation-dialog>\n \n <!-- Delete Connection Confirmation Dialog -->\n <app-confirmation-dialog\n *ngIf=\"connectionToDelete\"\n [title]=\"'Delete Connection'\"\n [message]=\"'Are you sure you want to delete this connection? This action cannot be undone.'\"\n [confirmText]=\"'Delete'\"\n (confirm)=\"confirmDeleteConnection()\"\n (cancel)=\"cancelDeleteConnection()\">\n </app-confirmation-dialog>\n</div>", styles: [".flow-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n.canvas-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem 1rem;\n background-color: var(--white-color);\n border-bottom: 1px solid var(--gray-700);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.canvas-controls {\n display: flex;\n gap: 0.5rem;\n}\n\n.rete-container {\n flex: 1;\n position: relative;\n overflow: hidden;\n cursor: grab;\n background-color: var(--gray-600);\n \n &.grabbing {\n cursor: grabbing;\n }\n \n &.drag-over {\n background-color: rgba(0, 118, 182, 0.05);\n outline: 2px dashed var(--mj-blue);\n outline-offset: -2px;\n }\n}\n\n.canvas-wrapper {\n position: relative;\n width: 5000px; // Large area for workflow\n height: 3000px; // Large height for vertical workflows\n min-height: 600px;\n transform-origin: 0 0;\n}\n\n.connections-layer {\n position: absolute;\n top: 0;\n left: 0;\n width: 5000px; // Match canvas-wrapper width\n height: 3000px; // Match canvas-wrapper height\n pointer-events: none;\n z-index: 1;\n overflow: visible;\n \n path {\n pointer-events: auto;\n }\n \n text, rect, circle {\n pointer-events: auto;\n }\n \n .temp-connection-path {\n animation: dash 1s linear infinite;\n }\n \n .connection-path {\n transition: stroke 0.2s ease;\n }\n \n .connection-hover:hover + .connection-path,\n .connection-path:hover {\n stroke: #dc3545 !important;\n }\n \n @keyframes dash {\n to {\n stroke-dashoffset: -10;\n }\n }\n}\n\n.steps-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 2;\n pointer-events: none;\n \n app-step {\n pointer-events: auto;\n }\n}\n\n.control-button {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n border: 1px solid var(--light-blue);\n background: var(--white-color);\n border-radius: 0.5rem;\n cursor: pointer;\n transition: all var(--transition-time);\n font-size: 0.875rem;\n color: var(--mj-blue);\n \n &:hover {\n background: var(--light-blue);\n color: var(--navy);\n transform: translateY(-2px);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 1rem;\n }\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-container {\n position: relative;\n animation: modalSlideIn 0.3s ease;\n}\n\n@keyframes modalSlideIn {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.legend-panel {\n position: relative;\n background: var(--white-color);\n border: 1px solid var(--gray-700);\n border-radius: var(--border-radius);\n box-shadow: var(--shadow);\n min-width: 150px;\n transition: all 0.3s ease;\n margin-right: auto;\n margin-left: 1rem;\n \n &.collapsed {\n min-width: auto;\n .legend-header {\n border-bottom: none;\n border-radius: var(--border-radius);\n }\n }\n \n .legend-header {\n padding: 0.75rem;\n background: var(--gray-600);\n border-bottom: 1px solid var(--gray-700);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n border-radius: calc(var(--border-radius) - 1px) calc(var(--border-radius) - 1px) 0 0;\n \n &:hover {\n background: var(--gray-650);\n }\n \n i {\n font-size: 0.75rem;\n transition: transform 0.2s;\n }\n \n span {\n font-weight: 600;\n font-size: 0.875rem;\n }\n }\n \n .legend-content {\n position: absolute;\n top: 100%;\n left: 0;\n margin-top: 0.25rem;\n background: var(--white-color);\n border: 1px solid var(--gray-700);\n border-radius: var(--border-radius);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 1rem;\n min-width: 280px;\n z-index: 1000;\n \n .legend-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.75rem;\n \n svg {\n flex-shrink: 0;\n }\n \n span {\n font-size: 0.813rem;\n color: var(--gray-800);\n }\n }\n \n .legend-note {\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--gray-700);\n font-size: 0.75rem;\n color: var(--gray-750);\n font-style: italic;\n }\n }\n}\n\n\n"] }]
942
+ }], () => [{ type: i1.FlowEditorService }, { type: i2.FlowExecutorService }, { type: i0.ChangeDetectorRef }], { reteEditor: [{
943
+ type: ViewChild,
944
+ args: ['reteEditor', { static: true }]
945
+ }], toggleExecution: [{
946
+ type: Output
947
+ }], stepMoved: [{
948
+ type: Output
949
+ }] }); })();
950
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FlowEditorComponent, { className: "FlowEditorComponent", filePath: "src/lib/custom/AIAgents/FlowAgentType/flow-editor-integration/components/flow-editor/flow-editor.component.ts", lineNumber: 18 }); })();
951
+ //# sourceMappingURL=flow-editor.component.js.map