@memberjunction/ng-dashboards 5.8.0 → 5.9.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 (77) hide show
  1. package/dist/AI/components/models/model-management.component.d.ts +2 -0
  2. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  3. package/dist/AI/components/models/model-management.component.js +44 -2
  4. package/dist/AI/components/models/model-management.component.js.map +1 -1
  5. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  6. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +5 -2
  7. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  8. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  9. package/dist/Home/home-dashboard.component.js +10 -7
  10. package/dist/Home/home-dashboard.component.js.map +1 -1
  11. package/dist/Integration/components/activity/activity.component.d.ts +96 -0
  12. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -0
  13. package/dist/Integration/components/activity/activity.component.js +961 -0
  14. package/dist/Integration/components/activity/activity.component.js.map +1 -0
  15. package/dist/Integration/components/connections/connections.component.d.ts +194 -0
  16. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -0
  17. package/dist/Integration/components/connections/connections.component.js +2368 -0
  18. package/dist/Integration/components/connections/connections.component.js.map +1 -0
  19. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts +211 -13
  20. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  21. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +2093 -187
  22. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  23. package/dist/Integration/components/overview/overview.component.d.ts +60 -0
  24. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -0
  25. package/dist/Integration/components/overview/overview.component.js +628 -0
  26. package/dist/Integration/components/overview/overview.component.js.map +1 -0
  27. package/dist/Integration/components/pipelines/pipelines.component.d.ts +203 -0
  28. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -0
  29. package/dist/Integration/components/pipelines/pipelines.component.js +2057 -0
  30. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -0
  31. package/dist/Integration/components/schedules/schedules.component.d.ts +110 -0
  32. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -0
  33. package/dist/Integration/components/schedules/schedules.component.js +842 -0
  34. package/dist/Integration/components/schedules/schedules.component.js.map +1 -0
  35. package/dist/Integration/components/visual-editor/visual-editor.component.d.ts +141 -0
  36. package/dist/Integration/components/visual-editor/visual-editor.component.d.ts.map +1 -0
  37. package/dist/Integration/components/visual-editor/visual-editor.component.js +1538 -0
  38. package/dist/Integration/components/visual-editor/visual-editor.component.js.map +1 -0
  39. package/dist/Integration/components/widgets/run-history-panel.component.js +3 -2
  40. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
  41. package/dist/Integration/index.d.ts +5 -3
  42. package/dist/Integration/index.d.ts.map +1 -1
  43. package/dist/Integration/index.js +11 -7
  44. package/dist/Integration/index.js.map +1 -1
  45. package/dist/Integration/integration.module.d.ts +20 -16
  46. package/dist/Integration/integration.module.d.ts.map +1 -1
  47. package/dist/Integration/integration.module.js +40 -21
  48. package/dist/Integration/integration.module.js.map +1 -1
  49. package/dist/Integration/services/integration-data.service.d.ts +117 -3
  50. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  51. package/dist/Integration/services/integration-data.service.js +415 -10
  52. package/dist/Integration/services/integration-data.service.js.map +1 -1
  53. package/dist/QueryBrowser/query-browser-resource.component.d.ts +27 -4
  54. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  55. package/dist/QueryBrowser/query-browser-resource.component.js +338 -144
  56. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  57. package/dist/__tests__/mapping-validation.test.d.ts +2 -0
  58. package/dist/__tests__/mapping-validation.test.d.ts.map +1 -0
  59. package/dist/__tests__/mapping-validation.test.js +170 -0
  60. package/dist/__tests__/mapping-validation.test.js.map +1 -0
  61. package/package.json +40 -38
  62. package/dist/Integration/components/connection-studio/connection-studio.component.d.ts +0 -81
  63. package/dist/Integration/components/connection-studio/connection-studio.component.d.ts.map +0 -1
  64. package/dist/Integration/components/connection-studio/connection-studio.component.js +0 -960
  65. package/dist/Integration/components/connection-studio/connection-studio.component.js.map +0 -1
  66. package/dist/Integration/components/control-tower/control-tower.component.d.ts +0 -43
  67. package/dist/Integration/components/control-tower/control-tower.component.d.ts.map +0 -1
  68. package/dist/Integration/components/control-tower/control-tower.component.js +0 -446
  69. package/dist/Integration/components/control-tower/control-tower.component.js.map +0 -1
  70. package/dist/Integration/components/sync-activity/sync-activity.component.d.ts +0 -65
  71. package/dist/Integration/components/sync-activity/sync-activity.component.d.ts.map +0 -1
  72. package/dist/Integration/components/sync-activity/sync-activity.component.js +0 -671
  73. package/dist/Integration/components/sync-activity/sync-activity.component.js.map +0 -1
  74. package/dist/__tests__/connection-studio.test.d.ts +0 -2
  75. package/dist/__tests__/connection-studio.test.d.ts.map +0 -1
  76. package/dist/__tests__/connection-studio.test.js +0 -186
  77. package/dist/__tests__/connection-studio.test.js.map +0 -1
@@ -0,0 +1,1538 @@
1
+ import { ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
2
+ import { IntegrationEngineBase } from '@memberjunction/integration-engine-base';
3
+ import { IntegrationDataService } from '../../services/integration-data.service';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ import * as i2 from "@angular/forms";
7
+ const _forTrack0 = ($index, $item) => $item.Name;
8
+ const _forTrack1 = ($index, $item) => $item.SourceFieldName + "-" + $item.DestFieldName;
9
+ const _forTrack2 = ($index, $item) => $item.Value;
10
+ function VisualFieldEditorComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
11
+ const _r1 = i0.ɵɵgetCurrentView();
12
+ i0.ɵɵelementStart(0, "label", 27)(1, "input", 28);
13
+ i0.ɵɵlistener("change", function VisualFieldEditorComponent_Conditional_12_Template_input_change_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnToggleEditorSyncEnabled($event)); });
14
+ i0.ɵɵelementEnd();
15
+ i0.ɵɵelement(2, "span", 29);
16
+ i0.ɵɵelementEnd();
17
+ i0.ɵɵelementStart(3, "span", 30);
18
+ i0.ɵɵtext(4);
19
+ i0.ɵɵelementEnd();
20
+ } if (rf & 2) {
21
+ const ctx_r1 = i0.ɵɵnextContext();
22
+ i0.ɵɵproperty("title", ctx_r1.EntityMap.SyncEnabled ? "Sync enabled" : "Sync disabled");
23
+ i0.ɵɵadvance();
24
+ i0.ɵɵproperty("checked", ctx_r1.EntityMap.SyncEnabled);
25
+ i0.ɵɵadvance(3);
26
+ i0.ɵɵtextInterpolate(ctx_r1.EntityMap.SyncEnabled ? "Sync On" : "Sync Off");
27
+ } }
28
+ function VisualFieldEditorComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
29
+ i0.ɵɵelement(0, "i", 31);
30
+ i0.ɵɵtext(1, " Saving... ");
31
+ } }
32
+ function VisualFieldEditorComponent_Conditional_41_Template(rf, ctx) { if (rf & 1) {
33
+ i0.ɵɵelement(0, "i", 32);
34
+ i0.ɵɵtext(1, " Save ");
35
+ } }
36
+ function VisualFieldEditorComponent_Conditional_42_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelementStart(0, "span", 22);
38
+ i0.ɵɵelement(1, "i", 33);
39
+ i0.ɵɵtext(2, " Saved ");
40
+ i0.ɵɵelementEnd();
41
+ } }
42
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "div", 38);
44
+ i0.ɵɵelement(1, "i", 31);
45
+ i0.ɵɵtext(2, " Loading... ");
46
+ i0.ɵɵelementEnd();
47
+ } }
48
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
49
+ i0.ɵɵelementStart(0, "div", 39);
50
+ i0.ɵɵtext(1, "No source data available");
51
+ i0.ɵɵelementEnd();
52
+ } }
53
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_5_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵelementStart(0, "th");
55
+ i0.ɵɵtext(1);
56
+ i0.ɵɵelementEnd();
57
+ } if (rf & 2) {
58
+ const col_r4 = ctx.$implicit;
59
+ i0.ɵɵadvance();
60
+ i0.ɵɵtextInterpolate(col_r4);
61
+ } }
62
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_8_For_2_Template(rf, ctx) { if (rf & 1) {
63
+ i0.ɵɵelementStart(0, "td", 42);
64
+ i0.ɵɵtext(1);
65
+ i0.ɵɵelementEnd();
66
+ } if (rf & 2) {
67
+ const col_r5 = ctx.$implicit;
68
+ const row_r6 = i0.ɵɵnextContext().$implicit;
69
+ i0.ɵɵproperty("title", (row_r6[col_r5] == null ? null : row_r6[col_r5].toString()) ?? "");
70
+ i0.ɵɵadvance();
71
+ i0.ɵɵtextInterpolate(row_r6[col_r5] ?? "");
72
+ } }
73
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_8_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵelementStart(0, "tr");
75
+ i0.ɵɵrepeaterCreate(1, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_8_For_2_Template, 2, 2, "td", 42, i0.ɵɵrepeaterTrackByIdentity);
76
+ i0.ɵɵelementEnd();
77
+ } if (rf & 2) {
78
+ const ctx_r1 = i0.ɵɵnextContext(4);
79
+ i0.ɵɵadvance();
80
+ i0.ɵɵrepeater(ctx_r1.PreviewSourceColumns);
81
+ } }
82
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
83
+ i0.ɵɵelementStart(0, "div", 40)(1, "table", 41)(2, "thead")(3, "tr");
84
+ i0.ɵɵrepeaterCreate(4, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_5_Template, 2, 1, "th", null, i0.ɵɵrepeaterTrackByIdentity);
85
+ i0.ɵɵelementEnd()();
86
+ i0.ɵɵelementStart(6, "tbody");
87
+ i0.ɵɵrepeaterCreate(7, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_For_8_Template, 3, 0, "tr", null, i0.ɵɵrepeaterTrackByIndex);
88
+ i0.ɵɵelementEnd()()();
89
+ } if (rf & 2) {
90
+ const ctx_r1 = i0.ɵɵnextContext(3);
91
+ i0.ɵɵadvance(4);
92
+ i0.ɵɵrepeater(ctx_r1.PreviewSourceColumns);
93
+ i0.ɵɵadvance(3);
94
+ i0.ɵɵrepeater(ctx_r1.PreviewSourceRows);
95
+ } }
96
+ function VisualFieldEditorComponent_Conditional_43_Conditional_1_Template(rf, ctx) { if (rf & 1) {
97
+ const _r3 = i0.ɵɵgetCurrentView();
98
+ i0.ɵɵelementStart(0, "div", 34)(1, "div", 35);
99
+ i0.ɵɵelement(2, "i", 15);
100
+ i0.ɵɵelementStart(3, "span");
101
+ i0.ɵɵtext(4);
102
+ i0.ɵɵelementEnd();
103
+ i0.ɵɵelementStart(5, "button", 36);
104
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_43_Conditional_1_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ShowSourcePreview = false); });
105
+ i0.ɵɵelement(6, "i", 37);
106
+ i0.ɵɵelementEnd()();
107
+ i0.ɵɵconditionalCreate(7, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_7_Template, 3, 0, "div", 38)(8, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_8_Template, 2, 0, "div", 39)(9, VisualFieldEditorComponent_Conditional_43_Conditional_1_Conditional_9_Template, 9, 0, "div", 40);
108
+ i0.ɵɵelementEnd();
109
+ } if (rf & 2) {
110
+ const ctx_r1 = i0.ɵɵnextContext(2);
111
+ i0.ɵɵadvance(4);
112
+ i0.ɵɵtextInterpolate1("Source Preview: ", (ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.ExternalObjectLabel) ?? (ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.ExternalObjectName));
113
+ i0.ɵɵadvance(3);
114
+ i0.ɵɵconditional(ctx_r1.PreviewSourceLoading ? 7 : ctx_r1.PreviewSourceRows.length === 0 ? 8 : 9);
115
+ } }
116
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
117
+ i0.ɵɵelementStart(0, "div", 38);
118
+ i0.ɵɵelement(1, "i", 31);
119
+ i0.ɵɵtext(2, " Loading... ");
120
+ i0.ɵɵelementEnd();
121
+ } }
122
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
123
+ i0.ɵɵelementStart(0, "div", 39);
124
+ i0.ɵɵtext(1, "No destination data available");
125
+ i0.ɵɵelementEnd();
126
+ } }
127
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_5_Template(rf, ctx) { if (rf & 1) {
128
+ i0.ɵɵelementStart(0, "th");
129
+ i0.ɵɵtext(1);
130
+ i0.ɵɵelementEnd();
131
+ } if (rf & 2) {
132
+ const col_r8 = ctx.$implicit;
133
+ i0.ɵɵadvance();
134
+ i0.ɵɵtextInterpolate(col_r8);
135
+ } }
136
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_8_For_2_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵelementStart(0, "td", 42);
138
+ i0.ɵɵtext(1);
139
+ i0.ɵɵelementEnd();
140
+ } if (rf & 2) {
141
+ const col_r9 = ctx.$implicit;
142
+ const row_r10 = i0.ɵɵnextContext().$implicit;
143
+ i0.ɵɵproperty("title", (row_r10[col_r9] == null ? null : row_r10[col_r9].toString()) ?? "");
144
+ i0.ɵɵadvance();
145
+ i0.ɵɵtextInterpolate(row_r10[col_r9] ?? "");
146
+ } }
147
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_8_Template(rf, ctx) { if (rf & 1) {
148
+ i0.ɵɵelementStart(0, "tr");
149
+ i0.ɵɵrepeaterCreate(1, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_8_For_2_Template, 2, 2, "td", 42, i0.ɵɵrepeaterTrackByIdentity);
150
+ i0.ɵɵelementEnd();
151
+ } if (rf & 2) {
152
+ const ctx_r1 = i0.ɵɵnextContext(4);
153
+ i0.ɵɵadvance();
154
+ i0.ɵɵrepeater(ctx_r1.PreviewDestColumns);
155
+ } }
156
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
157
+ i0.ɵɵelementStart(0, "div", 40)(1, "table", 41)(2, "thead")(3, "tr");
158
+ i0.ɵɵrepeaterCreate(4, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_5_Template, 2, 1, "th", null, i0.ɵɵrepeaterTrackByIdentity);
159
+ i0.ɵɵelementEnd()();
160
+ i0.ɵɵelementStart(6, "tbody");
161
+ i0.ɵɵrepeaterCreate(7, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_For_8_Template, 3, 0, "tr", null, i0.ɵɵrepeaterTrackByIndex);
162
+ i0.ɵɵelementEnd()()();
163
+ } if (rf & 2) {
164
+ const ctx_r1 = i0.ɵɵnextContext(3);
165
+ i0.ɵɵadvance(4);
166
+ i0.ɵɵrepeater(ctx_r1.PreviewDestColumns);
167
+ i0.ɵɵadvance(3);
168
+ i0.ɵɵrepeater(ctx_r1.PreviewDestRows);
169
+ } }
170
+ function VisualFieldEditorComponent_Conditional_43_Conditional_2_Template(rf, ctx) { if (rf & 1) {
171
+ const _r7 = i0.ɵɵgetCurrentView();
172
+ i0.ɵɵelementStart(0, "div", 34)(1, "div", 35);
173
+ i0.ɵɵelement(2, "i", 17);
174
+ i0.ɵɵelementStart(3, "span");
175
+ i0.ɵɵtext(4);
176
+ i0.ɵɵelementEnd();
177
+ i0.ɵɵelementStart(5, "button", 36);
178
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_43_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ShowDestPreview = false); });
179
+ i0.ɵɵelement(6, "i", 37);
180
+ i0.ɵɵelementEnd()();
181
+ i0.ɵɵconditionalCreate(7, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_7_Template, 3, 0, "div", 38)(8, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_8_Template, 2, 0, "div", 39)(9, VisualFieldEditorComponent_Conditional_43_Conditional_2_Conditional_9_Template, 9, 0, "div", 40);
182
+ i0.ɵɵelementEnd();
183
+ } if (rf & 2) {
184
+ const ctx_r1 = i0.ɵɵnextContext(2);
185
+ i0.ɵɵadvance(4);
186
+ i0.ɵɵtextInterpolate1("Dest Preview: ", ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.Entity);
187
+ i0.ɵɵadvance(3);
188
+ i0.ɵɵconditional(ctx_r1.PreviewDestLoading ? 7 : ctx_r1.PreviewDestRows.length === 0 ? 8 : 9);
189
+ } }
190
+ function VisualFieldEditorComponent_Conditional_43_Template(rf, ctx) { if (rf & 1) {
191
+ i0.ɵɵelementStart(0, "div", 23);
192
+ i0.ɵɵconditionalCreate(1, VisualFieldEditorComponent_Conditional_43_Conditional_1_Template, 10, 2, "div", 34);
193
+ i0.ɵɵconditionalCreate(2, VisualFieldEditorComponent_Conditional_43_Conditional_2_Template, 10, 2, "div", 34);
194
+ i0.ɵɵelementEnd();
195
+ } if (rf & 2) {
196
+ const ctx_r1 = i0.ɵɵnextContext();
197
+ i0.ɵɵadvance();
198
+ i0.ɵɵconditional(ctx_r1.ShowSourcePreview ? 1 : -1);
199
+ i0.ɵɵadvance();
200
+ i0.ɵɵconditional(ctx_r1.ShowDestPreview ? 2 : -1);
201
+ } }
202
+ function VisualFieldEditorComponent_Conditional_44_Template(rf, ctx) { if (rf & 1) {
203
+ const _r11 = i0.ɵɵgetCurrentView();
204
+ i0.ɵɵelementStart(0, "div", 24);
205
+ i0.ɵɵelement(1, "i", 43);
206
+ i0.ɵɵtext(2, " Click a destination field to map from ");
207
+ i0.ɵɵelementStart(3, "strong");
208
+ i0.ɵɵtext(4);
209
+ i0.ɵɵelementEnd();
210
+ i0.ɵɵelementStart(5, "button", 44);
211
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_44_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelConnect()); });
212
+ i0.ɵɵtext(6, "Cancel");
213
+ i0.ɵɵelementEnd()();
214
+ } if (rf & 2) {
215
+ const ctx_r1 = i0.ɵɵnextContext();
216
+ i0.ɵɵadvance(4);
217
+ i0.ɵɵtextInterpolate(ctx_r1.ConnectingFromSource);
218
+ } }
219
+ function VisualFieldEditorComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
220
+ i0.ɵɵelementStart(0, "div", 26);
221
+ i0.ɵɵelement(1, "i", 31);
222
+ i0.ɵɵelementStart(2, "span");
223
+ i0.ɵɵtext(3, "Loading field mappings...");
224
+ i0.ɵɵelementEnd()();
225
+ } }
226
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Conditional_6_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵelementStart(0, "span", 78);
228
+ i0.ɵɵtext(1, "PK");
229
+ i0.ɵɵelementEnd();
230
+ } }
231
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Conditional_7_Template(rf, ctx) { if (rf & 1) {
232
+ i0.ɵɵelementStart(0, "span", 79);
233
+ i0.ɵɵtext(1, "*");
234
+ i0.ɵɵelementEnd();
235
+ } }
236
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Template(rf, ctx) { if (rf & 1) {
237
+ const _r14 = i0.ɵɵgetCurrentView();
238
+ i0.ɵɵelementStart(0, "div", 74);
239
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Template_div_click_0_listener($event) { const sf_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.OnEditorSourceClick(sf_r15.Name); return i0.ɵɵresetView($event.stopPropagation()); });
240
+ i0.ɵɵelementStart(1, "span", 75);
241
+ i0.ɵɵtext(2);
242
+ i0.ɵɵelementEnd();
243
+ i0.ɵɵelementStart(3, "span", 76);
244
+ i0.ɵɵtext(4);
245
+ i0.ɵɵelementEnd();
246
+ i0.ɵɵelementStart(5, "span", 77);
247
+ i0.ɵɵconditionalCreate(6, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Conditional_6_Template, 2, 0, "span", 78);
248
+ i0.ɵɵconditionalCreate(7, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Conditional_7_Template, 2, 0, "span", 79);
249
+ i0.ɵɵelementEnd()();
250
+ } if (rf & 2) {
251
+ const sf_r15 = ctx.$implicit;
252
+ const ctx_r1 = i0.ɵɵnextContext(3);
253
+ i0.ɵɵstyleProp("height", ctx_r1.FIELD_HEIGHT, "px");
254
+ i0.ɵɵclassProp("mapped", ctx_r1.IsSourceFieldMapped(sf_r15.Name))("unmapped", !ctx_r1.IsSourceFieldMapped(sf_r15.Name))("connecting", ctx_r1.ConnectingFromSource === sf_r15.Name);
255
+ i0.ɵɵadvance();
256
+ i0.ɵɵproperty("title", sf_r15.Name);
257
+ i0.ɵɵadvance();
258
+ i0.ɵɵtextInterpolate(sf_r15.Label || sf_r15.Name);
259
+ i0.ɵɵadvance(2);
260
+ i0.ɵɵtextInterpolate(sf_r15.Type);
261
+ i0.ɵɵadvance(2);
262
+ i0.ɵɵconditional(sf_r15.IsPrimaryKey ? 6 : -1);
263
+ i0.ɵɵadvance();
264
+ i0.ɵɵconditional(sf_r15.IsRequired ? 7 : -1);
265
+ } }
266
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_Conditional_27_Template(rf, ctx) { if (rf & 1) {
267
+ i0.ɵɵelementStart(0, "div", 70);
268
+ i0.ɵɵtext(1, "No source fields found");
269
+ i0.ɵɵelementEnd();
270
+ } }
271
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_30_Template(rf, ctx) { if (rf & 1) {
272
+ const _r16 = i0.ɵɵgetCurrentView();
273
+ i0.ɵɵnamespaceSVG();
274
+ i0.ɵɵelementStart(0, "path", 80);
275
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_30_Template_path_click_0_listener($event) { const ɵ$index_296_r17 = i0.ɵɵrestoreView(_r16).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectConnection(ɵ$index_296_r17, $event)); });
276
+ i0.ɵɵelementEnd();
277
+ i0.ɵɵelementStart(1, "foreignObject", 81);
278
+ i0.ɵɵnamespaceHTML();
279
+ i0.ɵɵelementStart(2, "div", 82);
280
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_30_Template_div_click_2_listener($event) { const ɵ$index_296_r17 = i0.ɵɵrestoreView(_r16).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectConnection(ɵ$index_296_r17, $event)); });
281
+ i0.ɵɵelement(3, "i");
282
+ i0.ɵɵelementEnd()();
283
+ } if (rf & 2) {
284
+ const conn_r18 = ctx.$implicit;
285
+ const ɵ$index_296_r17 = ctx.$index;
286
+ const ctx_r1 = i0.ɵɵnextContext(3);
287
+ i0.ɵɵclassMap("ve-conn-line " + ctx_r1.GetConnectionLineClass(conn_r18));
288
+ i0.ɵɵclassProp("selected", ctx_r1.SelectedConnectionIdx === ɵ$index_296_r17);
289
+ i0.ɵɵattribute("d", ctx_r1.GetConnectionPath(conn_r18));
290
+ i0.ɵɵadvance();
291
+ i0.ɵɵattribute("x", ctx_r1.SVG_WIDTH / 2 - 14)("y", ctx_r1.GetConnectionMidY(conn_r18) - 14);
292
+ i0.ɵɵadvance();
293
+ i0.ɵɵclassMap("ve-conn-badge " + ctx_r1.GetConnectionBadgeClass(conn_r18));
294
+ i0.ɵɵclassProp("selected", ctx_r1.SelectedConnectionIdx === ɵ$index_296_r17);
295
+ i0.ɵɵadvance();
296
+ i0.ɵɵclassMap(ctx_r1.GetConnectionDirectionIcon(conn_r18));
297
+ } }
298
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_33_Conditional_6_Template(rf, ctx) { if (rf & 1) {
299
+ i0.ɵɵelementStart(0, "span", 79);
300
+ i0.ɵɵtext(1, "*");
301
+ i0.ɵɵelementEnd();
302
+ } }
303
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_33_Template(rf, ctx) { if (rf & 1) {
304
+ const _r19 = i0.ɵɵgetCurrentView();
305
+ i0.ɵɵelementStart(0, "div", 74);
306
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_For_33_Template_div_click_0_listener($event) { const df_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.OnEditorDestClick(df_r20.Name); return i0.ɵɵresetView($event.stopPropagation()); });
307
+ i0.ɵɵelementStart(1, "span", 75);
308
+ i0.ɵɵtext(2);
309
+ i0.ɵɵelementEnd();
310
+ i0.ɵɵelementStart(3, "span", 76);
311
+ i0.ɵɵtext(4);
312
+ i0.ɵɵelementEnd();
313
+ i0.ɵɵelementStart(5, "span", 77);
314
+ i0.ɵɵconditionalCreate(6, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_33_Conditional_6_Template, 2, 0, "span", 79);
315
+ i0.ɵɵelementEnd()();
316
+ } if (rf & 2) {
317
+ const df_r20 = ctx.$implicit;
318
+ const ctx_r1 = i0.ɵɵnextContext(3);
319
+ i0.ɵɵstyleProp("height", ctx_r1.FIELD_HEIGHT, "px");
320
+ i0.ɵɵclassProp("mapped", ctx_r1.IsDestFieldMapped(df_r20.Name))("unmapped", !ctx_r1.IsDestFieldMapped(df_r20.Name))("connect-target", ctx_r1.ConnectingFromSource !== null);
321
+ i0.ɵɵadvance();
322
+ i0.ɵɵproperty("title", df_r20.Name);
323
+ i0.ɵɵadvance();
324
+ i0.ɵɵtextInterpolate(df_r20.Name);
325
+ i0.ɵɵadvance(2);
326
+ i0.ɵɵtextInterpolate(df_r20.Type);
327
+ i0.ɵɵadvance(2);
328
+ i0.ɵɵconditional(df_r20.IsRequired ? 6 : -1);
329
+ } }
330
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_Conditional_34_Template(rf, ctx) { if (rf & 1) {
331
+ i0.ɵɵelementStart(0, "div", 70);
332
+ i0.ɵɵtext(1, "No destination fields found");
333
+ i0.ɵɵelementEnd();
334
+ } }
335
+ function VisualFieldEditorComponent_Conditional_47_Conditional_8_Template(rf, ctx) { if (rf & 1) {
336
+ const _r13 = i0.ɵɵgetCurrentView();
337
+ i0.ɵɵelementStart(0, "div", 51)(1, "div", 54)(2, "div", 55)(3, "div", 56);
338
+ i0.ɵɵelement(4, "i", 15);
339
+ i0.ɵɵtext(5, " Source Fields ");
340
+ i0.ɵɵelementStart(6, "span", 57);
341
+ i0.ɵɵtext(7);
342
+ i0.ɵɵelementEnd()();
343
+ i0.ɵɵelement(8, "div", 58);
344
+ i0.ɵɵelementStart(9, "div", 59);
345
+ i0.ɵɵelement(10, "i", 17);
346
+ i0.ɵɵtext(11, " MJ Entity Fields ");
347
+ i0.ɵɵelementStart(12, "span", 57);
348
+ i0.ɵɵtext(13);
349
+ i0.ɵɵelementEnd()()();
350
+ i0.ɵɵelementStart(14, "div", 60)(15, "div", 61);
351
+ i0.ɵɵelement(16, "i", 62);
352
+ i0.ɵɵelementStart(17, "input", 63);
353
+ i0.ɵɵlistener("input", function VisualFieldEditorComponent_Conditional_47_Conditional_8_Template_input_input_17_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.EditorSearchSource = $event.target.value); });
354
+ i0.ɵɵelementEnd()();
355
+ i0.ɵɵelement(18, "div", 64);
356
+ i0.ɵɵelementStart(19, "div", 61);
357
+ i0.ɵɵelement(20, "i", 62);
358
+ i0.ɵɵelementStart(21, "input", 65);
359
+ i0.ɵɵlistener("input", function VisualFieldEditorComponent_Conditional_47_Conditional_8_Template_input_input_21_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.EditorSearchDest = $event.target.value); });
360
+ i0.ɵɵelementEnd()()();
361
+ i0.ɵɵelementStart(22, "div", 66);
362
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_Template_div_click_22_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.DeselectConnection()); });
363
+ i0.ɵɵelementStart(23, "div", 67)(24, "div", 68);
364
+ i0.ɵɵrepeaterCreate(25, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_26_Template, 8, 13, "div", 69, _forTrack0);
365
+ i0.ɵɵconditionalCreate(27, VisualFieldEditorComponent_Conditional_47_Conditional_8_Conditional_27_Template, 2, 0, "div", 70);
366
+ i0.ɵɵelementEnd();
367
+ i0.ɵɵnamespaceSVG();
368
+ i0.ɵɵelementStart(28, "svg", 71);
369
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_8_Template_svg_click_28_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
370
+ i0.ɵɵrepeaterCreate(29, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_30_Template, 4, 13, null, null, _forTrack1);
371
+ i0.ɵɵelementEnd();
372
+ i0.ɵɵnamespaceHTML();
373
+ i0.ɵɵelementStart(31, "div", 72);
374
+ i0.ɵɵrepeaterCreate(32, VisualFieldEditorComponent_Conditional_47_Conditional_8_For_33_Template, 7, 12, "div", 73, _forTrack0);
375
+ i0.ɵɵconditionalCreate(34, VisualFieldEditorComponent_Conditional_47_Conditional_8_Conditional_34_Template, 2, 0, "div", 70);
376
+ i0.ɵɵelementEnd()()()()();
377
+ } if (rf & 2) {
378
+ const ctx_r1 = i0.ɵɵnextContext(2);
379
+ i0.ɵɵadvance(7);
380
+ i0.ɵɵtextInterpolate(ctx_r1.EditorSourceFields.length);
381
+ i0.ɵɵadvance(6);
382
+ i0.ɵɵtextInterpolate(ctx_r1.EditorDestFields.length);
383
+ i0.ɵɵadvance(4);
384
+ i0.ɵɵproperty("value", ctx_r1.EditorSearchSource);
385
+ i0.ɵɵadvance(4);
386
+ i0.ɵɵproperty("value", ctx_r1.EditorSearchDest);
387
+ i0.ɵɵadvance(2);
388
+ i0.ɵɵstyleProp("min-height", ctx_r1.EditorCanvasHeight, "px");
389
+ i0.ɵɵadvance(2);
390
+ i0.ɵɵrepeater(ctx_r1.FilteredEditorSourceFields);
391
+ i0.ɵɵadvance(2);
392
+ i0.ɵɵconditional(ctx_r1.FilteredEditorSourceFields.length === 0 ? 27 : -1);
393
+ i0.ɵɵadvance();
394
+ i0.ɵɵattribute("width", ctx_r1.SVG_WIDTH)("height", ctx_r1.EditorCanvasHeight)("viewBox", "0 0 " + ctx_r1.SVG_WIDTH + " " + ctx_r1.EditorCanvasHeight);
395
+ i0.ɵɵadvance();
396
+ i0.ɵɵrepeater(ctx_r1.VisibleConnections);
397
+ i0.ɵɵadvance(3);
398
+ i0.ɵɵrepeater(ctx_r1.FilteredEditorDestFields);
399
+ i0.ɵɵadvance(2);
400
+ i0.ɵɵconditional(ctx_r1.FilteredEditorDestFields.length === 0 ? 34 : -1);
401
+ } }
402
+ function VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
403
+ i0.ɵɵelementStart(0, "div", 83);
404
+ i0.ɵɵelement(1, "i", 31);
405
+ i0.ɵɵtext(2, " Loading stats... ");
406
+ i0.ɵɵelementEnd();
407
+ } }
408
+ function VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Conditional_25_Template(rf, ctx) { if (rf & 1) {
409
+ i0.ɵɵelementStart(0, "div", 85)(1, "div", 97);
410
+ i0.ɵɵelement(2, "i", 48);
411
+ i0.ɵɵelementEnd();
412
+ i0.ɵɵelementStart(3, "div", 87)(4, "span", 88);
413
+ i0.ɵɵtext(5);
414
+ i0.ɵɵelementEnd();
415
+ i0.ɵɵelementStart(6, "span", 89);
416
+ i0.ɵɵtext(7);
417
+ i0.ɵɵelementEnd()()();
418
+ } if (rf & 2) {
419
+ const ctx_r1 = i0.ɵɵnextContext(4);
420
+ i0.ɵɵadvance();
421
+ i0.ɵɵproperty("ngClass", ctx_r1.SyncStatusClass(ctx_r1.InfoLastSync.Status));
422
+ i0.ɵɵadvance();
423
+ i0.ɵɵclassProp("fa-circle-check", ctx_r1.InfoLastSync.Status === "Success")("fa-circle-xmark", ctx_r1.InfoLastSync.Status === "Failed")("fa-spinner", ctx_r1.InfoLastSync.Status === "In Progress")("fa-clock", ctx_r1.InfoLastSync.Status === "Pending");
424
+ i0.ɵɵadvance(3);
425
+ i0.ɵɵtextInterpolate(ctx_r1.InfoLastSync.Status);
426
+ i0.ɵɵadvance(2);
427
+ i0.ɵɵtextInterpolate1("", ctx_r1.InfoLastSync.TotalRecords, " records processed");
428
+ } }
429
+ function VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Conditional_47_Template(rf, ctx) { if (rf & 1) {
430
+ i0.ɵɵelementStart(0, "div", 94)(1, "span", 95);
431
+ i0.ɵɵtext(2, "Match Strategy");
432
+ i0.ɵɵelementEnd();
433
+ i0.ɵɵelementStart(3, "span", 96);
434
+ i0.ɵɵtext(4, "Configured");
435
+ i0.ɵɵelementEnd()();
436
+ } }
437
+ function VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
438
+ i0.ɵɵelementStart(0, "div", 84)(1, "div", 85)(2, "div", 86);
439
+ i0.ɵɵelement(3, "i", 17);
440
+ i0.ɵɵelementEnd();
441
+ i0.ɵɵelementStart(4, "div", 87)(5, "span", 88);
442
+ i0.ɵɵtext(6);
443
+ i0.ɵɵelementEnd();
444
+ i0.ɵɵelementStart(7, "span", 89);
445
+ i0.ɵɵtext(8, "MJ Records");
446
+ i0.ɵɵelementEnd()()();
447
+ i0.ɵɵelementStart(9, "div", 85)(10, "div", 90);
448
+ i0.ɵɵelement(11, "i", 15);
449
+ i0.ɵɵelementEnd();
450
+ i0.ɵɵelementStart(12, "div", 87)(13, "span", 88);
451
+ i0.ɵɵtext(14);
452
+ i0.ɵɵelementEnd();
453
+ i0.ɵɵelementStart(15, "span", 89);
454
+ i0.ɵɵtext(16, "Source Fields");
455
+ i0.ɵɵelementEnd()()();
456
+ i0.ɵɵelementStart(17, "div", 85)(18, "div", 91);
457
+ i0.ɵɵelement(19, "i", 92);
458
+ i0.ɵɵelementEnd();
459
+ i0.ɵɵelementStart(20, "div", 87)(21, "span", 88);
460
+ i0.ɵɵtext(22);
461
+ i0.ɵɵelementEnd();
462
+ i0.ɵɵelementStart(23, "span", 89);
463
+ i0.ɵɵtext(24, "Last Sync");
464
+ i0.ɵɵelementEnd()()();
465
+ i0.ɵɵconditionalCreate(25, VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Conditional_25_Template, 8, 11, "div", 85);
466
+ i0.ɵɵelementEnd();
467
+ i0.ɵɵelementStart(26, "div", 93)(27, "div", 94)(28, "span", 95);
468
+ i0.ɵɵtext(29, "Sync Direction");
469
+ i0.ɵɵelementEnd();
470
+ i0.ɵɵelementStart(30, "span", 96);
471
+ i0.ɵɵtext(31);
472
+ i0.ɵɵelementEnd()();
473
+ i0.ɵɵelementStart(32, "div", 94)(33, "span", 95);
474
+ i0.ɵɵtext(34, "Conflict Resolution");
475
+ i0.ɵɵelementEnd();
476
+ i0.ɵɵelementStart(35, "span", 96);
477
+ i0.ɵɵtext(36);
478
+ i0.ɵɵelementEnd()();
479
+ i0.ɵɵelementStart(37, "div", 94)(38, "span", 95);
480
+ i0.ɵɵtext(39, "Delete Behavior");
481
+ i0.ɵɵelementEnd();
482
+ i0.ɵɵelementStart(40, "span", 96);
483
+ i0.ɵɵtext(41);
484
+ i0.ɵɵelementEnd()();
485
+ i0.ɵɵelementStart(42, "div", 94)(43, "span", 95);
486
+ i0.ɵɵtext(44, "Priority");
487
+ i0.ɵɵelementEnd();
488
+ i0.ɵɵelementStart(45, "span", 96);
489
+ i0.ɵɵtext(46);
490
+ i0.ɵɵelementEnd()();
491
+ i0.ɵɵconditionalCreate(47, VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Conditional_47_Template, 5, 0, "div", 94);
492
+ i0.ɵɵelementEnd();
493
+ } if (rf & 2) {
494
+ const ctx_r1 = i0.ɵɵnextContext(3);
495
+ i0.ɵɵadvance(6);
496
+ i0.ɵɵtextInterpolate(ctx_r1.InfoDestRecordCount ?? "-");
497
+ i0.ɵɵadvance(8);
498
+ i0.ɵɵtextInterpolate(ctx_r1.EditorSourceFields.length);
499
+ i0.ɵɵadvance(8);
500
+ i0.ɵɵtextInterpolate(ctx_r1.FormatSyncDate((ctx_r1.InfoLastSync == null ? null : ctx_r1.InfoLastSync.StartedAt) ?? null));
501
+ i0.ɵɵadvance(3);
502
+ i0.ɵɵconditional(ctx_r1.InfoLastSync ? 25 : -1);
503
+ i0.ɵɵadvance(6);
504
+ i0.ɵɵtextInterpolate(ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.SyncDirection);
505
+ i0.ɵɵadvance(5);
506
+ i0.ɵɵtextInterpolate(ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.ConflictResolution);
507
+ i0.ɵɵadvance(5);
508
+ i0.ɵɵtextInterpolate(ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.DeleteBehavior);
509
+ i0.ɵɵadvance(5);
510
+ i0.ɵɵtextInterpolate(ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.Priority);
511
+ i0.ɵɵadvance();
512
+ i0.ɵɵconditional((ctx_r1.EntityMap == null ? null : ctx_r1.EntityMap.MatchStrategy) ? 47 : -1);
513
+ } }
514
+ function VisualFieldEditorComponent_Conditional_47_Conditional_14_Template(rf, ctx) { if (rf & 1) {
515
+ i0.ɵɵelementStart(0, "div", 52);
516
+ i0.ɵɵconditionalCreate(1, VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_1_Template, 3, 0, "div", 83)(2, VisualFieldEditorComponent_Conditional_47_Conditional_14_Conditional_2_Template, 48, 9);
517
+ i0.ɵɵelementEnd();
518
+ } if (rf & 2) {
519
+ const ctx_r1 = i0.ɵɵnextContext(2);
520
+ i0.ɵɵadvance();
521
+ i0.ɵɵconditional(ctx_r1.InfoPanelLoading ? 1 : 2);
522
+ } }
523
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_16_Template(rf, ctx) { if (rf & 1) {
524
+ i0.ɵɵelement(0, "i", 32);
525
+ } }
526
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_21_Template(rf, ctx) { if (rf & 1) {
527
+ i0.ɵɵelement(0, "i", 32);
528
+ } }
529
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_For_6_Template(rf, ctx) { if (rf & 1) {
530
+ i0.ɵɵelementStart(0, "option", 125);
531
+ i0.ɵɵtext(1);
532
+ i0.ɵɵelementEnd();
533
+ } if (rf & 2) {
534
+ const tt_r24 = ctx.$implicit;
535
+ const step_r25 = i0.ɵɵnextContext().$implicit;
536
+ i0.ɵɵproperty("value", tt_r24.Value)("selected", tt_r24.Value === step_r25.Type);
537
+ i0.ɵɵadvance();
538
+ i0.ɵɵtextInterpolate(tt_r24.Label);
539
+ } }
540
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Conditional_9_For_2_Template(rf, ctx) { if (rf & 1) {
541
+ const _r26 = i0.ɵɵgetCurrentView();
542
+ i0.ɵɵelementStart(0, "div", 133)(1, "label");
543
+ i0.ɵɵtext(2);
544
+ i0.ɵɵelementEnd();
545
+ i0.ɵɵelementStart(3, "input", 134);
546
+ i0.ɵɵlistener("input", function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Conditional_9_For_2_Template_input_input_3_listener($event) { const key_r27 = i0.ɵɵrestoreView(_r26).$implicit; const ɵ$index_521_r23 = i0.ɵɵnextContext(2).$index; const conn_r28 = i0.ɵɵnextContext(); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnTransformConfigChange(conn_r28, ɵ$index_521_r23, key_r27, $event.target.value)); });
547
+ i0.ɵɵelementEnd()();
548
+ } if (rf & 2) {
549
+ const key_r27 = ctx.$implicit;
550
+ const step_r25 = i0.ɵɵnextContext(2).$implicit;
551
+ const ctx_r1 = i0.ɵɵnextContext(3);
552
+ i0.ɵɵadvance(2);
553
+ i0.ɵɵtextInterpolate(key_r27);
554
+ i0.ɵɵadvance();
555
+ i0.ɵɵproperty("placeholder", i0.ɵɵinterpolate(key_r27))("value", ctx_r1.GetConfigValue(step_r25, key_r27));
556
+ } }
557
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Conditional_9_Template(rf, ctx) { if (rf & 1) {
558
+ i0.ɵɵelementStart(0, "div", 127);
559
+ i0.ɵɵrepeaterCreate(1, VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Conditional_9_For_2_Template, 4, 4, "div", 133, i0.ɵɵrepeaterTrackByIdentity);
560
+ i0.ɵɵelementEnd();
561
+ } if (rf & 2) {
562
+ const step_r25 = i0.ɵɵnextContext().$implicit;
563
+ const ctx_r1 = i0.ɵɵnextContext(3);
564
+ i0.ɵɵadvance();
565
+ i0.ɵɵrepeater(ctx_r1.GetConfigKeys(step_r25));
566
+ } }
567
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Template(rf, ctx) { if (rf & 1) {
568
+ const _r22 = i0.ɵɵgetCurrentView();
569
+ i0.ɵɵelementStart(0, "div", 117)(1, "div", 122)(2, "span", 123);
570
+ i0.ɵɵtext(3);
571
+ i0.ɵɵelementEnd();
572
+ i0.ɵɵelementStart(4, "select", 124);
573
+ i0.ɵɵlistener("change", function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Template_select_change_4_listener($event) { const ɵ$index_521_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnConnectionTransformChange(ɵ$index_521_r23, $event.target.value)); });
574
+ i0.ɵɵrepeaterCreate(5, VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_For_6_Template, 2, 3, "option", 125, _forTrack2);
575
+ i0.ɵɵelementEnd();
576
+ i0.ɵɵelementStart(7, "button", 126);
577
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Template_button_click_7_listener() { const ɵ$index_521_r23 = i0.ɵɵrestoreView(_r22).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.RemoveTransformStep(ɵ$index_521_r23)); });
578
+ i0.ɵɵelement(8, "i", 121);
579
+ i0.ɵɵelementEnd()();
580
+ i0.ɵɵconditionalCreate(9, VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Conditional_9_Template, 3, 0, "div", 127);
581
+ i0.ɵɵelementStart(10, "div", 128)(11, "label");
582
+ i0.ɵɵtext(12, "On Error:");
583
+ i0.ɵɵelementEnd();
584
+ i0.ɵɵelementStart(13, "select", 129);
585
+ i0.ɵɵlistener("change", function VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Template_select_change_13_listener($event) { const step_r25 = i0.ɵɵrestoreView(_r22).$implicit; const conn_r28 = i0.ɵɵnextContext(); step_r25.OnError = $event.target.value; return i0.ɵɵresetView(conn_r28.IsDirty = true); });
586
+ i0.ɵɵelementStart(14, "option", 130);
587
+ i0.ɵɵtext(15, "Fail");
588
+ i0.ɵɵelementEnd();
589
+ i0.ɵɵelementStart(16, "option", 131);
590
+ i0.ɵɵtext(17, "Skip");
591
+ i0.ɵɵelementEnd();
592
+ i0.ɵɵelementStart(18, "option", 132);
593
+ i0.ɵɵtext(19, "Null");
594
+ i0.ɵɵelementEnd()()()();
595
+ } if (rf & 2) {
596
+ const step_r25 = ctx.$implicit;
597
+ const ɵ$index_521_r23 = ctx.$index;
598
+ const ctx_r1 = i0.ɵɵnextContext(3);
599
+ i0.ɵɵadvance(3);
600
+ i0.ɵɵtextInterpolate(ɵ$index_521_r23 + 1);
601
+ i0.ɵɵadvance();
602
+ i0.ɵɵproperty("value", step_r25.Type);
603
+ i0.ɵɵadvance();
604
+ i0.ɵɵrepeater(ctx_r1.TRANSFORM_TYPES);
605
+ i0.ɵɵadvance(4);
606
+ i0.ɵɵconditional(step_r25.Type !== "direct" ? 9 : -1);
607
+ i0.ɵɵadvance(4);
608
+ i0.ɵɵproperty("value", step_r25.OnError);
609
+ } }
610
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_43_Template(rf, ctx) { if (rf & 1) {
611
+ i0.ɵɵelementStart(0, "div", 118);
612
+ i0.ɵɵtext(1, " No transform steps. Data passes through as-is. ");
613
+ i0.ɵɵelementEnd();
614
+ } }
615
+ function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template(rf, ctx) { if (rf & 1) {
616
+ const _r21 = i0.ɵɵgetCurrentView();
617
+ i0.ɵɵelementStart(0, "div", 98);
618
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r21); return i0.ɵɵresetView($event.stopPropagation()); });
619
+ i0.ɵɵelementStart(1, "div", 99)(2, "span", 100);
620
+ i0.ɵɵtext(3, "Mapping Details");
621
+ i0.ɵɵelementEnd();
622
+ i0.ɵɵelementStart(4, "button", 101);
623
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.DeselectConnection()); });
624
+ i0.ɵɵelement(5, "i", 37);
625
+ i0.ɵɵelementEnd()();
626
+ i0.ɵɵelementStart(6, "div", 102)(7, "div", 103)(8, "span", 104);
627
+ i0.ɵɵtext(9);
628
+ i0.ɵɵelementEnd();
629
+ i0.ɵɵelement(10, "i", 105);
630
+ i0.ɵɵelementStart(11, "span", 106);
631
+ i0.ɵɵtext(12);
632
+ i0.ɵɵelementEnd()()();
633
+ i0.ɵɵelementStart(13, "div", 107)(14, "label", 108);
634
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_label_click_14_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleConnectionKey()); });
635
+ i0.ɵɵelementStart(15, "span", 109);
636
+ i0.ɵɵconditionalCreate(16, VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_16_Template, 1, 0, "i", 32);
637
+ i0.ɵɵelementEnd();
638
+ i0.ɵɵelementStart(17, "span");
639
+ i0.ɵɵtext(18, "Key Field");
640
+ i0.ɵɵelementEnd()();
641
+ i0.ɵɵelementStart(19, "label", 108);
642
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_label_click_19_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleConnectionRequired()); });
643
+ i0.ɵɵelementStart(20, "span", 109);
644
+ i0.ɵɵconditionalCreate(21, VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_21_Template, 1, 0, "i", 32);
645
+ i0.ɵɵelementEnd();
646
+ i0.ɵɵelementStart(22, "span");
647
+ i0.ɵɵtext(23, "Required");
648
+ i0.ɵɵelementEnd()()();
649
+ i0.ɵɵelementStart(24, "div", 110)(25, "label", 111);
650
+ i0.ɵɵtext(26, "Direction");
651
+ i0.ɵɵelementEnd();
652
+ i0.ɵɵelementStart(27, "div", 112)(28, "button", 113);
653
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_28_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnConnectionDirectionChange("SourceToDest")); });
654
+ i0.ɵɵtext(29, " Source \u2192 Dest ");
655
+ i0.ɵɵelementEnd();
656
+ i0.ɵɵelementStart(30, "button", 113);
657
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnConnectionDirectionChange("DestToSource")); });
658
+ i0.ɵɵtext(31, " Dest \u2192 Source ");
659
+ i0.ɵɵelementEnd();
660
+ i0.ɵɵelementStart(32, "button", 113);
661
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnConnectionDirectionChange("Both")); });
662
+ i0.ɵɵtext(33, " Both ");
663
+ i0.ɵɵelementEnd()()();
664
+ i0.ɵɵelementStart(34, "div", 110)(35, "div", 114)(36, "label", 111);
665
+ i0.ɵɵtext(37, "Transform Pipeline");
666
+ i0.ɵɵelementEnd();
667
+ i0.ɵɵelementStart(38, "button", 115);
668
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_38_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.AddTransformStep()); });
669
+ i0.ɵɵelement(39, "i", 116);
670
+ i0.ɵɵtext(40, " Add Step ");
671
+ i0.ɵɵelementEnd()();
672
+ i0.ɵɵrepeaterCreate(41, VisualFieldEditorComponent_Conditional_47_Conditional_15_For_42_Template, 20, 4, "div", 117, i0.ɵɵrepeaterTrackByIndex);
673
+ i0.ɵɵconditionalCreate(43, VisualFieldEditorComponent_Conditional_47_Conditional_15_Conditional_43_Template, 2, 0, "div", 118);
674
+ i0.ɵɵelementEnd();
675
+ i0.ɵɵelementStart(44, "div", 119)(45, "button", 120);
676
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Conditional_15_Template_button_click_45_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RemoveSelectedConnection()); });
677
+ i0.ɵɵelement(46, "i", 121);
678
+ i0.ɵɵtext(47, " Remove Mapping ");
679
+ i0.ɵɵelementEnd()()();
680
+ } if (rf & 2) {
681
+ const conn_r28 = ctx;
682
+ i0.ɵɵadvance(9);
683
+ i0.ɵɵtextInterpolate(conn_r28.SourceFieldName);
684
+ i0.ɵɵadvance();
685
+ i0.ɵɵclassProp("fa-arrow-right", conn_r28.Direction === "SourceToDest")("fa-arrow-left", conn_r28.Direction === "DestToSource")("fa-right-left", conn_r28.Direction === "Both");
686
+ i0.ɵɵadvance(2);
687
+ i0.ɵɵtextInterpolate(conn_r28.DestFieldName);
688
+ i0.ɵɵadvance(3);
689
+ i0.ɵɵclassProp("active", conn_r28.IsKeyField);
690
+ i0.ɵɵadvance();
691
+ i0.ɵɵconditional(conn_r28.IsKeyField ? 16 : -1);
692
+ i0.ɵɵadvance(4);
693
+ i0.ɵɵclassProp("active", conn_r28.IsRequired);
694
+ i0.ɵɵadvance();
695
+ i0.ɵɵconditional(conn_r28.IsRequired ? 21 : -1);
696
+ i0.ɵɵadvance(7);
697
+ i0.ɵɵclassProp("active", conn_r28.Direction === "SourceToDest");
698
+ i0.ɵɵadvance(2);
699
+ i0.ɵɵclassProp("active", conn_r28.Direction === "DestToSource");
700
+ i0.ɵɵadvance(2);
701
+ i0.ɵɵclassProp("active", conn_r28.Direction === "Both");
702
+ i0.ɵɵadvance(9);
703
+ i0.ɵɵrepeater(conn_r28.TransformSteps);
704
+ i0.ɵɵadvance(2);
705
+ i0.ɵɵconditional(conn_r28.TransformSteps.length === 0 ? 43 : -1);
706
+ } }
707
+ function VisualFieldEditorComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
708
+ const _r12 = i0.ɵɵgetCurrentView();
709
+ i0.ɵɵelementStart(0, "div", 45)(1, "div", 46)(2, "div", 47);
710
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleFieldMaps()); });
711
+ i0.ɵɵelement(3, "i", 48);
712
+ i0.ɵɵelementStart(4, "span", 49);
713
+ i0.ɵɵtext(5, "Field Mappings");
714
+ i0.ɵɵelementEnd();
715
+ i0.ɵɵelementStart(6, "span", 50);
716
+ i0.ɵɵtext(7);
717
+ i0.ɵɵelementEnd()();
718
+ i0.ɵɵconditionalCreate(8, VisualFieldEditorComponent_Conditional_47_Conditional_8_Template, 35, 11, "div", 51);
719
+ i0.ɵɵelementEnd();
720
+ i0.ɵɵelementStart(9, "div", 46)(10, "div", 47);
721
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Conditional_47_Template_div_click_10_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleInfoPanel()); });
722
+ i0.ɵɵelement(11, "i", 48);
723
+ i0.ɵɵelementStart(12, "span", 49);
724
+ i0.ɵɵtext(13, "Sync Info");
725
+ i0.ɵɵelementEnd()();
726
+ i0.ɵɵconditionalCreate(14, VisualFieldEditorComponent_Conditional_47_Conditional_14_Template, 3, 1, "div", 52);
727
+ i0.ɵɵelementEnd()();
728
+ i0.ɵɵconditionalCreate(15, VisualFieldEditorComponent_Conditional_47_Conditional_15_Template, 48, 21, "div", 53);
729
+ } if (rf & 2) {
730
+ let tmp_10_0;
731
+ const ctx_r1 = i0.ɵɵnextContext();
732
+ i0.ɵɵadvance();
733
+ i0.ɵɵclassProp("collapsed", !ctx_r1.FieldMapsExpanded);
734
+ i0.ɵɵadvance(2);
735
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.FieldMapsExpanded)("fa-chevron-right", !ctx_r1.FieldMapsExpanded);
736
+ i0.ɵɵadvance(4);
737
+ i0.ɵɵtextInterpolate1("", ctx_r1.EditorMappedCount, " mapped");
738
+ i0.ɵɵadvance();
739
+ i0.ɵɵconditional(ctx_r1.FieldMapsExpanded ? 8 : -1);
740
+ i0.ɵɵadvance();
741
+ i0.ɵɵclassProp("collapsed", !ctx_r1.InfoPanelExpanded);
742
+ i0.ɵɵadvance(2);
743
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.InfoPanelExpanded)("fa-chevron-right", !ctx_r1.InfoPanelExpanded);
744
+ i0.ɵɵadvance(3);
745
+ i0.ɵɵconditional(ctx_r1.InfoPanelExpanded ? 14 : -1);
746
+ i0.ɵɵadvance();
747
+ i0.ɵɵconditional((tmp_10_0 = ctx_r1.SelectedConnection) ? 15 : -1, tmp_10_0);
748
+ } }
749
+ export class VisualFieldEditorComponent {
750
+ // ---------------------------------------------------------------------------
751
+ // Inputs / Outputs
752
+ // ---------------------------------------------------------------------------
753
+ EntityMap = null;
754
+ CompanyIntegrationID = null;
755
+ RunViewProvider = null;
756
+ Close = new EventEmitter();
757
+ // ---------------------------------------------------------------------------
758
+ // Visual Editor state (copied from PipelinesComponent)
759
+ // ---------------------------------------------------------------------------
760
+ EditorSourceFields = [];
761
+ EditorDestFields = [];
762
+ EditorConnections = [];
763
+ EditorLoading = false;
764
+ EditorSaving = false;
765
+ EditorSaveSuccess = false;
766
+ SelectedConnectionIdx = null;
767
+ ConnectingFromSource = null;
768
+ EditorSearchSource = '';
769
+ EditorSearchDest = '';
770
+ ShowSourcePreview = false;
771
+ ShowDestPreview = false;
772
+ PreviewSourceLoading = false;
773
+ PreviewDestLoading = false;
774
+ PreviewSourceRows = [];
775
+ PreviewDestRows = [];
776
+ PreviewSourceColumns = [];
777
+ PreviewDestColumns = [];
778
+ FieldMapsExpanded = true;
779
+ InfoPanelExpanded = false;
780
+ InfoPanelLoading = false;
781
+ InfoDestRecordCount = null;
782
+ InfoLastSync = null;
783
+ FIELD_HEIGHT = 40;
784
+ SVG_WIDTH = 200;
785
+ TRANSFORM_TYPES = [
786
+ { Value: 'direct', Label: 'Direct', Icon: 'fa-solid fa-arrow-right' },
787
+ { Value: 'regex', Label: 'Regex', Icon: 'fa-solid fa-code' },
788
+ { Value: 'split', Label: 'Split', Icon: 'fa-solid fa-scissors' },
789
+ { Value: 'combine', Label: 'Combine', Icon: 'fa-solid fa-object-group' },
790
+ { Value: 'lookup', Label: 'Lookup', Icon: 'fa-solid fa-book' },
791
+ { Value: 'format', Label: 'Format', Icon: 'fa-solid fa-font' },
792
+ { Value: 'coerce', Label: 'Coerce', Icon: 'fa-solid fa-exchange-alt' },
793
+ { Value: 'substring', Label: 'Substring', Icon: 'fa-solid fa-text-width' },
794
+ { Value: 'custom', Label: 'Custom', Icon: 'fa-solid fa-wand-magic-sparkles' }
795
+ ];
796
+ dataService = inject(IntegrationDataService);
797
+ cdr = inject(ChangeDetectorRef);
798
+ // ---------------------------------------------------------------------------
799
+ // Lifecycle
800
+ // ---------------------------------------------------------------------------
801
+ ngOnChanges(changes) {
802
+ if (changes['EntityMap'] && this.EntityMap && this.CompanyIntegrationID) {
803
+ this.openEditor();
804
+ }
805
+ }
806
+ // ---------------------------------------------------------------------------
807
+ // Open / Close
808
+ // ---------------------------------------------------------------------------
809
+ openEditor() {
810
+ this.SelectedConnectionIdx = null;
811
+ this.ConnectingFromSource = null;
812
+ this.EditorSearchSource = '';
813
+ this.EditorSearchDest = '';
814
+ this.EditorSaveSuccess = false;
815
+ this.ShowSourcePreview = false;
816
+ this.ShowDestPreview = false;
817
+ this.PreviewSourceRows = [];
818
+ this.PreviewDestRows = [];
819
+ this.PreviewSourceColumns = [];
820
+ this.PreviewDestColumns = [];
821
+ this.FieldMapsExpanded = true;
822
+ this.InfoPanelExpanded = false;
823
+ this.InfoDestRecordCount = null;
824
+ this.InfoLastSync = null;
825
+ this.cdr.detectChanges();
826
+ this.LoadVisualEditorData();
827
+ }
828
+ OnClose() {
829
+ this.Close.emit();
830
+ }
831
+ // ---------------------------------------------------------------------------
832
+ // SyncEnabled toggle
833
+ // ---------------------------------------------------------------------------
834
+ async OnToggleEditorSyncEnabled(event) {
835
+ if (!this.EntityMap)
836
+ return;
837
+ const checkbox = event.target;
838
+ const newValue = checkbox.checked;
839
+ this.EntityMap.SyncEnabled = newValue;
840
+ this.cdr.detectChanges();
841
+ try {
842
+ await this.dataService.ToggleEntityMapEnabled(this.EntityMap.ID, newValue);
843
+ }
844
+ catch (err) {
845
+ this.EntityMap.SyncEnabled = !newValue;
846
+ checkbox.checked = !newValue;
847
+ console.error('[VisualFieldEditor] Failed to toggle SyncEnabled:', err);
848
+ this.cdr.detectChanges();
849
+ }
850
+ }
851
+ // ---------------------------------------------------------------------------
852
+ // Data loading
853
+ // ---------------------------------------------------------------------------
854
+ async LoadVisualEditorData() {
855
+ if (!this.EntityMap || !this.CompanyIntegrationID)
856
+ return;
857
+ this.EditorLoading = true;
858
+ this.cdr.detectChanges();
859
+ const entityMap = this.EntityMap;
860
+ try {
861
+ const [fieldMaps, destFields] = await Promise.all([
862
+ this.dataService.LoadFieldMaps(entityMap.ID, this.RunViewProvider),
863
+ this.dataService.LoadEntityFields(entityMap.EntityID, this.RunViewProvider)
864
+ ]);
865
+ const sourceFields = this.resolveSourceFieldsFromMetadata(this.CompanyIntegrationID, entityMap.ExternalObjectName);
866
+ if (sourceFields.length > 0) {
867
+ this.EditorSourceFields = sourceFields;
868
+ }
869
+ else {
870
+ this.EditorSourceFields = fieldMaps.map(fm => ({
871
+ Name: fm.SourceFieldName,
872
+ Label: fm.SourceFieldLabel ?? fm.SourceFieldName,
873
+ Type: '',
874
+ IsRequired: fm.IsRequired,
875
+ IsPrimaryKey: fm.IsKeyField
876
+ }));
877
+ }
878
+ this.EditorDestFields = destFields
879
+ .filter(f => !f.Name.startsWith('__mj'))
880
+ .map(f => ({
881
+ Name: f.Name,
882
+ Type: f.Type,
883
+ IsRequired: f.IsRequired
884
+ }));
885
+ this.EditorConnections = fieldMaps
886
+ .filter(fm => fm.Status === 'Active')
887
+ .map(fm => ({
888
+ ID: fm.ID,
889
+ SourceFieldName: fm.SourceFieldName,
890
+ DestFieldName: fm.DestinationFieldName,
891
+ IsKeyField: fm.IsKeyField,
892
+ IsRequired: fm.IsRequired,
893
+ Direction: fm.Direction,
894
+ TransformSteps: this.parseTransformPipeline(fm.TransformPipeline),
895
+ IsDirty: false,
896
+ IsNew: false,
897
+ MarkedForDelete: false
898
+ }));
899
+ }
900
+ catch (err) {
901
+ console.error('[VisualFieldEditor] Failed to load editor data:', err);
902
+ }
903
+ finally {
904
+ this.EditorLoading = false;
905
+ this.cdr.detectChanges();
906
+ }
907
+ }
908
+ // ---------------------------------------------------------------------------
909
+ // Filtered field lists
910
+ // ---------------------------------------------------------------------------
911
+ get FilteredEditorSourceFields() {
912
+ if (!this.EditorSearchSource.trim())
913
+ return this.EditorSourceFields;
914
+ const term = this.EditorSearchSource.toLowerCase();
915
+ return this.EditorSourceFields.filter(f => f.Name.toLowerCase().includes(term) || f.Label.toLowerCase().includes(term));
916
+ }
917
+ get FilteredEditorDestFields() {
918
+ if (!this.EditorSearchDest.trim())
919
+ return this.EditorDestFields;
920
+ const term = this.EditorSearchDest.toLowerCase();
921
+ return this.EditorDestFields.filter(f => f.Name.toLowerCase().includes(term));
922
+ }
923
+ get VisibleConnections() {
924
+ return this.EditorConnections.filter(c => !c.MarkedForDelete &&
925
+ this.getSourceFieldIndex(c.SourceFieldName) >= 0 &&
926
+ this.getDestFieldIndex(c.DestFieldName) >= 0);
927
+ }
928
+ // ---------------------------------------------------------------------------
929
+ // SVG Calculations
930
+ // ---------------------------------------------------------------------------
931
+ get EditorCanvasHeight() {
932
+ const sourceHeight = this.FilteredEditorSourceFields.length * this.FIELD_HEIGHT;
933
+ const destHeight = this.FilteredEditorDestFields.length * this.FIELD_HEIGHT;
934
+ return Math.max(sourceHeight, destHeight, 200);
935
+ }
936
+ GetConnectionPath(conn) {
937
+ const sourceY = this.getSourceFieldY(conn.SourceFieldName);
938
+ const destY = this.getDestFieldY(conn.DestFieldName);
939
+ if (sourceY < 0 || destY < 0)
940
+ return '';
941
+ const cp1x = this.SVG_WIDTH * 0.35;
942
+ const cp2x = this.SVG_WIDTH * 0.65;
943
+ return `M 0 ${sourceY} C ${cp1x} ${sourceY}, ${cp2x} ${destY}, ${this.SVG_WIDTH} ${destY}`;
944
+ }
945
+ GetConnectionMidY(conn) {
946
+ const sourceY = this.getSourceFieldY(conn.SourceFieldName);
947
+ const destY = this.getDestFieldY(conn.DestFieldName);
948
+ return (sourceY + destY) / 2;
949
+ }
950
+ GetConnectionLineClass(conn) {
951
+ return `conn-${this.getPrimaryTransformType(conn)}`;
952
+ }
953
+ GetConnectionBadgeClass(conn) {
954
+ return `badge-${this.getPrimaryTransformType(conn)}`;
955
+ }
956
+ GetConnectionTransformIcon(conn) {
957
+ const type = this.getPrimaryTransformType(conn);
958
+ return this.TRANSFORM_TYPES.find(t => t.Value === type)?.Icon ?? 'fa-solid fa-arrow-right';
959
+ }
960
+ GetConnectionDirectionIcon(conn) {
961
+ switch (conn.Direction) {
962
+ case 'DestToSource': return 'fa-solid fa-arrow-left';
963
+ case 'Both': return 'fa-solid fa-right-left';
964
+ default: return 'fa-solid fa-arrow-right';
965
+ }
966
+ }
967
+ GetTransformTypeLabel(type) {
968
+ return this.TRANSFORM_TYPES.find(t => t.Value === type)?.Label ?? type;
969
+ }
970
+ // ---------------------------------------------------------------------------
971
+ // Field mapped state
972
+ // ---------------------------------------------------------------------------
973
+ IsSourceFieldMapped(fieldName) {
974
+ return this.EditorConnections.some(c => !c.MarkedForDelete && c.SourceFieldName === fieldName);
975
+ }
976
+ IsDestFieldMapped(fieldName) {
977
+ return this.EditorConnections.some(c => !c.MarkedForDelete && c.DestFieldName === fieldName);
978
+ }
979
+ // ---------------------------------------------------------------------------
980
+ // Creating connections
981
+ // ---------------------------------------------------------------------------
982
+ OnEditorSourceClick(fieldName) {
983
+ if (this.IsSourceFieldMapped(fieldName))
984
+ return;
985
+ if (this.ConnectingFromSource === fieldName) {
986
+ this.ConnectingFromSource = null;
987
+ }
988
+ else {
989
+ this.ConnectingFromSource = fieldName;
990
+ this.SelectedConnectionIdx = null;
991
+ }
992
+ this.cdr.detectChanges();
993
+ }
994
+ OnEditorDestClick(fieldName) {
995
+ if (!this.ConnectingFromSource)
996
+ return;
997
+ if (this.IsDestFieldMapped(fieldName))
998
+ return;
999
+ const existing = this.EditorConnections.find(c => !c.MarkedForDelete && c.SourceFieldName === this.ConnectingFromSource && c.DestFieldName === fieldName);
1000
+ if (existing) {
1001
+ this.ConnectingFromSource = null;
1002
+ return;
1003
+ }
1004
+ this.EditorConnections.push({
1005
+ ID: null,
1006
+ SourceFieldName: this.ConnectingFromSource,
1007
+ DestFieldName: fieldName,
1008
+ IsKeyField: false,
1009
+ IsRequired: false,
1010
+ Direction: 'SourceToDest',
1011
+ TransformSteps: [{ Type: 'direct', Config: {}, OnError: 'Fail' }],
1012
+ IsDirty: true,
1013
+ IsNew: true,
1014
+ MarkedForDelete: false
1015
+ });
1016
+ this.ConnectingFromSource = null;
1017
+ this.SelectedConnectionIdx = this.EditorConnections.length - 1;
1018
+ this.cdr.detectChanges();
1019
+ }
1020
+ CancelConnect() {
1021
+ this.ConnectingFromSource = null;
1022
+ this.cdr.detectChanges();
1023
+ }
1024
+ // ---------------------------------------------------------------------------
1025
+ // Connection selection / editing
1026
+ // ---------------------------------------------------------------------------
1027
+ SelectConnection(index, event) {
1028
+ event.stopPropagation();
1029
+ this.SelectedConnectionIdx = this.SelectedConnectionIdx === index ? null : index;
1030
+ this.ConnectingFromSource = null;
1031
+ this.cdr.detectChanges();
1032
+ }
1033
+ DeselectConnection() {
1034
+ this.SelectedConnectionIdx = null;
1035
+ this.cdr.detectChanges();
1036
+ }
1037
+ get SelectedConnection() {
1038
+ if (this.SelectedConnectionIdx == null)
1039
+ return null;
1040
+ return this.EditorConnections[this.SelectedConnectionIdx] ?? null;
1041
+ }
1042
+ RemoveSelectedConnection() {
1043
+ if (this.SelectedConnectionIdx == null)
1044
+ return;
1045
+ const conn = this.EditorConnections[this.SelectedConnectionIdx];
1046
+ if (conn.IsNew) {
1047
+ this.EditorConnections.splice(this.SelectedConnectionIdx, 1);
1048
+ }
1049
+ else {
1050
+ conn.MarkedForDelete = true;
1051
+ conn.IsDirty = true;
1052
+ }
1053
+ this.SelectedConnectionIdx = null;
1054
+ this.cdr.detectChanges();
1055
+ }
1056
+ ToggleConnectionKey() {
1057
+ const conn = this.SelectedConnection;
1058
+ if (!conn)
1059
+ return;
1060
+ conn.IsKeyField = !conn.IsKeyField;
1061
+ conn.IsDirty = true;
1062
+ this.cdr.detectChanges();
1063
+ }
1064
+ ToggleConnectionRequired() {
1065
+ const conn = this.SelectedConnection;
1066
+ if (!conn)
1067
+ return;
1068
+ conn.IsRequired = !conn.IsRequired;
1069
+ conn.IsDirty = true;
1070
+ this.cdr.detectChanges();
1071
+ }
1072
+ GetDirectionArrowClass(direction) {
1073
+ switch (direction) {
1074
+ case 'DestToSource': return 'fa-arrow-left';
1075
+ case 'Both': return 'fa-right-left';
1076
+ default: return 'fa-arrow-right';
1077
+ }
1078
+ }
1079
+ OnConnectionDirectionChange(direction) {
1080
+ const conn = this.SelectedConnection;
1081
+ if (!conn)
1082
+ return;
1083
+ conn.Direction = direction;
1084
+ conn.IsDirty = true;
1085
+ this.cdr.detectChanges();
1086
+ }
1087
+ OnConnectionTransformChange(stepIndex, type) {
1088
+ const conn = this.SelectedConnection;
1089
+ if (!conn || !conn.TransformSteps[stepIndex])
1090
+ return;
1091
+ conn.TransformSteps[stepIndex].Type = type;
1092
+ conn.TransformSteps[stepIndex].Config = this.getDefaultConfigForType(type);
1093
+ conn.IsDirty = true;
1094
+ this.cdr.detectChanges();
1095
+ }
1096
+ OnTransformConfigChange(conn, stepIndex, key, value) {
1097
+ if (!conn.TransformSteps[stepIndex])
1098
+ return;
1099
+ conn.TransformSteps[stepIndex].Config[key] = value;
1100
+ conn.IsDirty = true;
1101
+ }
1102
+ AddTransformStep() {
1103
+ const conn = this.SelectedConnection;
1104
+ if (!conn)
1105
+ return;
1106
+ conn.TransformSteps.push({ Type: 'direct', Config: {}, OnError: 'Fail' });
1107
+ conn.IsDirty = true;
1108
+ this.cdr.detectChanges();
1109
+ }
1110
+ RemoveTransformStep(stepIndex) {
1111
+ const conn = this.SelectedConnection;
1112
+ if (!conn)
1113
+ return;
1114
+ conn.TransformSteps.splice(stepIndex, 1);
1115
+ conn.IsDirty = true;
1116
+ this.cdr.detectChanges();
1117
+ }
1118
+ // ---------------------------------------------------------------------------
1119
+ // Data preview
1120
+ // ---------------------------------------------------------------------------
1121
+ async ToggleSourcePreview() {
1122
+ this.ShowSourcePreview = !this.ShowSourcePreview;
1123
+ if (this.ShowSourcePreview && this.PreviewSourceRows.length === 0) {
1124
+ await this.loadSourcePreview();
1125
+ }
1126
+ this.cdr.detectChanges();
1127
+ }
1128
+ async ToggleDestPreview() {
1129
+ this.ShowDestPreview = !this.ShowDestPreview;
1130
+ if (this.ShowDestPreview && this.PreviewDestRows.length === 0) {
1131
+ await this.loadDestPreview();
1132
+ }
1133
+ this.cdr.detectChanges();
1134
+ }
1135
+ async loadSourcePreview() {
1136
+ if (!this.EntityMap || !this.CompanyIntegrationID)
1137
+ return;
1138
+ this.PreviewSourceLoading = true;
1139
+ this.cdr.detectChanges();
1140
+ try {
1141
+ const rows = await this.dataService.PreviewSourceData(this.CompanyIntegrationID, this.EntityMap.ExternalObjectName, 5);
1142
+ this.PreviewSourceRows = rows;
1143
+ this.PreviewSourceColumns = rows.length > 0 ? Object.keys(rows[0]) : [];
1144
+ }
1145
+ catch (err) {
1146
+ console.error('[VisualFieldEditor] Failed to load source preview:', err);
1147
+ this.PreviewSourceRows = [];
1148
+ this.PreviewSourceColumns = [];
1149
+ }
1150
+ finally {
1151
+ this.PreviewSourceLoading = false;
1152
+ this.cdr.detectChanges();
1153
+ }
1154
+ }
1155
+ async loadDestPreview() {
1156
+ if (!this.EntityMap)
1157
+ return;
1158
+ this.PreviewDestLoading = true;
1159
+ this.cdr.detectChanges();
1160
+ try {
1161
+ const rows = await this.dataService.PreviewDestinationData(this.EntityMap.EntityID, 5, this.RunViewProvider);
1162
+ this.PreviewDestRows = rows;
1163
+ this.PreviewDestColumns = rows.length > 0 ? Object.keys(rows[0]) : [];
1164
+ }
1165
+ catch (err) {
1166
+ console.error('[VisualFieldEditor] Failed to load dest preview:', err);
1167
+ this.PreviewDestRows = [];
1168
+ this.PreviewDestColumns = [];
1169
+ }
1170
+ finally {
1171
+ this.PreviewDestLoading = false;
1172
+ this.cdr.detectChanges();
1173
+ }
1174
+ }
1175
+ // ---------------------------------------------------------------------------
1176
+ // Collapsible sections
1177
+ // ---------------------------------------------------------------------------
1178
+ ToggleFieldMaps() {
1179
+ this.FieldMapsExpanded = !this.FieldMapsExpanded;
1180
+ this.cdr.detectChanges();
1181
+ }
1182
+ ToggleInfoPanel() {
1183
+ this.InfoPanelExpanded = !this.InfoPanelExpanded;
1184
+ if (this.InfoPanelExpanded && this.InfoDestRecordCount === null) {
1185
+ this.loadInfoPanelData();
1186
+ }
1187
+ this.cdr.detectChanges();
1188
+ }
1189
+ async loadInfoPanelData() {
1190
+ if (!this.EntityMap || !this.CompanyIntegrationID)
1191
+ return;
1192
+ this.InfoPanelLoading = true;
1193
+ this.cdr.detectChanges();
1194
+ try {
1195
+ const [destCount, lastSync] = await Promise.all([
1196
+ this.dataService.GetDestinationRecordCount(this.EntityMap.EntityID, this.RunViewProvider),
1197
+ this.dataService.GetLastSyncForEntity(this.CompanyIntegrationID, this.EntityMap.EntityID, this.RunViewProvider)
1198
+ ]);
1199
+ this.InfoDestRecordCount = destCount;
1200
+ this.InfoLastSync = lastSync;
1201
+ }
1202
+ catch (err) {
1203
+ console.error('[VisualFieldEditor] Failed to load info panel data:', err);
1204
+ }
1205
+ finally {
1206
+ this.InfoPanelLoading = false;
1207
+ this.cdr.detectChanges();
1208
+ }
1209
+ }
1210
+ FormatSyncDate(dateStr) {
1211
+ if (!dateStr)
1212
+ return 'Never';
1213
+ const d = new Date(dateStr);
1214
+ const now = new Date();
1215
+ const diffMs = now.getTime() - d.getTime();
1216
+ const diffMins = Math.floor(diffMs / 60000);
1217
+ if (diffMins < 1)
1218
+ return 'Just now';
1219
+ if (diffMins < 60)
1220
+ return `${diffMins}m ago`;
1221
+ const diffHours = Math.floor(diffMins / 60);
1222
+ if (diffHours < 24)
1223
+ return `${diffHours}h ago`;
1224
+ const diffDays = Math.floor(diffHours / 24);
1225
+ if (diffDays < 7)
1226
+ return `${diffDays}d ago`;
1227
+ return d.toLocaleDateString();
1228
+ }
1229
+ SyncStatusClass(status) {
1230
+ switch (status) {
1231
+ case 'Success': return 'info-status-success';
1232
+ case 'Failed': return 'info-status-error';
1233
+ case 'In Progress': return 'info-status-running';
1234
+ default: return 'info-status-pending';
1235
+ }
1236
+ }
1237
+ // ---------------------------------------------------------------------------
1238
+ // Save / Auto-map
1239
+ // ---------------------------------------------------------------------------
1240
+ get HasEditorChanges() {
1241
+ return this.EditorConnections.some(c => c.IsDirty);
1242
+ }
1243
+ async SaveVisualEditor() {
1244
+ if (!this.EntityMap)
1245
+ return;
1246
+ this.EditorSaving = true;
1247
+ this.EditorSaveSuccess = false;
1248
+ this.cdr.detectChanges();
1249
+ try {
1250
+ for (const conn of this.EditorConnections) {
1251
+ if (!conn.IsDirty)
1252
+ continue;
1253
+ if (conn.MarkedForDelete && conn.ID) {
1254
+ await this.dataService.DeleteFieldMap(conn.ID);
1255
+ }
1256
+ else if (conn.IsNew && !conn.MarkedForDelete) {
1257
+ await this.dataService.CreateFieldMap({
1258
+ EntityMapID: this.EntityMap.ID,
1259
+ SourceFieldName: conn.SourceFieldName,
1260
+ DestinationFieldName: conn.DestFieldName,
1261
+ IsKeyField: conn.IsKeyField,
1262
+ IsRequired: conn.IsRequired,
1263
+ Direction: conn.Direction,
1264
+ TransformPipeline: this.serializeTransformPipeline(conn.TransformSteps)
1265
+ });
1266
+ }
1267
+ else if (conn.ID && !conn.MarkedForDelete) {
1268
+ await this.dataService.UpdateFieldMap(conn.ID, {
1269
+ SourceFieldName: conn.SourceFieldName,
1270
+ DestinationFieldName: conn.DestFieldName,
1271
+ IsKeyField: conn.IsKeyField,
1272
+ IsRequired: conn.IsRequired,
1273
+ Direction: conn.Direction,
1274
+ TransformPipeline: this.serializeTransformPipeline(conn.TransformSteps)
1275
+ });
1276
+ }
1277
+ }
1278
+ await this.LoadVisualEditorData();
1279
+ this.EditorSaveSuccess = true;
1280
+ this.SelectedConnectionIdx = null;
1281
+ }
1282
+ catch (err) {
1283
+ console.error('[VisualFieldEditor] Failed to save field mappings:', err);
1284
+ }
1285
+ finally {
1286
+ this.EditorSaving = false;
1287
+ this.cdr.detectChanges();
1288
+ }
1289
+ }
1290
+ async AutoMapEditorFields() {
1291
+ if (!this.EntityMap || !this.CompanyIntegrationID)
1292
+ return;
1293
+ const destMap = new Map();
1294
+ for (const df of this.EditorDestFields) {
1295
+ destMap.set(df.Name.toLowerCase(), df);
1296
+ }
1297
+ let addedCount = 0;
1298
+ for (const sf of this.EditorSourceFields) {
1299
+ if (this.IsSourceFieldMapped(sf.Name))
1300
+ continue;
1301
+ const destMatch = destMap.get(sf.Name.toLowerCase());
1302
+ if (!destMatch)
1303
+ continue;
1304
+ if (this.IsDestFieldMapped(destMatch.Name))
1305
+ continue;
1306
+ this.EditorConnections.push({
1307
+ ID: null,
1308
+ SourceFieldName: sf.Name,
1309
+ DestFieldName: destMatch.Name,
1310
+ IsKeyField: sf.IsPrimaryKey,
1311
+ IsRequired: sf.IsRequired || destMatch.IsRequired,
1312
+ Direction: 'SourceToDest',
1313
+ TransformSteps: [{ Type: 'direct', Config: {}, OnError: 'Fail' }],
1314
+ IsDirty: true,
1315
+ IsNew: true,
1316
+ MarkedForDelete: false
1317
+ });
1318
+ addedCount++;
1319
+ }
1320
+ if (addedCount > 0) {
1321
+ this.cdr.detectChanges();
1322
+ }
1323
+ }
1324
+ // ---------------------------------------------------------------------------
1325
+ // Computed props
1326
+ // ---------------------------------------------------------------------------
1327
+ get EditorMappedCount() {
1328
+ return this.EditorConnections.filter(c => !c.MarkedForDelete).length;
1329
+ }
1330
+ get EditorKeyFieldCount() {
1331
+ return this.EditorConnections.filter(c => !c.MarkedForDelete && c.IsKeyField).length;
1332
+ }
1333
+ get EditorRequiredCount() {
1334
+ return this.EditorConnections.filter(c => !c.MarkedForDelete && c.IsRequired).length;
1335
+ }
1336
+ GetConfigKeys(step) {
1337
+ return Object.keys(step.Config);
1338
+ }
1339
+ GetConfigValue(step, key) {
1340
+ const val = step.Config[key];
1341
+ if (val == null)
1342
+ return '';
1343
+ if (typeof val === 'object')
1344
+ return JSON.stringify(val);
1345
+ return String(val);
1346
+ }
1347
+ // ---------------------------------------------------------------------------
1348
+ // Private helpers
1349
+ // ---------------------------------------------------------------------------
1350
+ getSourceFieldIndex(fieldName) {
1351
+ return this.FilteredEditorSourceFields.findIndex(f => f.Name === fieldName);
1352
+ }
1353
+ getDestFieldIndex(fieldName) {
1354
+ return this.FilteredEditorDestFields.findIndex(f => f.Name === fieldName);
1355
+ }
1356
+ getSourceFieldY(fieldName) {
1357
+ const idx = this.getSourceFieldIndex(fieldName);
1358
+ if (idx < 0)
1359
+ return -1;
1360
+ return idx * this.FIELD_HEIGHT + this.FIELD_HEIGHT / 2;
1361
+ }
1362
+ getDestFieldY(fieldName) {
1363
+ const idx = this.getDestFieldIndex(fieldName);
1364
+ if (idx < 0)
1365
+ return -1;
1366
+ return idx * this.FIELD_HEIGHT + this.FIELD_HEIGHT / 2;
1367
+ }
1368
+ getPrimaryTransformType(conn) {
1369
+ if (conn.TransformSteps.length === 0)
1370
+ return 'direct';
1371
+ return conn.TransformSteps[0].Type;
1372
+ }
1373
+ parseTransformPipeline(json) {
1374
+ if (!json || json.trim() === '')
1375
+ return [];
1376
+ try {
1377
+ const parsed = JSON.parse(json);
1378
+ if (!Array.isArray(parsed))
1379
+ return [];
1380
+ return parsed.map(step => ({
1381
+ Type: step.Type ?? 'direct',
1382
+ Config: step.Config ?? {},
1383
+ OnError: step.OnError ?? 'Fail'
1384
+ }));
1385
+ }
1386
+ catch {
1387
+ return [];
1388
+ }
1389
+ }
1390
+ serializeTransformPipeline(steps) {
1391
+ if (steps.length === 0)
1392
+ return null;
1393
+ return JSON.stringify(steps.map(s => ({ Type: s.Type, Config: s.Config, OnError: s.OnError })));
1394
+ }
1395
+ getDefaultConfigForType(type) {
1396
+ switch (type) {
1397
+ case 'direct': return {};
1398
+ case 'regex': return { Pattern: '', Replacement: '', Flags: 'g' };
1399
+ case 'split': return { Delimiter: ',', Index: 0 };
1400
+ case 'combine': return { SourceFields: [], Separator: ' ' };
1401
+ case 'lookup': return { Map: {}, Default: '' };
1402
+ case 'format': return { FormatString: '', FormatType: 'date' };
1403
+ case 'coerce': return { TargetType: 'string' };
1404
+ case 'substring': return { Start: 0, Length: 10 };
1405
+ case 'custom': return { Expression: 'value' };
1406
+ }
1407
+ }
1408
+ resolveSourceFieldsFromMetadata(companyIntegrationID, externalObjectName) {
1409
+ const engine = IntegrationEngineBase.Instance;
1410
+ const integration = engine.GetIntegrationForCompanyIntegration(companyIntegrationID);
1411
+ if (!integration)
1412
+ return [];
1413
+ const obj = engine.GetIntegrationObject(integration.ID, externalObjectName);
1414
+ if (!obj)
1415
+ return [];
1416
+ const fields = engine.GetIntegrationObjectFields(obj.ID);
1417
+ return fields
1418
+ .filter(f => f.Status === 'Active')
1419
+ .sort((a, b) => a.Sequence - b.Sequence)
1420
+ .map(f => ({
1421
+ Name: f.Name,
1422
+ Label: f.DisplayName || f.Name,
1423
+ Type: f.Type,
1424
+ IsRequired: f.IsRequired,
1425
+ IsPrimaryKey: f.IsPrimaryKey
1426
+ }));
1427
+ }
1428
+ static ɵfac = function VisualFieldEditorComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || VisualFieldEditorComponent)(); };
1429
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: VisualFieldEditorComponent, selectors: [["app-visual-field-editor"]], inputs: { EntityMap: "EntityMap", CompanyIntegrationID: "CompanyIntegrationID", RunViewProvider: "RunViewProvider" }, outputs: { Close: "Close" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 48, vars: 18, consts: [[1, "ve-container"], [1, "ve-header"], [1, "ve-header-left"], ["title", "Back to entity maps", 1, "ve-back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "ve-header-title"], [1, "ve-source-label"], [1, "ve-direction-arrow"], [1, "fa-solid", "fa-arrow-right-arrow-left"], [1, "ve-dest-label"], [1, "ve-header-stats"], [1, "ve-stat"], [1, "ve-stat-sep"], [1, "ve-header-actions"], ["title", "Preview source data", 1, "ve-btn", "ve-btn-ghost", 3, "click"], [1, "fa-solid", "fa-cloud"], ["title", "Preview MJ data", 1, "ve-btn", "ve-btn-ghost", 3, "click"], [1, "fa-solid", "fa-database"], [1, "ve-action-sep"], ["title", "Auto-map fields by name", 1, "ve-btn", "ve-btn-ghost", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "ve-btn", "ve-btn-primary", 3, "click", "disabled"], [1, "ve-save-success"], [1, "ve-preview-strip"], [1, "ve-connect-banner"], [1, "ve-body"], [1, "ve-loading"], [1, "sync-toggle", "ve-sync-toggle", 3, "title"], ["type", "checkbox", 3, "change", "checked"], [1, "sync-toggle-track"], [1, "ve-sync-label"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-check"], [1, "fa-solid", "fa-circle-check"], [1, "ve-preview-panel"], [1, "ve-preview-header"], [1, "ve-preview-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ve-preview-loading"], [1, "ve-preview-empty"], [1, "ve-preview-table-wrap"], [1, "ve-preview-table"], [3, "title"], [1, "fa-solid", "fa-link"], [1, "ve-connect-cancel", 3, "click"], [1, "ve-sections-wrapper"], [1, "ve-section"], [1, "ve-section-header", 3, "click"], [1, "fa-solid"], [1, "ve-section-title"], [1, "ve-section-badge"], [1, "ve-section-body"], [1, "ve-section-body", "ve-info-body"], [1, "ve-transform-panel"], [1, "ve-canvas-wrapper"], [1, "ve-col-headers"], [1, "ve-col-header", "source"], [1, "ve-col-count"], [1, "ve-col-header-spacer"], [1, "ve-col-header", "dest"], [1, "ve-col-searches"], [1, "ve-col-search"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Filter source fields...", 3, "input", "value"], [1, "ve-col-search-spacer"], ["type", "text", "placeholder", "Filter destination fields...", 3, "input", "value"], [1, "ve-canvas-scroll", 3, "click"], [1, "ve-canvas-grid"], [1, "ve-field-col", "source"], [1, "ve-field-item", 3, "mapped", "unmapped", "connecting", "height"], [1, "ve-field-empty"], [1, "ve-svg", 3, "click"], [1, "ve-field-col", "dest"], [1, "ve-field-item", 3, "mapped", "unmapped", "connect-target", "height"], [1, "ve-field-item", 3, "click"], [1, "ve-field-name", 3, "title"], [1, "ve-field-type"], [1, "ve-field-badges"], ["title", "Primary Key", 1, "ve-fbadge", "pk"], ["title", "Required", 1, "ve-fbadge", "req"], [1, "ve-conn-line", 3, "click"], ["width", "28", "height", "28", 1, "ve-badge-fo"], ["xmlns", "http://www.w3.org/1999/xhtml", 1, "ve-conn-badge", 3, "click"], [1, "ve-info-loading"], [1, "ve-info-grid"], [1, "ve-info-card"], [1, "ve-info-card-icon"], [1, "ve-info-card-content"], [1, "ve-info-card-value"], [1, "ve-info-card-label"], [1, "ve-info-card-icon", "source"], [1, "ve-info-card-icon", "sync"], [1, "fa-solid", "fa-arrows-rotate"], [1, "ve-info-details"], [1, "ve-info-detail-row"], [1, "ve-info-detail-label"], [1, "ve-info-detail-value"], [1, "ve-info-card-icon", 3, "ngClass"], [1, "ve-transform-panel", 3, "click"], [1, "ve-tp-header"], [1, "ve-tp-title"], [1, "ve-tp-close", 3, "click"], [1, "ve-tp-mapping-info"], [1, "ve-tp-field-pair"], [1, "ve-tp-field", "source"], [1, "fa-solid", "ve-tp-arrow"], [1, "ve-tp-field", "dest"], [1, "ve-tp-toggles"], [1, "ve-tp-toggle", 3, "click"], [1, "ve-tp-toggle-box"], [1, "ve-tp-section"], [1, "ve-tp-section-label"], [1, "ve-tp-direction-btns"], [3, "click"], [1, "ve-tp-section-header"], [1, "ve-tp-add-step", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "ve-tp-step"], [1, "ve-tp-no-steps"], [1, "ve-tp-footer"], [1, "ve-btn", "ve-btn-danger", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "ve-tp-step-header"], [1, "ve-tp-step-num"], [1, "ve-tp-type-select", 3, "change", "value"], [3, "value", "selected"], ["title", "Remove step", 1, "ve-tp-remove-step", 3, "click"], [1, "ve-tp-step-config"], [1, "ve-tp-step-onerror"], [3, "change", "value"], ["value", "Fail"], ["value", "Skip"], ["value", "Null"], [1, "ve-tp-config-row"], ["type", "text", 3, "input", "value", "placeholder"]], template: function VisualFieldEditorComponent_Template(rf, ctx) { if (rf & 1) {
1430
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "button", 3);
1431
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Template_button_click_3_listener() { return ctx.OnClose(); });
1432
+ i0.ɵɵelement(4, "i", 4);
1433
+ i0.ɵɵelementEnd();
1434
+ i0.ɵɵelementStart(5, "div", 5)(6, "span", 6);
1435
+ i0.ɵɵtext(7);
1436
+ i0.ɵɵelementEnd();
1437
+ i0.ɵɵelementStart(8, "span", 7);
1438
+ i0.ɵɵelement(9, "i", 8);
1439
+ i0.ɵɵelementEnd();
1440
+ i0.ɵɵelementStart(10, "span", 9);
1441
+ i0.ɵɵtext(11);
1442
+ i0.ɵɵelementEnd()();
1443
+ i0.ɵɵconditionalCreate(12, VisualFieldEditorComponent_Conditional_12_Template, 5, 3);
1444
+ i0.ɵɵelementEnd();
1445
+ i0.ɵɵelementStart(13, "div", 10)(14, "span", 11)(15, "strong");
1446
+ i0.ɵɵtext(16);
1447
+ i0.ɵɵelementEnd();
1448
+ i0.ɵɵtext(17, " mapped ");
1449
+ i0.ɵɵelementEnd();
1450
+ i0.ɵɵelement(18, "span", 12);
1451
+ i0.ɵɵelementStart(19, "span", 11)(20, "strong");
1452
+ i0.ɵɵtext(21);
1453
+ i0.ɵɵelementEnd();
1454
+ i0.ɵɵtext(22, " key ");
1455
+ i0.ɵɵelementEnd();
1456
+ i0.ɵɵelement(23, "span", 12);
1457
+ i0.ɵɵelementStart(24, "span", 11)(25, "strong");
1458
+ i0.ɵɵtext(26);
1459
+ i0.ɵɵelementEnd();
1460
+ i0.ɵɵtext(27, " required ");
1461
+ i0.ɵɵelementEnd()();
1462
+ i0.ɵɵelementStart(28, "div", 13)(29, "button", 14);
1463
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Template_button_click_29_listener() { return ctx.ToggleSourcePreview(); });
1464
+ i0.ɵɵelement(30, "i", 15);
1465
+ i0.ɵɵtext(31, " Source Data ");
1466
+ i0.ɵɵelementEnd();
1467
+ i0.ɵɵelementStart(32, "button", 16);
1468
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Template_button_click_32_listener() { return ctx.ToggleDestPreview(); });
1469
+ i0.ɵɵelement(33, "i", 17);
1470
+ i0.ɵɵtext(34, " MJ Data ");
1471
+ i0.ɵɵelementEnd();
1472
+ i0.ɵɵelement(35, "div", 18);
1473
+ i0.ɵɵelementStart(36, "button", 19);
1474
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Template_button_click_36_listener() { return ctx.AutoMapEditorFields(); });
1475
+ i0.ɵɵelement(37, "i", 20);
1476
+ i0.ɵɵtext(38, " Auto-Map ");
1477
+ i0.ɵɵelementEnd();
1478
+ i0.ɵɵelementStart(39, "button", 21);
1479
+ i0.ɵɵlistener("click", function VisualFieldEditorComponent_Template_button_click_39_listener() { return ctx.SaveVisualEditor(); });
1480
+ i0.ɵɵconditionalCreate(40, VisualFieldEditorComponent_Conditional_40_Template, 2, 0)(41, VisualFieldEditorComponent_Conditional_41_Template, 2, 0);
1481
+ i0.ɵɵelementEnd();
1482
+ i0.ɵɵconditionalCreate(42, VisualFieldEditorComponent_Conditional_42_Template, 3, 0, "span", 22);
1483
+ i0.ɵɵelementEnd()();
1484
+ i0.ɵɵconditionalCreate(43, VisualFieldEditorComponent_Conditional_43_Template, 3, 2, "div", 23);
1485
+ i0.ɵɵconditionalCreate(44, VisualFieldEditorComponent_Conditional_44_Template, 7, 1, "div", 24);
1486
+ i0.ɵɵelementStart(45, "div", 25);
1487
+ i0.ɵɵconditionalCreate(46, VisualFieldEditorComponent_Conditional_46_Template, 4, 0, "div", 26)(47, VisualFieldEditorComponent_Conditional_47_Template, 16, 16);
1488
+ i0.ɵɵelementEnd()();
1489
+ } if (rf & 2) {
1490
+ i0.ɵɵadvance(7);
1491
+ i0.ɵɵtextInterpolate((ctx.EntityMap == null ? null : ctx.EntityMap.ExternalObjectLabel) ?? (ctx.EntityMap == null ? null : ctx.EntityMap.ExternalObjectName));
1492
+ i0.ɵɵadvance(4);
1493
+ i0.ɵɵtextInterpolate(ctx.EntityMap == null ? null : ctx.EntityMap.Entity);
1494
+ i0.ɵɵadvance();
1495
+ i0.ɵɵconditional(ctx.EntityMap ? 12 : -1);
1496
+ i0.ɵɵadvance(4);
1497
+ i0.ɵɵtextInterpolate(ctx.EditorMappedCount);
1498
+ i0.ɵɵadvance(5);
1499
+ i0.ɵɵtextInterpolate(ctx.EditorKeyFieldCount);
1500
+ i0.ɵɵadvance(5);
1501
+ i0.ɵɵtextInterpolate(ctx.EditorRequiredCount);
1502
+ i0.ɵɵadvance(3);
1503
+ i0.ɵɵclassProp("active", ctx.ShowSourcePreview);
1504
+ i0.ɵɵadvance(3);
1505
+ i0.ɵɵclassProp("active", ctx.ShowDestPreview);
1506
+ i0.ɵɵadvance(7);
1507
+ i0.ɵɵproperty("disabled", !ctx.HasEditorChanges || ctx.EditorSaving);
1508
+ i0.ɵɵadvance();
1509
+ i0.ɵɵconditional(ctx.EditorSaving ? 40 : 41);
1510
+ i0.ɵɵadvance(2);
1511
+ i0.ɵɵconditional(ctx.EditorSaveSuccess && !ctx.HasEditorChanges ? 42 : -1);
1512
+ i0.ɵɵadvance();
1513
+ i0.ɵɵconditional(ctx.ShowSourcePreview || ctx.ShowDestPreview ? 43 : -1);
1514
+ i0.ɵɵadvance();
1515
+ i0.ɵɵconditional(ctx.ConnectingFromSource ? 44 : -1);
1516
+ i0.ɵɵadvance();
1517
+ i0.ɵɵclassProp("has-transform-panel", ctx.SelectedConnectionIdx !== null);
1518
+ i0.ɵɵadvance();
1519
+ i0.ɵɵconditional(ctx.EditorLoading ? 46 : 47);
1520
+ } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.ve-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mj-bg-surface);\n animation: _ngcontent-%COMP%_slideIn 250ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from { opacity: 0; transform: translateX(30px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n\n\n\n.ve-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 16px;\n}\n\n.ve-header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.ve-back-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 14px;\n flex-shrink: 0;\n transition: all 150ms ease;\n}\n\n.ve-back-btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n.ve-header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 15px;\n font-weight: 600;\n min-width: 0;\n}\n\n.ve-source-label[_ngcontent-%COMP%] {\n color: var(--mj-color-indigo-500);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n.ve-direction-arrow[_ngcontent-%COMP%] { color: var(--mj-text-disabled); font-size: 13px; flex-shrink: 0; }\n\n.ve-dest-label[_ngcontent-%COMP%] {\n color: var(--mj-color-success-600);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n.ve-header-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.ve-stat[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.ve-stat[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 700;\n}\n\n.ve-stat-sep[_ngcontent-%COMP%] {\n width: 1px;\n height: 14px;\n background: var(--mj-border-default);\n}\n\n.ve-header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.ve-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n border: none;\n white-space: nowrap;\n}\n\n.ve-btn-ghost[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.ve-btn-ghost[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-primary); }\n\n.ve-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-color-indigo-500);\n color: var(--mj-bg-surface);\n}\n\n.ve-btn-primary[_ngcontent-%COMP%]:hover { background: var(--mj-color-indigo-600); }\n.ve-btn-primary[_ngcontent-%COMP%]:disabled { opacity: 0.5; cursor: default; }\n\n.ve-btn-danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-color-error-600);\n border: 1px solid var(--mj-color-error-200);\n}\n\n.ve-btn-danger[_ngcontent-%COMP%]:hover { background: var(--mj-color-error-100); }\n\n.ve-save-success[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-color-success-600);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 4px;\n animation: _ngcontent-%COMP%_fadeIn 300ms ease;\n}\n\n\n\n.ve-sync-toggle[_ngcontent-%COMP%] { flex-shrink: 0; margin-left: 8px; }\n.ve-sync-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n\n\n.sync-toggle[_ngcontent-%COMP%] {\n position: relative;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n}\n\n.sync-toggle[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n}\n\n.sync-toggle-track[_ngcontent-%COMP%] {\n width: 34px;\n height: 18px;\n background: var(--mj-color-neutral-300);\n border-radius: 9px;\n position: relative;\n transition: background 200ms ease;\n}\n\n.sync-toggle-track[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n transition: transform 200ms ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);\n}\n\n.sync-toggle[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:checked + .sync-toggle-track[_ngcontent-%COMP%] {\n background: var(--mj-color-success-500);\n}\n\n.sync-toggle[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:checked + .sync-toggle-track[_ngcontent-%COMP%]::after {\n transform: translateX(16px);\n}\n\n\n\n.ve-action-sep[_ngcontent-%COMP%] {\n width: 1px;\n height: 20px;\n background: var(--mj-border-default);\n flex-shrink: 0;\n}\n\n\n\n.ve-btn-ghost.active[_ngcontent-%COMP%] {\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-600);\n border-color: var(--mj-color-indigo-200);\n}\n\n\n\n\n\n\n.ve-preview-strip[_ngcontent-%COMP%] {\n display: flex;\n gap: 1px;\n background: var(--mj-border-default);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 220px;\n flex-shrink: 0;\n overflow: hidden;\n}\n\n.ve-preview-panel[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n}\n\n.ve-preview-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.ve-preview-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-color-indigo-500); }\n.ve-preview-header[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n.ve-preview-close[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.ve-preview-close[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-secondary); }\n\n.ve-preview-loading[_ngcontent-%COMP%], \n.ve-preview-empty[_ngcontent-%COMP%] {\n padding: 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.ve-preview-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { margin-right: 6px; color: var(--mj-color-indigo-500); }\n\n.ve-preview-table-wrap[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n}\n\n.ve-preview-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 11px;\n}\n\n.ve-preview-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-muted);\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n font-size: 10px;\n padding: 5px 10px;\n text-align: left;\n white-space: nowrap;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.ve-preview-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 4px 10px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.ve-preview-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover td[_ngcontent-%COMP%] {\n background: var(--mj-color-indigo-50);\n}\n\n\n\n\n\n\n.ve-connect-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 20px;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-700);\n font-size: 13px;\n border-bottom: 1px solid var(--mj-color-indigo-100);\n flex-shrink: 0;\n}\n\n.ve-connect-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] { font-weight: 700; }\n\n.ve-connect-cancel[_ngcontent-%COMP%] {\n margin-left: auto;\n padding: 3px 10px;\n border: 1px solid var(--mj-color-indigo-100);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-color-indigo-700);\n font-size: 12px;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.ve-connect-cancel[_ngcontent-%COMP%]:hover { background: var(--mj-color-indigo-100); }\n\n\n\n\n\n\n.ve-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.ve-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: 12px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.ve-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 24px; color: var(--mj-color-indigo-500); }\n\n\n\n.ve-sections-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n\n\n.ve-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.ve-section[_ngcontent-%COMP%]:not(.collapsed) {\n flex: 1;\n min-height: 0;\n}\n\n.ve-section.collapsed[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.ve-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n cursor: pointer;\n user-select: none;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n transition: background 150ms ease;\n}\n\n.ve-section-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.ve-section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-disabled);\n width: 12px;\n flex-shrink: 0;\n transition: transform 200ms ease;\n}\n\n.ve-section-title[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n color: var(--mj-text-muted);\n}\n\n.ve-section-badge[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-600);\n padding: 1px 8px;\n border-radius: 4px;\n margin-left: auto;\n}\n\n.ve-section-body[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n animation: _ngcontent-%COMP%_fadeIn 200ms ease;\n}\n\n\n\n.ve-canvas-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n\n\n\n\n\n.ve-col-headers[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-col-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n}\n\n.ve-col-header.source[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-color-indigo-500); }\n.ve-col-header.dest[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-color-success-600); }\n.ve-col-header-spacer[_ngcontent-%COMP%] { \n }\n\n.ve-col-count[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-disabled);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n\n\n\n\n\n.ve-col-searches[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 6px 0;\n}\n\n.ve-col-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 12px;\n}\n\n.ve-col-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.ve-col-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-page);\n outline: none;\n transition: border-color 150ms ease;\n}\n\n.ve-col-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus { border-color: var(--mj-color-indigo-500); background: var(--mj-bg-surface); }\n.ve-col-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-color-neutral-300); }\n.ve-col-search-spacer[_ngcontent-%COMP%] { \n }\n\n\n\n\n\n\n.ve-canvas-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.ve-canvas-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n position: relative;\n}\n\n\n\n\n\n\n.ve-field-col[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.ve-field-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 14px;\n font-size: 13px;\n cursor: pointer;\n transition: background 150ms ease, opacity 150ms ease;\n border-bottom: 1px solid var(--mj-bg-page);\n box-sizing: border-box;\n}\n\n.ve-field-item.mapped[_ngcontent-%COMP%] { background: var(--mj-bg-surface); }\n\n.ve-field-item.unmapped[_ngcontent-%COMP%] {\n opacity: 0.5;\n background: var(--mj-bg-page);\n}\n\n.ve-field-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-indigo-50);\n opacity: 1;\n}\n\n.ve-field-item.connecting[_ngcontent-%COMP%] {\n background: var(--mj-color-indigo-100);\n opacity: 1;\n box-shadow: inset 0 0 0 2px var(--mj-color-indigo-500);\n}\n\n.ve-field-item.connect-target[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-success-100);\n box-shadow: inset 0 0 0 2px var(--mj-color-success-600);\n}\n\n.ve-field-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--mj-color-neutral-700);\n font-weight: 500;\n}\n\n.ve-field-type[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n font-family: 'SF Mono', 'Fira Code', monospace;\n}\n\n.ve-field-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 3px;\n flex-shrink: 0;\n}\n\n.ve-fbadge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 3px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n}\n\n.ve-fbadge.pk[_ngcontent-%COMP%] { background: var(--mj-color-warning-100); color: var(--mj-color-warning-700); }\n.ve-fbadge.req[_ngcontent-%COMP%] { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n\n.ve-field-empty[_ngcontent-%COMP%] {\n padding: 32px 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n\n\n\n.ve-svg[_ngcontent-%COMP%] {\n display: block;\n}\n\n.ve-conn-line[_ngcontent-%COMP%] {\n fill: none;\n stroke-width: 2;\n cursor: pointer;\n transition: stroke 200ms ease, stroke-width 200ms ease;\n}\n\n\n\n.ve-conn-line.conn-direct[_ngcontent-%COMP%] { stroke: #6366f1; stroke-dasharray: none; }\n.ve-conn-line.conn-regex[_ngcontent-%COMP%] { stroke: #8b5cf6; stroke-dasharray: 6 3; }\n.ve-conn-line.conn-split[_ngcontent-%COMP%] { stroke: #f59e0b; stroke-dasharray: 8 4; }\n.ve-conn-line.conn-combine[_ngcontent-%COMP%] { stroke: #10b981; stroke-dasharray: 8 4; }\n.ve-conn-line.conn-lookup[_ngcontent-%COMP%] { stroke: #0ea5e9; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-format[_ngcontent-%COMP%] { stroke: #ec4899; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-coerce[_ngcontent-%COMP%] { stroke: #f97316; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-substring[_ngcontent-%COMP%] { stroke: #14b8a6; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-custom[_ngcontent-%COMP%] { stroke: #a855f7; stroke-dasharray: 2 3; }\n\n.ve-conn-line[_ngcontent-%COMP%]:hover { stroke-width: 3.5; }\n.ve-conn-line.selected[_ngcontent-%COMP%] { stroke-width: 3.5; filter: drop-shadow(0 0 4px rgba(99, 102, 241, 0.4)); }\n\n\n\n.ve-badge-fo[_ngcontent-%COMP%] { overflow: visible; }\n\n.ve-conn-badge[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n cursor: pointer;\n transition: all 150ms ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n}\n\n.ve-conn-badge.badge-direct[_ngcontent-%COMP%] { background: #eef2ff; color: #6366f1; border: 2px solid #6366f1; }\n.ve-conn-badge.badge-regex[_ngcontent-%COMP%] { background: #f5f3ff; color: #8b5cf6; border: 2px solid #8b5cf6; }\n.ve-conn-badge.badge-split[_ngcontent-%COMP%] { background: #fffbeb; color: #f59e0b; border: 2px solid #f59e0b; }\n.ve-conn-badge.badge-combine[_ngcontent-%COMP%] { background: #ecfdf5; color: #10b981; border: 2px solid #10b981; }\n.ve-conn-badge.badge-lookup[_ngcontent-%COMP%] { background: #f0f9ff; color: #0ea5e9; border: 2px solid #0ea5e9; }\n.ve-conn-badge.badge-format[_ngcontent-%COMP%] { background: #fdf2f8; color: #ec4899; border: 2px solid #ec4899; }\n.ve-conn-badge.badge-coerce[_ngcontent-%COMP%] { background: #fff7ed; color: #f97316; border: 2px solid #f97316; }\n.ve-conn-badge.badge-substring[_ngcontent-%COMP%] { background: #f0fdfa; color: #14b8a6; border: 2px solid #14b8a6; }\n.ve-conn-badge.badge-custom[_ngcontent-%COMP%] { background: #faf5ff; color: #a855f7; border: 2px solid #a855f7; }\n\n.ve-conn-badge[_ngcontent-%COMP%]:hover { transform: scale(1.2); }\n.ve-conn-badge.selected[_ngcontent-%COMP%] { transform: scale(1.25); box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3); }\n\n\n\n\n\n\n.ve-transform-panel[_ngcontent-%COMP%] {\n width: 320px;\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n background: var(--mj-bg-page);\n animation: _ngcontent-%COMP%_slideInRight 200ms ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideInRight {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n.ve-tp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.ve-tp-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.ve-tp-close[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.ve-tp-close[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-secondary); }\n\n\n\n.ve-tp-mapping-info[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-field-pair[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.ve-tp-field[_ngcontent-%COMP%] {\n padding: 4px 10px;\n border-radius: 6px;\n font-weight: 600;\n font-size: 12px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 110px;\n}\n\n.ve-tp-field.source[_ngcontent-%COMP%] { background: var(--mj-color-indigo-50); color: var(--mj-color-indigo-700); }\n.ve-tp-field.dest[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-color-success-700); }\n.ve-tp-arrow[_ngcontent-%COMP%] { color: var(--mj-text-disabled); font-size: 11px; flex-shrink: 0; }\n\n\n\n.ve-tp-toggles[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.ve-tp-toggle-box[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n color: var(--mj-bg-surface);\n transition: all 150ms ease;\n}\n\n.ve-tp-toggle-box.active[_ngcontent-%COMP%] {\n background: var(--mj-color-indigo-500);\n border-color: var(--mj-color-indigo-500);\n}\n\n\n\n.ve-tp-section[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-section-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 8px;\n}\n\n.ve-tp-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n\n\n.ve-tp-direction-btns[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.ve-tp-direction-btns[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n padding: 6px 8px;\n border: none;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.ve-tp-direction-btns[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:last-child { border-right: none; }\n.ve-tp-direction-btns[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.ve-tp-direction-btns[_ngcontent-%COMP%] button.active[_ngcontent-%COMP%] { background: var(--mj-color-indigo-500); color: var(--mj-bg-surface); }\n\n\n\n.ve-tp-add-step[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.ve-tp-add-step[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n.ve-tp-step[_ngcontent-%COMP%] {\n margin-top: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n overflow: hidden;\n}\n\n.ve-tp-step-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-step-num[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-color-indigo-500);\n color: var(--mj-bg-surface);\n font-size: 10px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.ve-tp-type-select[_ngcontent-%COMP%] {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.ve-tp-type-select[_ngcontent-%COMP%]:focus { border-color: var(--mj-color-indigo-500); }\n\n.ve-tp-remove-step[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 5px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 11px;\n transition: all 150ms ease;\n flex-shrink: 0;\n}\n\n.ve-tp-remove-step[_ngcontent-%COMP%]:hover { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n\n.ve-tp-step-config[_ngcontent-%COMP%] {\n padding: 8px 10px;\n}\n\n.ve-tp-config-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.ve-tp-config-row[_ngcontent-%COMP%]:last-child { margin-bottom: 0; }\n\n.ve-tp-config-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n width: 80px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.ve-tp-config-row[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-page);\n outline: none;\n font-family: 'SF Mono', 'Fira Code', monospace;\n}\n\n.ve-tp-config-row[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus { border-color: var(--mj-color-indigo-500); background: var(--mj-bg-surface); }\n\n.ve-tp-step-onerror[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n border-top: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n}\n\n.ve-tp-step-onerror[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.ve-tp-step-onerror[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n height: 24px;\n padding: 0 6px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.ve-tp-no-steps[_ngcontent-%COMP%] {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-style: italic;\n}\n\n\n\n.ve-tp-footer[_ngcontent-%COMP%] {\n padding: 14px 16px;\n margin-top: auto;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.ve-canvas-scroll[_ngcontent-%COMP%]::-webkit-scrollbar, \n.ve-transform-panel[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n\n.ve-canvas-scroll[_ngcontent-%COMP%]::-webkit-scrollbar-track, \n.ve-transform-panel[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.ve-canvas-scroll[_ngcontent-%COMP%]::-webkit-scrollbar-thumb, \n.ve-transform-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-color-neutral-300);\n border-radius: 3px;\n}\n\n.ve-canvas-scroll[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover, \n.ve-transform-panel[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n\n\n\n.ve-info-body[_ngcontent-%COMP%] {\n padding: 16px;\n overflow-y: auto;\n}\n\n.ve-info-loading[_ngcontent-%COMP%] {\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n padding: 20px;\n}\n\n.ve-info-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-indigo-500);\n margin-right: 6px;\n}\n\n.ve-info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.ve-info-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.ve-info-card-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-500);\n}\n\n.ve-info-card-icon.source[_ngcontent-%COMP%] {\n background: var(--mj-color-info-100);\n color: var(--mj-brand-primary);\n}\n\n.ve-info-card-icon.sync[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.ve-info-card-icon.info-status-success[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.ve-info-card-icon.info-status-error[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.ve-info-card-icon.info-status-running[_ngcontent-%COMP%] {\n background: var(--mj-color-info-100);\n color: var(--mj-brand-primary);\n}\n\n.ve-info-card-icon.info-status-pending[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-100);\n color: var(--mj-color-warning-600);\n}\n\n.ve-info-card-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.ve-info-card-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ve-info-card-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n.ve-info-details[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.ve-info-detail-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n font-size: 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-info-detail-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.ve-info-detail-label[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.ve-info-detail-value[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 600;\n}"] });
1521
+ }
1522
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VisualFieldEditorComponent, [{
1523
+ type: Component,
1524
+ args: [{ standalone: false, selector: 'app-visual-field-editor', template: "<div class=\"ve-container\">\n\n <!-- Header -->\n <div class=\"ve-header\">\n <div class=\"ve-header-left\">\n <button class=\"ve-back-btn\" (click)=\"OnClose()\" title=\"Back to entity maps\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n </button>\n <div class=\"ve-header-title\">\n <span class=\"ve-source-label\">{{ EntityMap?.ExternalObjectLabel ?? EntityMap?.ExternalObjectName }}</span>\n <span class=\"ve-direction-arrow\">\n <i class=\"fa-solid fa-arrow-right-arrow-left\"></i>\n </span>\n <span class=\"ve-dest-label\">{{ EntityMap?.Entity }}</span>\n </div>\n <!-- SyncEnabled toggle in editor header -->\n @if (EntityMap) {\n <label class=\"sync-toggle ve-sync-toggle\"\n [title]=\"EntityMap.SyncEnabled ? 'Sync enabled' : 'Sync disabled'\">\n <input type=\"checkbox\"\n [checked]=\"EntityMap.SyncEnabled\"\n (change)=\"OnToggleEditorSyncEnabled($event)\" />\n <span class=\"sync-toggle-track\"></span>\n </label>\n <span class=\"ve-sync-label\">{{ EntityMap.SyncEnabled ? 'Sync On' : 'Sync Off' }}</span>\n }\n </div>\n <div class=\"ve-header-stats\">\n <span class=\"ve-stat\">\n <strong>{{ EditorMappedCount }}</strong> mapped\n </span>\n <span class=\"ve-stat-sep\"></span>\n <span class=\"ve-stat\">\n <strong>{{ EditorKeyFieldCount }}</strong> key\n </span>\n <span class=\"ve-stat-sep\"></span>\n <span class=\"ve-stat\">\n <strong>{{ EditorRequiredCount }}</strong> required\n </span>\n </div>\n <div class=\"ve-header-actions\">\n <!-- Data preview buttons -->\n <button class=\"ve-btn ve-btn-ghost\"\n (click)=\"ToggleSourcePreview()\"\n [class.active]=\"ShowSourcePreview\"\n title=\"Preview source data\">\n <i class=\"fa-solid fa-cloud\"></i> Source Data\n </button>\n <button class=\"ve-btn ve-btn-ghost\"\n (click)=\"ToggleDestPreview()\"\n [class.active]=\"ShowDestPreview\"\n title=\"Preview MJ data\">\n <i class=\"fa-solid fa-database\"></i> MJ Data\n </button>\n <div class=\"ve-action-sep\"></div>\n <button class=\"ve-btn ve-btn-ghost\" (click)=\"AutoMapEditorFields()\" title=\"Auto-map fields by name\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Auto-Map\n </button>\n <button class=\"ve-btn ve-btn-primary\"\n [disabled]=\"!HasEditorChanges || EditorSaving\"\n (click)=\"SaveVisualEditor()\">\n @if (EditorSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Save\n }\n </button>\n @if (EditorSaveSuccess && !HasEditorChanges) {\n <span class=\"ve-save-success\">\n <i class=\"fa-solid fa-circle-check\"></i> Saved\n </span>\n }\n </div>\n </div>\n\n <!-- Data preview panels (collapsible) -->\n @if (ShowSourcePreview || ShowDestPreview) {\n <div class=\"ve-preview-strip\">\n @if (ShowSourcePreview) {\n <div class=\"ve-preview-panel\">\n <div class=\"ve-preview-header\">\n <i class=\"fa-solid fa-cloud\"></i>\n <span>Source Preview: {{ EntityMap?.ExternalObjectLabel ?? EntityMap?.ExternalObjectName }}</span>\n <button class=\"ve-preview-close\" (click)=\"ShowSourcePreview = false\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n @if (PreviewSourceLoading) {\n <div class=\"ve-preview-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...\n </div>\n } @else if (PreviewSourceRows.length === 0) {\n <div class=\"ve-preview-empty\">No source data available</div>\n } @else {\n <div class=\"ve-preview-table-wrap\">\n <table class=\"ve-preview-table\">\n <thead>\n <tr>\n @for (col of PreviewSourceColumns; track col) {\n <th>{{ col }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of PreviewSourceRows; track $index) {\n <tr>\n @for (col of PreviewSourceColumns; track col) {\n <td [title]=\"row[col]?.toString() ?? ''\">{{ row[col] ?? '' }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n @if (ShowDestPreview) {\n <div class=\"ve-preview-panel\">\n <div class=\"ve-preview-header\">\n <i class=\"fa-solid fa-database\"></i>\n <span>Dest Preview: {{ EntityMap?.Entity }}</span>\n <button class=\"ve-preview-close\" (click)=\"ShowDestPreview = false\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n @if (PreviewDestLoading) {\n <div class=\"ve-preview-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...\n </div>\n } @else if (PreviewDestRows.length === 0) {\n <div class=\"ve-preview-empty\">No destination data available</div>\n } @else {\n <div class=\"ve-preview-table-wrap\">\n <table class=\"ve-preview-table\">\n <thead>\n <tr>\n @for (col of PreviewDestColumns; track col) {\n <th>{{ col }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of PreviewDestRows; track $index) {\n <tr>\n @for (col of PreviewDestColumns; track col) {\n <td [title]=\"row[col]?.toString() ?? ''\">{{ row[col] ?? '' }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Connect mode banner -->\n @if (ConnectingFromSource) {\n <div class=\"ve-connect-banner\">\n <i class=\"fa-solid fa-link\"></i>\n Click a destination field to map from\n <strong>{{ ConnectingFromSource }}</strong>\n <button class=\"ve-connect-cancel\" (click)=\"CancelConnect()\">Cancel</button>\n </div>\n }\n\n <!-- Main content: sections + transform panel -->\n <div class=\"ve-body\" [class.has-transform-panel]=\"SelectedConnectionIdx !== null\">\n\n <!-- Loading state -->\n @if (EditorLoading) {\n <div class=\"ve-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading field mappings...</span>\n </div>\n } @else {\n\n <!-- Left content area (sections stacked vertically) -->\n <div class=\"ve-sections-wrapper\">\n\n <!-- ============================================================= -->\n <!-- FIELD MAPPINGS SECTION (collapsible) -->\n <!-- ============================================================= -->\n <div class=\"ve-section\" [class.collapsed]=\"!FieldMapsExpanded\">\n <div class=\"ve-section-header\" (click)=\"ToggleFieldMaps()\">\n <i class=\"fa-solid\"\n [class.fa-chevron-down]=\"FieldMapsExpanded\"\n [class.fa-chevron-right]=\"!FieldMapsExpanded\"></i>\n <span class=\"ve-section-title\">Field Mappings</span>\n <span class=\"ve-section-badge\">{{ EditorMappedCount }} mapped</span>\n </div>\n\n @if (FieldMapsExpanded) {\n <div class=\"ve-section-body\">\n <!-- Canvas area (scrollable) -->\n <div class=\"ve-canvas-wrapper\">\n\n <!-- Column headers -->\n <div class=\"ve-col-headers\">\n <div class=\"ve-col-header source\">\n <i class=\"fa-solid fa-cloud\"></i>\n Source Fields\n <span class=\"ve-col-count\">{{ EditorSourceFields.length }}</span>\n </div>\n <div class=\"ve-col-header-spacer\"></div>\n <div class=\"ve-col-header dest\">\n <i class=\"fa-solid fa-database\"></i>\n MJ Entity Fields\n <span class=\"ve-col-count\">{{ EditorDestFields.length }}</span>\n </div>\n </div>\n\n <!-- Search bars -->\n <div class=\"ve-col-searches\">\n <div class=\"ve-col-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter source fields...\"\n [value]=\"EditorSearchSource\"\n (input)=\"EditorSearchSource = $any($event.target).value\" />\n </div>\n <div class=\"ve-col-search-spacer\"></div>\n <div class=\"ve-col-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter destination fields...\"\n [value]=\"EditorSearchDest\"\n (input)=\"EditorSearchDest = $any($event.target).value\" />\n </div>\n </div>\n\n <!-- Canvas grid (source + SVG + dest) -->\n <div class=\"ve-canvas-scroll\" (click)=\"DeselectConnection()\">\n <div class=\"ve-canvas-grid\" [style.min-height.px]=\"EditorCanvasHeight\">\n\n <!-- Source column -->\n <div class=\"ve-field-col source\">\n @for (sf of FilteredEditorSourceFields; track sf.Name) {\n <div class=\"ve-field-item\"\n [class.mapped]=\"IsSourceFieldMapped(sf.Name)\"\n [class.unmapped]=\"!IsSourceFieldMapped(sf.Name)\"\n [class.connecting]=\"ConnectingFromSource === sf.Name\"\n [style.height.px]=\"FIELD_HEIGHT\"\n (click)=\"OnEditorSourceClick(sf.Name); $event.stopPropagation()\">\n <span class=\"ve-field-name\" [title]=\"sf.Name\">{{ sf.Label || sf.Name }}</span>\n <span class=\"ve-field-type\">{{ sf.Type }}</span>\n <span class=\"ve-field-badges\">\n @if (sf.IsPrimaryKey) {\n <span class=\"ve-fbadge pk\" title=\"Primary Key\">PK</span>\n }\n @if (sf.IsRequired) {\n <span class=\"ve-fbadge req\" title=\"Required\">*</span>\n }\n </span>\n </div>\n }\n @if (FilteredEditorSourceFields.length === 0) {\n <div class=\"ve-field-empty\">No source fields found</div>\n }\n </div>\n\n <!-- SVG connection lines -->\n <svg class=\"ve-svg\"\n [attr.width]=\"SVG_WIDTH\"\n [attr.height]=\"EditorCanvasHeight\"\n [attr.viewBox]=\"'0 0 ' + SVG_WIDTH + ' ' + EditorCanvasHeight\"\n (click)=\"$event.stopPropagation()\">\n @for (conn of VisibleConnections; track conn.SourceFieldName + '-' + conn.DestFieldName; let i = $index) {\n <!-- Connection line -->\n <path [attr.d]=\"GetConnectionPath(conn)\"\n class=\"ve-conn-line\"\n [class]=\"'ve-conn-line ' + GetConnectionLineClass(conn)\"\n [class.selected]=\"SelectedConnectionIdx === i\"\n (click)=\"SelectConnection(i, $event)\" />\n <!-- Transform badge at midpoint -->\n <foreignObject\n [attr.x]=\"SVG_WIDTH / 2 - 14\"\n [attr.y]=\"GetConnectionMidY(conn) - 14\"\n width=\"28\" height=\"28\"\n class=\"ve-badge-fo\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"ve-conn-badge\"\n [class]=\"'ve-conn-badge ' + GetConnectionBadgeClass(conn)\"\n [class.selected]=\"SelectedConnectionIdx === i\"\n (click)=\"SelectConnection(i, $event)\">\n <i [class]=\"GetConnectionDirectionIcon(conn)\"></i>\n </div>\n </foreignObject>\n }\n </svg>\n\n <!-- Dest column -->\n <div class=\"ve-field-col dest\">\n @for (df of FilteredEditorDestFields; track df.Name) {\n <div class=\"ve-field-item\"\n [class.mapped]=\"IsDestFieldMapped(df.Name)\"\n [class.unmapped]=\"!IsDestFieldMapped(df.Name)\"\n [class.connect-target]=\"ConnectingFromSource !== null\"\n [style.height.px]=\"FIELD_HEIGHT\"\n (click)=\"OnEditorDestClick(df.Name); $event.stopPropagation()\">\n <span class=\"ve-field-name\" [title]=\"df.Name\">{{ df.Name }}</span>\n <span class=\"ve-field-type\">{{ df.Type }}</span>\n <span class=\"ve-field-badges\">\n @if (df.IsRequired) {\n <span class=\"ve-fbadge req\" title=\"Required\">*</span>\n }\n </span>\n </div>\n }\n @if (FilteredEditorDestFields.length === 0) {\n <div class=\"ve-field-empty\">No destination fields found</div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- ============================================================= -->\n <!-- INFO PANEL SECTION (collapsible) -->\n <!-- ============================================================= -->\n <div class=\"ve-section\" [class.collapsed]=\"!InfoPanelExpanded\">\n <div class=\"ve-section-header\" (click)=\"ToggleInfoPanel()\">\n <i class=\"fa-solid\"\n [class.fa-chevron-down]=\"InfoPanelExpanded\"\n [class.fa-chevron-right]=\"!InfoPanelExpanded\"></i>\n <span class=\"ve-section-title\">Sync Info</span>\n </div>\n\n @if (InfoPanelExpanded) {\n <div class=\"ve-section-body ve-info-body\">\n @if (InfoPanelLoading) {\n <div class=\"ve-info-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading stats...\n </div>\n } @else {\n <div class=\"ve-info-grid\">\n <!-- Destination record count -->\n <div class=\"ve-info-card\">\n <div class=\"ve-info-card-icon\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"ve-info-card-content\">\n <span class=\"ve-info-card-value\">{{ InfoDestRecordCount ?? '-' }}</span>\n <span class=\"ve-info-card-label\">MJ Records</span>\n </div>\n </div>\n <!-- Source fields count -->\n <div class=\"ve-info-card\">\n <div class=\"ve-info-card-icon source\">\n <i class=\"fa-solid fa-cloud\"></i>\n </div>\n <div class=\"ve-info-card-content\">\n <span class=\"ve-info-card-value\">{{ EditorSourceFields.length }}</span>\n <span class=\"ve-info-card-label\">Source Fields</span>\n </div>\n </div>\n <!-- Last sync -->\n <div class=\"ve-info-card\">\n <div class=\"ve-info-card-icon sync\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </div>\n <div class=\"ve-info-card-content\">\n <span class=\"ve-info-card-value\">{{ FormatSyncDate(InfoLastSync?.StartedAt ?? null) }}</span>\n <span class=\"ve-info-card-label\">Last Sync</span>\n </div>\n </div>\n <!-- Sync status -->\n @if (InfoLastSync) {\n <div class=\"ve-info-card\">\n <div class=\"ve-info-card-icon\" [ngClass]=\"SyncStatusClass(InfoLastSync.Status)\">\n <i class=\"fa-solid\"\n [class.fa-circle-check]=\"InfoLastSync.Status === 'Success'\"\n [class.fa-circle-xmark]=\"InfoLastSync.Status === 'Failed'\"\n [class.fa-spinner]=\"InfoLastSync.Status === 'In Progress'\"\n [class.fa-clock]=\"InfoLastSync.Status === 'Pending'\"></i>\n </div>\n <div class=\"ve-info-card-content\">\n <span class=\"ve-info-card-value\">{{ InfoLastSync.Status }}</span>\n <span class=\"ve-info-card-label\">{{ InfoLastSync.TotalRecords }} records processed</span>\n </div>\n </div>\n }\n </div>\n\n <!-- Configuration details -->\n <div class=\"ve-info-details\">\n <div class=\"ve-info-detail-row\">\n <span class=\"ve-info-detail-label\">Sync Direction</span>\n <span class=\"ve-info-detail-value\">{{ EntityMap?.SyncDirection }}</span>\n </div>\n <div class=\"ve-info-detail-row\">\n <span class=\"ve-info-detail-label\">Conflict Resolution</span>\n <span class=\"ve-info-detail-value\">{{ EntityMap?.ConflictResolution }}</span>\n </div>\n <div class=\"ve-info-detail-row\">\n <span class=\"ve-info-detail-label\">Delete Behavior</span>\n <span class=\"ve-info-detail-value\">{{ EntityMap?.DeleteBehavior }}</span>\n </div>\n <div class=\"ve-info-detail-row\">\n <span class=\"ve-info-detail-label\">Priority</span>\n <span class=\"ve-info-detail-value\">{{ EntityMap?.Priority }}</span>\n </div>\n @if (EntityMap?.MatchStrategy) {\n <div class=\"ve-info-detail-row\">\n <span class=\"ve-info-detail-label\">Match Strategy</span>\n <span class=\"ve-info-detail-value\">Configured</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Transform editor panel (right side, appears when connection selected) -->\n @if (SelectedConnection; as conn) {\n <div class=\"ve-transform-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"ve-tp-header\">\n <span class=\"ve-tp-title\">Mapping Details</span>\n <button class=\"ve-tp-close\" (click)=\"DeselectConnection()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Source -> Dest -->\n <div class=\"ve-tp-mapping-info\">\n <div class=\"ve-tp-field-pair\">\n <span class=\"ve-tp-field source\">{{ conn.SourceFieldName }}</span>\n <i class=\"fa-solid ve-tp-arrow\"\n [class.fa-arrow-right]=\"conn.Direction === 'SourceToDest'\"\n [class.fa-arrow-left]=\"conn.Direction === 'DestToSource'\"\n [class.fa-right-left]=\"conn.Direction === 'Both'\"></i>\n <span class=\"ve-tp-field dest\">{{ conn.DestFieldName }}</span>\n </div>\n </div>\n\n <!-- Toggles -->\n <div class=\"ve-tp-toggles\">\n <label class=\"ve-tp-toggle\" (click)=\"ToggleConnectionKey()\">\n <span class=\"ve-tp-toggle-box\" [class.active]=\"conn.IsKeyField\">\n @if (conn.IsKeyField) { <i class=\"fa-solid fa-check\"></i> }\n </span>\n <span>Key Field</span>\n </label>\n <label class=\"ve-tp-toggle\" (click)=\"ToggleConnectionRequired()\">\n <span class=\"ve-tp-toggle-box\" [class.active]=\"conn.IsRequired\">\n @if (conn.IsRequired) { <i class=\"fa-solid fa-check\"></i> }\n </span>\n <span>Required</span>\n </label>\n </div>\n\n <!-- Direction -->\n <div class=\"ve-tp-section\">\n <label class=\"ve-tp-section-label\">Direction</label>\n <div class=\"ve-tp-direction-btns\">\n <button [class.active]=\"conn.Direction === 'SourceToDest'\"\n (click)=\"OnConnectionDirectionChange('SourceToDest')\">\n Source &rarr; Dest\n </button>\n <button [class.active]=\"conn.Direction === 'DestToSource'\"\n (click)=\"OnConnectionDirectionChange('DestToSource')\">\n Dest &rarr; Source\n </button>\n <button [class.active]=\"conn.Direction === 'Both'\"\n (click)=\"OnConnectionDirectionChange('Both')\">\n Both\n </button>\n </div>\n </div>\n\n <!-- Transform pipeline -->\n <div class=\"ve-tp-section\">\n <div class=\"ve-tp-section-header\">\n <label class=\"ve-tp-section-label\">Transform Pipeline</label>\n <button class=\"ve-tp-add-step\" (click)=\"AddTransformStep()\">\n <i class=\"fa-solid fa-plus\"></i> Add Step\n </button>\n </div>\n\n @for (step of conn.TransformSteps; track $index; let si = $index) {\n <div class=\"ve-tp-step\">\n <div class=\"ve-tp-step-header\">\n <span class=\"ve-tp-step-num\">{{ si + 1 }}</span>\n <select class=\"ve-tp-type-select\"\n [value]=\"step.Type\"\n (change)=\"OnConnectionTransformChange(si, $any($event.target).value)\">\n @for (tt of TRANSFORM_TYPES; track tt.Value) {\n <option [value]=\"tt.Value\" [selected]=\"tt.Value === step.Type\">{{ tt.Label }}</option>\n }\n </select>\n <button class=\"ve-tp-remove-step\" (click)=\"RemoveTransformStep(si)\" title=\"Remove step\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n\n <!-- Config fields based on transform type -->\n @if (step.Type !== 'direct') {\n <div class=\"ve-tp-step-config\">\n @for (key of GetConfigKeys(step); track key) {\n <div class=\"ve-tp-config-row\">\n <label>{{ key }}</label>\n <input type=\"text\"\n [value]=\"GetConfigValue(step, key)\"\n (input)=\"OnTransformConfigChange(conn, si, key, $any($event.target).value)\"\n placeholder=\"{{ key }}\" />\n </div>\n }\n </div>\n }\n\n <!-- On error -->\n <div class=\"ve-tp-step-onerror\">\n <label>On Error:</label>\n <select [value]=\"step.OnError\"\n (change)=\"step.OnError = $any($event.target).value; conn.IsDirty = true\">\n <option value=\"Fail\">Fail</option>\n <option value=\"Skip\">Skip</option>\n <option value=\"Null\">Null</option>\n </select>\n </div>\n </div>\n }\n\n @if (conn.TransformSteps.length === 0) {\n <div class=\"ve-tp-no-steps\">\n No transform steps. Data passes through as-is.\n </div>\n }\n </div>\n\n <!-- Delete mapping button -->\n <div class=\"ve-tp-footer\">\n <button class=\"ve-btn ve-btn-danger\" (click)=\"RemoveSelectedConnection()\">\n <i class=\"fa-solid fa-trash-can\"></i> Remove Mapping\n </button>\n </div>\n </div>\n }\n }\n </div>\n</div>\n", styles: ["/* ==========================================================================\n Visual Field Editor Component CSS\n Copied from pipelines.component.css (visual editor section)\n ========================================================================== */\n\n:host {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.ve-container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mj-bg-surface);\n animation: slideIn 250ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideIn {\n from { opacity: 0; transform: translateX(30px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* ---------------------------------------------------------------------------\n VE Header\n --------------------------------------------------------------------------- */\n\n.ve-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 16px;\n}\n\n.ve-header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.ve-back-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 14px;\n flex-shrink: 0;\n transition: all 150ms ease;\n}\n\n.ve-back-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n.ve-header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 15px;\n font-weight: 600;\n min-width: 0;\n}\n\n.ve-source-label {\n color: var(--mj-color-indigo-500);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n.ve-direction-arrow { color: var(--mj-text-disabled); font-size: 13px; flex-shrink: 0; }\n\n.ve-dest-label {\n color: var(--mj-color-success-600);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n.ve-header-stats {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.ve-stat {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.ve-stat strong {\n color: var(--mj-text-primary);\n font-weight: 700;\n}\n\n.ve-stat-sep {\n width: 1px;\n height: 14px;\n background: var(--mj-border-default);\n}\n\n.ve-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.ve-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border-radius: 7px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n border: none;\n white-space: nowrap;\n}\n\n.ve-btn-ghost {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n}\n\n.ve-btn-ghost:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-primary); }\n\n.ve-btn-primary {\n background: var(--mj-color-indigo-500);\n color: var(--mj-bg-surface);\n}\n\n.ve-btn-primary:hover { background: var(--mj-color-indigo-600); }\n.ve-btn-primary:disabled { opacity: 0.5; cursor: default; }\n\n.ve-btn-danger {\n background: var(--mj-status-error-bg);\n color: var(--mj-color-error-600);\n border: 1px solid var(--mj-color-error-200);\n}\n\n.ve-btn-danger:hover { background: var(--mj-color-error-100); }\n\n.ve-save-success {\n font-size: 12px;\n color: var(--mj-color-success-600);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 4px;\n animation: fadeIn 300ms ease;\n}\n\n/* Sync toggle in editor header */\n.ve-sync-toggle { flex-shrink: 0; margin-left: 8px; }\n.ve-sync-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n/* Sync toggle styling */\n.sync-toggle {\n position: relative;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n}\n\n.sync-toggle input {\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n}\n\n.sync-toggle-track {\n width: 34px;\n height: 18px;\n background: var(--mj-color-neutral-300);\n border-radius: 9px;\n position: relative;\n transition: background 200ms ease;\n}\n\n.sync-toggle-track::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 14px;\n height: 14px;\n background: var(--mj-bg-surface);\n border-radius: 50%;\n transition: transform 200ms ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);\n}\n\n.sync-toggle input:checked + .sync-toggle-track {\n background: var(--mj-color-success-500);\n}\n\n.sync-toggle input:checked + .sync-toggle-track::after {\n transform: translateX(16px);\n}\n\n/* Action separator */\n.ve-action-sep {\n width: 1px;\n height: 20px;\n background: var(--mj-border-default);\n flex-shrink: 0;\n}\n\n/* Active state for preview toggle buttons */\n.ve-btn-ghost.active {\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-600);\n border-color: var(--mj-color-indigo-200);\n}\n\n/* ---------------------------------------------------------------------------\n Data Preview Strip\n --------------------------------------------------------------------------- */\n\n.ve-preview-strip {\n display: flex;\n gap: 1px;\n background: var(--mj-border-default);\n border-bottom: 1px solid var(--mj-border-default);\n max-height: 220px;\n flex-shrink: 0;\n overflow: hidden;\n}\n\n.ve-preview-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n}\n\n.ve-preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n}\n\n.ve-preview-header i { font-size: 11px; color: var(--mj-color-indigo-500); }\n.ve-preview-header span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n.ve-preview-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.ve-preview-close:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-secondary); }\n\n.ve-preview-loading,\n.ve-preview-empty {\n padding: 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.ve-preview-loading i { margin-right: 6px; color: var(--mj-color-indigo-500); }\n\n.ve-preview-table-wrap {\n flex: 1;\n overflow: auto;\n}\n\n.ve-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 11px;\n}\n\n.ve-preview-table th {\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-muted);\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n font-size: 10px;\n padding: 5px 10px;\n text-align: left;\n white-space: nowrap;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.ve-preview-table td {\n padding: 4px 10px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.ve-preview-table tbody tr:hover td {\n background: var(--mj-color-indigo-50);\n}\n\n/* ---------------------------------------------------------------------------\n Connect mode banner\n --------------------------------------------------------------------------- */\n\n.ve-connect-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 20px;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-700);\n font-size: 13px;\n border-bottom: 1px solid var(--mj-color-indigo-100);\n flex-shrink: 0;\n}\n\n.ve-connect-banner strong { font-weight: 700; }\n\n.ve-connect-cancel {\n margin-left: auto;\n padding: 3px 10px;\n border: 1px solid var(--mj-color-indigo-100);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-color-indigo-700);\n font-size: 12px;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.ve-connect-cancel:hover { background: var(--mj-color-indigo-100); }\n\n/* ---------------------------------------------------------------------------\n VE Body\n --------------------------------------------------------------------------- */\n\n.ve-body {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.ve-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n gap: 12px;\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.ve-loading i { font-size: 24px; color: var(--mj-color-indigo-500); }\n\n/* Sections wrapper (replaces ve-canvas-wrapper as the main left area) */\n.ve-sections-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n/* Collapsible section */\n.ve-section {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.ve-section:not(.collapsed) {\n flex: 1;\n min-height: 0;\n}\n\n.ve-section.collapsed {\n flex-shrink: 0;\n}\n\n.ve-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n cursor: pointer;\n user-select: none;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-shrink: 0;\n transition: background 150ms ease;\n}\n\n.ve-section-header:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.ve-section-header i {\n font-size: 10px;\n color: var(--mj-text-disabled);\n width: 12px;\n flex-shrink: 0;\n transition: transform 200ms ease;\n}\n\n.ve-section-title {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n color: var(--mj-text-muted);\n}\n\n.ve-section-badge {\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-600);\n padding: 1px 8px;\n border-radius: 4px;\n margin-left: auto;\n}\n\n.ve-section-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n animation: fadeIn 200ms ease;\n}\n\n/* Canvas wrapper (takes available space, pushes transform panel right) */\n.ve-canvas-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n/* ---------------------------------------------------------------------------\n Column headers\n --------------------------------------------------------------------------- */\n\n.ve-col-headers {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-col-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n}\n\n.ve-col-header.source i { color: var(--mj-color-indigo-500); }\n.ve-col-header.dest i { color: var(--mj-color-success-600); }\n.ve-col-header-spacer { /* SVG gap */ }\n\n.ve-col-count {\n font-size: 10px;\n font-weight: 600;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-disabled);\n padding: 1px 6px;\n border-radius: 4px;\n}\n\n/* ---------------------------------------------------------------------------\n Column search bars\n --------------------------------------------------------------------------- */\n\n.ve-col-searches {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n flex-shrink: 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n padding: 6px 0;\n}\n\n.ve-col-search {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 12px;\n}\n\n.ve-col-search i {\n font-size: 11px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.ve-col-search input {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-page);\n outline: none;\n transition: border-color 150ms ease;\n}\n\n.ve-col-search input:focus { border-color: var(--mj-color-indigo-500); background: var(--mj-bg-surface); }\n.ve-col-search input::placeholder { color: var(--mj-color-neutral-300); }\n.ve-col-search-spacer { /* SVG gap */ }\n\n/* ---------------------------------------------------------------------------\n Canvas scroll + grid\n --------------------------------------------------------------------------- */\n\n.ve-canvas-scroll {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.ve-canvas-grid {\n display: grid;\n grid-template-columns: 1fr 200px 1fr;\n position: relative;\n}\n\n/* ---------------------------------------------------------------------------\n Field columns\n --------------------------------------------------------------------------- */\n\n.ve-field-col {\n display: flex;\n flex-direction: column;\n}\n\n.ve-field-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 14px;\n font-size: 13px;\n cursor: pointer;\n transition: background 150ms ease, opacity 150ms ease;\n border-bottom: 1px solid var(--mj-bg-page);\n box-sizing: border-box;\n}\n\n.ve-field-item.mapped { background: var(--mj-bg-surface); }\n\n.ve-field-item.unmapped {\n opacity: 0.5;\n background: var(--mj-bg-page);\n}\n\n.ve-field-item:hover {\n background: var(--mj-color-indigo-50);\n opacity: 1;\n}\n\n.ve-field-item.connecting {\n background: var(--mj-color-indigo-100);\n opacity: 1;\n box-shadow: inset 0 0 0 2px var(--mj-color-indigo-500);\n}\n\n.ve-field-item.connect-target:hover {\n background: var(--mj-color-success-100);\n box-shadow: inset 0 0 0 2px var(--mj-color-success-600);\n}\n\n.ve-field-name {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--mj-color-neutral-700);\n font-weight: 500;\n}\n\n.ve-field-type {\n font-size: 10px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n font-family: 'SF Mono', 'Fira Code', monospace;\n}\n\n.ve-field-badges {\n display: flex;\n gap: 3px;\n flex-shrink: 0;\n}\n\n.ve-fbadge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 3px;\n border-radius: 4px;\n font-size: 9px;\n font-weight: 700;\n}\n\n.ve-fbadge.pk { background: var(--mj-color-warning-100); color: var(--mj-color-warning-700); }\n.ve-fbadge.req { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n\n.ve-field-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n/* ---------------------------------------------------------------------------\n SVG connections\n --------------------------------------------------------------------------- */\n\n.ve-svg {\n display: block;\n}\n\n.ve-conn-line {\n fill: none;\n stroke-width: 2;\n cursor: pointer;\n transition: stroke 200ms ease, stroke-width 200ms ease;\n}\n\n/* Transform-based line styles */\n.ve-conn-line.conn-direct { stroke: #6366f1; stroke-dasharray: none; }\n.ve-conn-line.conn-regex { stroke: #8b5cf6; stroke-dasharray: 6 3; }\n.ve-conn-line.conn-split { stroke: #f59e0b; stroke-dasharray: 8 4; }\n.ve-conn-line.conn-combine { stroke: #10b981; stroke-dasharray: 8 4; }\n.ve-conn-line.conn-lookup { stroke: #0ea5e9; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-format { stroke: #ec4899; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-coerce { stroke: #f97316; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-substring { stroke: #14b8a6; stroke-dasharray: 4 4; }\n.ve-conn-line.conn-custom { stroke: #a855f7; stroke-dasharray: 2 3; }\n\n.ve-conn-line:hover { stroke-width: 3.5; }\n.ve-conn-line.selected { stroke-width: 3.5; filter: drop-shadow(0 0 4px rgba(99, 102, 241, 0.4)); }\n\n/* Connection badge at midpoint */\n.ve-badge-fo { overflow: visible; }\n\n.ve-conn-badge {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n cursor: pointer;\n transition: all 150ms ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n}\n\n.ve-conn-badge.badge-direct { background: #eef2ff; color: #6366f1; border: 2px solid #6366f1; }\n.ve-conn-badge.badge-regex { background: #f5f3ff; color: #8b5cf6; border: 2px solid #8b5cf6; }\n.ve-conn-badge.badge-split { background: #fffbeb; color: #f59e0b; border: 2px solid #f59e0b; }\n.ve-conn-badge.badge-combine { background: #ecfdf5; color: #10b981; border: 2px solid #10b981; }\n.ve-conn-badge.badge-lookup { background: #f0f9ff; color: #0ea5e9; border: 2px solid #0ea5e9; }\n.ve-conn-badge.badge-format { background: #fdf2f8; color: #ec4899; border: 2px solid #ec4899; }\n.ve-conn-badge.badge-coerce { background: #fff7ed; color: #f97316; border: 2px solid #f97316; }\n.ve-conn-badge.badge-substring { background: #f0fdfa; color: #14b8a6; border: 2px solid #14b8a6; }\n.ve-conn-badge.badge-custom { background: #faf5ff; color: #a855f7; border: 2px solid #a855f7; }\n\n.ve-conn-badge:hover { transform: scale(1.2); }\n.ve-conn-badge.selected { transform: scale(1.25); box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3); }\n\n/* ---------------------------------------------------------------------------\n Transform Panel (right side)\n --------------------------------------------------------------------------- */\n\n.ve-transform-panel {\n width: 320px;\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n background: var(--mj-bg-page);\n animation: slideInRight 200ms ease;\n}\n\n@keyframes slideInRight {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n.ve-tp-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.ve-tp-title {\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.ve-tp-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.ve-tp-close:hover { background: var(--mj-bg-surface-active); color: var(--mj-text-secondary); }\n\n/* Mapping info */\n.ve-tp-mapping-info {\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-field-pair {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.ve-tp-field {\n padding: 4px 10px;\n border-radius: 6px;\n font-weight: 600;\n font-size: 12px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 110px;\n}\n\n.ve-tp-field.source { background: var(--mj-color-indigo-50); color: var(--mj-color-indigo-700); }\n.ve-tp-field.dest { background: var(--mj-status-success-bg); color: var(--mj-color-success-700); }\n.ve-tp-arrow { color: var(--mj-text-disabled); font-size: 11px; flex-shrink: 0; }\n\n/* Toggles */\n.ve-tp-toggles {\n display: flex;\n gap: 16px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.ve-tp-toggle-box {\n width: 18px;\n height: 18px;\n border: 2px solid var(--mj-color-neutral-300);\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n color: var(--mj-bg-surface);\n transition: all 150ms ease;\n}\n\n.ve-tp-toggle-box.active {\n background: var(--mj-color-indigo-500);\n border-color: var(--mj-color-indigo-500);\n}\n\n/* Sections */\n.ve-tp-section {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-section-label {\n display: block;\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 8px;\n}\n\n.ve-tp-section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n/* Direction buttons */\n.ve-tp-direction-btns {\n display: flex;\n gap: 0;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.ve-tp-direction-btns button {\n flex: 1;\n padding: 6px 8px;\n border: none;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.ve-tp-direction-btns button:last-child { border-right: none; }\n.ve-tp-direction-btns button:hover { background: var(--mj-bg-surface-hover); }\n.ve-tp-direction-btns button.active { background: var(--mj-color-indigo-500); color: var(--mj-bg-surface); }\n\n/* Transform steps */\n.ve-tp-add-step {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.ve-tp-add-step:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n.ve-tp-step {\n margin-top: 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n overflow: hidden;\n}\n\n.ve-tp-step-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-tp-step-num {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-color-indigo-500);\n color: var(--mj-bg-surface);\n font-size: 10px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.ve-tp-type-select {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.ve-tp-type-select:focus { border-color: var(--mj-color-indigo-500); }\n\n.ve-tp-remove-step {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 5px;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n font-size: 11px;\n transition: all 150ms ease;\n flex-shrink: 0;\n}\n\n.ve-tp-remove-step:hover { background: var(--mj-color-error-100); color: var(--mj-color-error-600); }\n\n.ve-tp-step-config {\n padding: 8px 10px;\n}\n\n.ve-tp-config-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.ve-tp-config-row:last-child { margin-bottom: 0; }\n\n.ve-tp-config-row label {\n width: 80px;\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.ve-tp-config-row input {\n flex: 1;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n font-size: 12px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-page);\n outline: none;\n font-family: 'SF Mono', 'Fira Code', monospace;\n}\n\n.ve-tp-config-row input:focus { border-color: var(--mj-color-indigo-500); background: var(--mj-bg-surface); }\n\n.ve-tp-step-onerror {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n border-top: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-page);\n}\n\n.ve-tp-step-onerror label {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.ve-tp-step-onerror select {\n height: 24px;\n padding: 0 6px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n font-size: 11px;\n color: var(--mj-color-neutral-700);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.ve-tp-no-steps {\n padding: 16px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-style: italic;\n}\n\n/* Footer */\n.ve-tp-footer {\n padding: 14px 16px;\n margin-top: auto;\n flex-shrink: 0;\n}\n\n/* ---------------------------------------------------------------------------\n Scrollbar styling\n --------------------------------------------------------------------------- */\n\n.ve-canvas-scroll::-webkit-scrollbar,\n.ve-transform-panel::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n}\n\n.ve-canvas-scroll::-webkit-scrollbar-track,\n.ve-transform-panel::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.ve-canvas-scroll::-webkit-scrollbar-thumb,\n.ve-transform-panel::-webkit-scrollbar-thumb {\n background: var(--mj-color-neutral-300);\n border-radius: 3px;\n}\n\n.ve-canvas-scroll::-webkit-scrollbar-thumb:hover,\n.ve-transform-panel::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* ---------------------------------------------------------------------------\n Info Panel\n --------------------------------------------------------------------------- */\n\n.ve-info-body {\n padding: 16px;\n overflow-y: auto;\n}\n\n.ve-info-loading {\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n padding: 20px;\n}\n\n.ve-info-loading i {\n color: var(--mj-color-indigo-500);\n margin-right: 6px;\n}\n\n.ve-info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.ve-info-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.ve-info-card-icon {\n width: 36px;\n height: 36px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n flex-shrink: 0;\n background: var(--mj-color-indigo-50);\n color: var(--mj-color-indigo-500);\n}\n\n.ve-info-card-icon.source {\n background: var(--mj-color-info-100);\n color: var(--mj-brand-primary);\n}\n\n.ve-info-card-icon.sync {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.ve-info-card-icon.info-status-success {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.ve-info-card-icon.info-status-error {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.ve-info-card-icon.info-status-running {\n background: var(--mj-color-info-100);\n color: var(--mj-brand-primary);\n}\n\n.ve-info-card-icon.info-status-pending {\n background: var(--mj-color-warning-100);\n color: var(--mj-color-warning-600);\n}\n\n.ve-info-card-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.ve-info-card-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ve-info-card-label {\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n.ve-info-details {\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.ve-info-detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n font-size: 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.ve-info-detail-row:last-child {\n border-bottom: none;\n}\n\n.ve-info-detail-label {\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.ve-info-detail-value {\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n"] }]
1525
+ }], null, { EntityMap: [{
1526
+ type: Input
1527
+ }], CompanyIntegrationID: [{
1528
+ type: Input
1529
+ }], RunViewProvider: [{
1530
+ type: Input
1531
+ }], Close: [{
1532
+ type: Output
1533
+ }] }); })();
1534
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VisualFieldEditorComponent, { className: "VisualFieldEditorComponent", filePath: "src/Integration/components/visual-editor/visual-editor.component.ts", lineNumber: 55 }); })();
1535
+ export function LoadVisualFieldEditorComponent() {
1536
+ // Tree-shaking prevention
1537
+ }
1538
+ //# sourceMappingURL=visual-editor.component.js.map