@memberjunction/ng-base-forms 4.4.0 → 5.1.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 (35) hide show
  1. package/dist/lib/__tests__/base-forms.test.js +52 -52
  2. package/dist/lib/__tests__/base-forms.test.js.map +1 -1
  3. package/dist/lib/base-form-component.d.ts +2 -2
  4. package/dist/lib/base-form-component.d.ts.map +1 -1
  5. package/dist/lib/base-form-component.js +1 -1
  6. package/dist/lib/base-form-component.js.map +1 -1
  7. package/dist/lib/container/record-form-container.component.d.ts +2 -0
  8. package/dist/lib/container/record-form-container.component.d.ts.map +1 -1
  9. package/dist/lib/container/record-form-container.component.js +57 -29
  10. package/dist/lib/container/record-form-container.component.js.map +1 -1
  11. package/dist/lib/isa-related-panel/isa-hierarchy-utils.d.ts +62 -0
  12. package/dist/lib/isa-related-panel/isa-hierarchy-utils.d.ts.map +1 -0
  13. package/dist/lib/isa-related-panel/isa-hierarchy-utils.js +135 -0
  14. package/dist/lib/isa-related-panel/isa-hierarchy-utils.js.map +1 -0
  15. package/dist/lib/isa-related-panel/isa-related-card.component.d.ts +69 -0
  16. package/dist/lib/isa-related-panel/isa-related-card.component.d.ts.map +1 -0
  17. package/dist/lib/isa-related-panel/isa-related-card.component.js +347 -0
  18. package/dist/lib/isa-related-panel/isa-related-card.component.js.map +1 -0
  19. package/dist/lib/isa-related-panel/isa-related-panel.component.d.ts +70 -0
  20. package/dist/lib/isa-related-panel/isa-related-panel.component.d.ts.map +1 -0
  21. package/dist/lib/isa-related-panel/isa-related-panel.component.js +190 -0
  22. package/dist/lib/isa-related-panel/isa-related-panel.component.js.map +1 -0
  23. package/dist/lib/toolbar/form-toolbar.component.d.ts +38 -0
  24. package/dist/lib/toolbar/form-toolbar.component.d.ts.map +1 -1
  25. package/dist/lib/toolbar/form-toolbar.component.js +249 -100
  26. package/dist/lib/toolbar/form-toolbar.component.js.map +1 -1
  27. package/dist/module.d.ts +8 -6
  28. package/dist/module.d.ts.map +1 -1
  29. package/dist/module.js +14 -4
  30. package/dist/module.js.map +1 -1
  31. package/dist/public-api.d.ts +3 -0
  32. package/dist/public-api.d.ts.map +1 -1
  33. package/dist/public-api.js +3 -0
  34. package/dist/public-api.js.map +1 -1
  35. package/package.json +8 -8
@@ -1,16 +1,18 @@
1
1
  import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
2
  import { DEFAULT_TOOLBAR_CONFIG } from '../types/toolbar-config';
3
+ import { DiscoverISADescendants, BuildDescendantTree } from '../isa-related-panel/isa-hierarchy-utils';
3
4
  import { BeforeSaveEventArgs, BeforeDeleteEventArgs, BeforeCancelEventArgs, BeforeHistoryViewEventArgs, BeforeListManagementEventArgs } from '../types/form-events';
4
5
  import * as i0 from "@angular/core";
5
6
  import * as i1 from "@angular/common";
6
7
  const _c0 = [[["", "toolbar-additional-controls", ""]]];
7
8
  const _c1 = ["[toolbar-additional-controls]"];
9
+ const _c2 = a0 => ({ items: a0 });
8
10
  const _forTrack0 = ($index, $item) => $item.Key;
9
11
  const _forTrack1 = ($index, $item) => $item.ID;
10
- const _forTrack2 = ($index, $item) => $item.EntityInfo.ID;
12
+ const _forTrack2 = ($index, $item) => $item.EntityName;
11
13
  function MjFormToolbarComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
12
- i0.ɵɵelement(0, "i", 10);
13
- i0.ɵɵelementStart(1, "span", 11)(2, "strong");
14
+ i0.ɵɵelement(0, "i", 11);
15
+ i0.ɵɵelementStart(1, "span", 12)(2, "strong");
14
16
  i0.ɵɵtext(3);
15
17
  i0.ɵɵelementEnd();
16
18
  i0.ɵɵtext(4);
@@ -23,8 +25,8 @@ function MjFormToolbarComponent_Conditional_0_Conditional_1_Template(rf, ctx) {
23
25
  i0.ɵɵtextInterpolate2(" field", ctx_r1.DirtyFieldDisplayNames.length === 1 ? "" : "s", " modified \u2014 ", ctx_r1.DirtyFieldDisplayNames.join(", "), " ");
24
26
  } }
25
27
  function MjFormToolbarComponent_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
26
- i0.ɵɵelement(0, "i", 12);
27
- i0.ɵɵelementStart(1, "span", 13);
28
+ i0.ɵɵelement(0, "i", 13);
29
+ i0.ɵɵelementStart(1, "span", 14);
28
30
  i0.ɵɵtext(2);
29
31
  i0.ɵɵelementEnd();
30
32
  } if (rf & 2) {
@@ -34,19 +36,19 @@ function MjFormToolbarComponent_Conditional_0_Conditional_2_Template(rf, ctx) {
34
36
  } }
35
37
  function MjFormToolbarComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
36
38
  const _r1 = i0.ɵɵgetCurrentView();
37
- i0.ɵɵelementStart(0, "div", 0);
39
+ i0.ɵɵelementStart(0, "div", 1);
38
40
  i0.ɵɵconditionalCreate(1, MjFormToolbarComponent_Conditional_0_Conditional_1_Template, 5, 3)(2, MjFormToolbarComponent_Conditional_0_Conditional_2_Template, 3, 1);
39
- i0.ɵɵelement(3, "div", 3);
40
- i0.ɵɵelementStart(4, "div", 4)(5, "button", 5);
41
+ i0.ɵɵelement(3, "div", 4);
42
+ i0.ɵɵelementStart(4, "div", 5)(5, "button", 6);
41
43
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_0_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSave()); });
42
- i0.ɵɵelement(6, "i", 6);
43
- i0.ɵɵelementStart(7, "span", 7);
44
+ i0.ɵɵelement(6, "i", 7);
45
+ i0.ɵɵelementStart(7, "span", 8);
44
46
  i0.ɵɵtext(8, "Save Changes");
45
47
  i0.ɵɵelementEnd()();
46
- i0.ɵɵelementStart(9, "button", 8);
48
+ i0.ɵɵelementStart(9, "button", 9);
47
49
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_0_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCancel()); });
48
- i0.ɵɵelement(10, "i", 9);
49
- i0.ɵɵelementStart(11, "span", 7);
50
+ i0.ɵɵelement(10, "i", 10);
51
+ i0.ɵɵelementStart(11, "span", 8);
50
52
  i0.ɵɵtext(12, "Discard");
51
53
  i0.ɵɵelementEnd()()()();
52
54
  } if (rf & 2) {
@@ -60,21 +62,21 @@ function MjFormToolbarComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
60
62
  } }
61
63
  function MjFormToolbarComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
62
64
  const _r3 = i0.ɵɵgetCurrentView();
63
- i0.ɵɵelementStart(0, "button", 25);
65
+ i0.ɵɵelementStart(0, "button", 26);
64
66
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEdit()); });
65
- i0.ɵɵelement(1, "i", 12);
67
+ i0.ɵɵelement(1, "i", 13);
66
68
  i0.ɵɵelementEnd();
67
69
  } }
68
70
  function MjFormToolbarComponent_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
69
71
  const _r4 = i0.ɵɵgetCurrentView();
70
- i0.ɵɵelementStart(0, "button", 26);
72
+ i0.ɵɵelementStart(0, "button", 27);
71
73
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteClick()); });
72
- i0.ɵɵelement(1, "i", 27);
74
+ i0.ɵɵelement(1, "i", 28);
73
75
  i0.ɵɵelementEnd();
74
76
  } }
75
77
  function MjFormToolbarComponent_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
76
78
  const _r5 = i0.ɵɵgetCurrentView();
77
- i0.ɵɵelementStart(0, "button", 28);
79
+ i0.ɵɵelementStart(0, "button", 29);
78
80
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFavoriteToggle()); });
79
81
  i0.ɵɵelement(1, "i");
80
82
  i0.ɵɵelementEnd();
@@ -86,13 +88,13 @@ function MjFormToolbarComponent_Conditional_1_Conditional_4_Template(rf, ctx) {
86
88
  } }
87
89
  function MjFormToolbarComponent_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
88
90
  const _r6 = i0.ɵɵgetCurrentView();
89
- i0.ɵɵelementStart(0, "button", 29);
91
+ i0.ɵɵelementStart(0, "button", 30);
90
92
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnHistory()); });
91
- i0.ɵɵelement(1, "i", 30);
93
+ i0.ɵɵelement(1, "i", 31);
92
94
  i0.ɵɵelementEnd();
93
95
  } }
94
96
  function MjFormToolbarComponent_Conditional_1_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
95
- i0.ɵɵelementStart(0, "span", 33);
97
+ i0.ɵɵelementStart(0, "span", 34);
96
98
  i0.ɵɵtext(1);
97
99
  i0.ɵɵelementEnd();
98
100
  } if (rf & 2) {
@@ -102,10 +104,10 @@ function MjFormToolbarComponent_Conditional_1_Conditional_6_Conditional_2_Templa
102
104
  } }
103
105
  function MjFormToolbarComponent_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
104
106
  const _r7 = i0.ɵɵgetCurrentView();
105
- i0.ɵɵelementStart(0, "button", 31);
107
+ i0.ɵɵelementStart(0, "button", 32);
106
108
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnListManagement()); });
107
- i0.ɵɵelement(1, "i", 32);
108
- i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_1_Conditional_6_Conditional_2_Template, 2, 1, "span", 33);
109
+ i0.ɵɵelement(1, "i", 33);
110
+ i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_1_Conditional_6_Conditional_2_Template, 2, 1, "span", 34);
109
111
  i0.ɵɵelementEnd();
110
112
  } if (rf & 2) {
111
113
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -115,7 +117,7 @@ function MjFormToolbarComponent_Conditional_1_Conditional_6_Template(rf, ctx) {
115
117
  } }
116
118
  function MjFormToolbarComponent_Conditional_1_For_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
117
119
  const _r8 = i0.ɵɵgetCurrentView();
118
- i0.ɵɵelementStart(0, "button", 35);
120
+ i0.ɵɵelementStart(0, "button", 36);
119
121
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_For_8_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const button_r9 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCustomButtonClick(button_r9)); });
120
122
  i0.ɵɵelement(1, "i");
121
123
  i0.ɵɵelementEnd();
@@ -127,23 +129,23 @@ function MjFormToolbarComponent_Conditional_1_For_8_Conditional_0_Template(rf, c
127
129
  i0.ɵɵclassMap(button_r9.Icon);
128
130
  } }
129
131
  function MjFormToolbarComponent_Conditional_1_For_8_Template(rf, ctx) { if (rf & 1) {
130
- i0.ɵɵconditionalCreate(0, MjFormToolbarComponent_Conditional_1_For_8_Conditional_0_Template, 2, 6, "button", 34);
132
+ i0.ɵɵconditionalCreate(0, MjFormToolbarComponent_Conditional_1_For_8_Conditional_0_Template, 2, 6, "button", 35);
131
133
  } if (rf & 2) {
132
134
  const button_r9 = ctx.$implicit;
133
135
  i0.ɵɵconditional(button_r9.Visible !== false ? 0 : -1);
134
136
  } }
135
137
  function MjFormToolbarComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
136
- i0.ɵɵelement(0, "div", 21);
138
+ i0.ɵɵelement(0, "div", 22);
137
139
  } }
138
140
  function MjFormToolbarComponent_Conditional_1_Conditional_10_For_2_Template(rf, ctx) { if (rf & 1) {
139
141
  const _r10 = i0.ɵɵgetCurrentView();
140
- i0.ɵɵelementStart(0, "a", 37);
142
+ i0.ɵɵelementStart(0, "a", 39);
141
143
  i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_10_For_2_Template_a_click_0_listener($event) { const parent_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnParentBadgeClick(parent_r11, $event)); });
142
- i0.ɵɵelement(1, "i", 38);
144
+ i0.ɵɵelement(1, "i", 40);
143
145
  i0.ɵɵtext(2);
144
146
  i0.ɵɵelementEnd();
145
- i0.ɵɵelementStart(3, "span", 39);
146
- i0.ɵɵelement(4, "i", 40);
147
+ i0.ɵɵelementStart(3, "span", 41);
148
+ i0.ɵɵelement(4, "i", 42);
147
149
  i0.ɵɵelementEnd();
148
150
  } if (rf & 2) {
149
151
  const parent_r11 = ctx.$implicit;
@@ -151,30 +153,20 @@ function MjFormToolbarComponent_Conditional_1_Conditional_10_For_2_Template(rf,
151
153
  i0.ɵɵadvance(2);
152
154
  i0.ɵɵtextInterpolate1(" ", parent_r11.Name, " ");
153
155
  } }
154
- function MjFormToolbarComponent_Conditional_1_Conditional_10_For_6_Template(rf, ctx) { if (rf & 1) {
155
- const _r12 = i0.ɵɵgetCurrentView();
156
- i0.ɵɵelementStart(0, "span", 39);
157
- i0.ɵɵelement(1, "i", 40);
158
- i0.ɵɵelementEnd();
159
- i0.ɵɵelementStart(2, "a", 41);
160
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_10_For_6_Template_a_click_2_listener($event) { const child_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnChildBadgeClick(child_r13, $event)); });
161
- i0.ɵɵelement(3, "i", 42);
162
- i0.ɵɵtext(4);
163
- i0.ɵɵelementEnd();
156
+ function MjFormToolbarComponent_Conditional_1_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
157
+ i0.ɵɵelementContainer(0, 38);
164
158
  } if (rf & 2) {
165
- const child_r13 = ctx.$implicit;
166
- i0.ɵɵadvance(2);
167
- i0.ɵɵproperty("title", "Navigate to child: " + child_r13.EntityInfo.Name);
168
- i0.ɵɵadvance(2);
169
- i0.ɵɵtextInterpolate1(" ", child_r13.EntityInfo.Name, " ");
159
+ const ctx_r1 = i0.ɵɵnextContext(3);
160
+ const descendantTreeTpl_r12 = i0.ɵɵreference(5);
161
+ i0.ɵɵproperty("ngTemplateOutlet", descendantTreeTpl_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, ctx_r1.DescendantTree));
170
162
  } }
171
163
  function MjFormToolbarComponent_Conditional_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
172
- i0.ɵɵelementStart(0, "div", 22);
164
+ i0.ɵɵelementStart(0, "div", 23);
173
165
  i0.ɵɵrepeaterCreate(1, MjFormToolbarComponent_Conditional_1_Conditional_10_For_2_Template, 5, 2, null, null, _forTrack1);
174
- i0.ɵɵelementStart(3, "span", 36);
166
+ i0.ɵɵelementStart(3, "span", 37);
175
167
  i0.ɵɵtext(4);
176
168
  i0.ɵɵelementEnd();
177
- i0.ɵɵrepeaterCreate(5, MjFormToolbarComponent_Conditional_1_Conditional_10_For_6_Template, 5, 2, null, null, _forTrack2);
169
+ i0.ɵɵconditionalCreate(5, MjFormToolbarComponent_Conditional_1_Conditional_10_Conditional_5_Template, 1, 4, "ng-container", 38);
178
170
  i0.ɵɵelementEnd();
179
171
  } if (rf & 2) {
180
172
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -183,19 +175,19 @@ function MjFormToolbarComponent_Conditional_1_Conditional_10_Template(rf, ctx) {
183
175
  i0.ɵɵadvance(3);
184
176
  i0.ɵɵtextInterpolate(ctx_r1.EntityInfo == null ? null : ctx_r1.EntityInfo.Name);
185
177
  i0.ɵɵadvance();
186
- i0.ɵɵrepeater(ctx_r1.ChildChain);
178
+ i0.ɵɵconditional(ctx_r1.DescendantTree.length > 0 ? 5 : -1);
187
179
  } }
188
180
  function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
189
- const _r16 = i0.ɵɵgetCurrentView();
181
+ const _r15 = i0.ɵɵgetCurrentView();
190
182
  i0.ɵɵelementStart(0, "button", 53);
191
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnClearFilter()); });
183
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnClearFilter()); });
192
184
  i0.ɵɵelement(1, "i", 54);
193
185
  i0.ɵɵelementEnd();
194
186
  } }
195
187
  function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
196
- const _r15 = i0.ɵɵgetCurrentView();
188
+ const _r14 = i0.ɵɵgetCurrentView();
197
189
  i0.ɵɵelementStart(0, "div", 43)(1, "input", 51);
198
- i0.ɵɵlistener("input", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Template_input_input_1_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFilterInput($event)); });
190
+ i0.ɵɵlistener("input", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Template_input_input_1_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFilterInput($event)); });
199
191
  i0.ɵɵelementEnd();
200
192
  i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Conditional_2_Template, 2, 0, "button", 52);
201
193
  i0.ɵɵelementEnd();
@@ -208,35 +200,35 @@ function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Templ
208
200
  i0.ɵɵconditional(ctx_r1.SearchFilter ? 2 : -1);
209
201
  } }
210
202
  function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_6_Template(rf, ctx) { if (rf & 1) {
211
- const _r17 = i0.ɵɵgetCurrentView();
203
+ const _r16 = i0.ɵɵgetCurrentView();
212
204
  i0.ɵɵelementStart(0, "button", 55);
213
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnResetSectionOrder()); });
205
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnResetSectionOrder()); });
214
206
  i0.ɵɵelement(1, "i", 56);
215
207
  i0.ɵɵelementEnd();
216
208
  } }
217
209
  function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_7_Template(rf, ctx) { if (rf & 1) {
218
- const _r18 = i0.ɵɵgetCurrentView();
210
+ const _r17 = i0.ɵɵgetCurrentView();
219
211
  i0.ɵɵelementStart(0, "button", 57);
220
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnManageSections()); });
212
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnManageSections()); });
221
213
  i0.ɵɵelement(1, "i", 58);
222
214
  i0.ɵɵelementEnd();
223
215
  } }
224
216
  function MjFormToolbarComponent_Conditional_1_Conditional_12_Template(rf, ctx) { if (rf & 1) {
225
- const _r14 = i0.ɵɵgetCurrentView();
226
- i0.ɵɵelementStart(0, "div", 23);
217
+ const _r13 = i0.ɵɵgetCurrentView();
218
+ i0.ɵɵelementStart(0, "div", 24);
227
219
  i0.ɵɵconditionalCreate(1, MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_1_Template, 3, 4, "div", 43);
228
220
  i0.ɵɵelementStart(2, "button", 44);
229
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnExpandAll()); });
221
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnExpandAll()); });
230
222
  i0.ɵɵelement(3, "i", 45);
231
223
  i0.ɵɵelementEnd();
232
224
  i0.ɵɵelementStart(4, "button", 46);
233
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCollapseAll()); });
225
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCollapseAll()); });
234
226
  i0.ɵɵelement(5, "i", 47);
235
227
  i0.ɵɵelementEnd();
236
228
  i0.ɵɵconditionalCreate(6, MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_6_Template, 2, 0, "button", 48);
237
229
  i0.ɵɵconditionalCreate(7, MjFormToolbarComponent_Conditional_1_Conditional_12_Conditional_7_Template, 2, 0, "button", 49);
238
230
  i0.ɵɵelementStart(8, "button", 50);
239
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnToggleWidthMode()); });
231
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_1_Conditional_12_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnToggleWidthMode()); });
240
232
  i0.ɵɵelement(9, "i");
241
233
  i0.ɵɵelementEnd()();
242
234
  } if (rf & 2) {
@@ -257,25 +249,25 @@ function MjFormToolbarComponent_Conditional_1_Conditional_12_Template(rf, ctx) {
257
249
  i0.ɵɵclassMap(ctx_r1.WidthMode === "centered" ? "fa-solid fa-arrows-left-right-to-line" : "fa-solid fa-compress");
258
250
  } }
259
251
  function MjFormToolbarComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
260
- i0.ɵɵelementContainer(0, 24);
252
+ i0.ɵɵelementContainer(0, 25);
261
253
  } if (rf & 2) {
262
254
  const ctx_r1 = i0.ɵɵnextContext(2);
263
255
  i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.AdditionalActionsTemplate);
264
256
  } }
265
257
  function MjFormToolbarComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
266
- i0.ɵɵelementStart(0, "div", 14)(1, "div", 15);
267
- i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_1_Conditional_2_Template, 2, 0, "button", 16);
268
- i0.ɵɵconditionalCreate(3, MjFormToolbarComponent_Conditional_1_Conditional_3_Template, 2, 0, "button", 17);
269
- i0.ɵɵconditionalCreate(4, MjFormToolbarComponent_Conditional_1_Conditional_4_Template, 2, 3, "button", 18);
270
- i0.ɵɵconditionalCreate(5, MjFormToolbarComponent_Conditional_1_Conditional_5_Template, 2, 0, "button", 19);
271
- i0.ɵɵconditionalCreate(6, MjFormToolbarComponent_Conditional_1_Conditional_6_Template, 3, 2, "button", 20);
258
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 16);
259
+ i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_1_Conditional_2_Template, 2, 0, "button", 17);
260
+ i0.ɵɵconditionalCreate(3, MjFormToolbarComponent_Conditional_1_Conditional_3_Template, 2, 0, "button", 18);
261
+ i0.ɵɵconditionalCreate(4, MjFormToolbarComponent_Conditional_1_Conditional_4_Template, 2, 3, "button", 19);
262
+ i0.ɵɵconditionalCreate(5, MjFormToolbarComponent_Conditional_1_Conditional_5_Template, 2, 0, "button", 20);
263
+ i0.ɵɵconditionalCreate(6, MjFormToolbarComponent_Conditional_1_Conditional_6_Template, 3, 2, "button", 21);
272
264
  i0.ɵɵrepeaterCreate(7, MjFormToolbarComponent_Conditional_1_For_8_Template, 1, 1, null, null, _forTrack0);
273
265
  i0.ɵɵelementEnd();
274
- i0.ɵɵconditionalCreate(9, MjFormToolbarComponent_Conditional_1_Conditional_9_Template, 1, 0, "div", 21);
275
- i0.ɵɵconditionalCreate(10, MjFormToolbarComponent_Conditional_1_Conditional_10_Template, 7, 1, "div", 22);
276
- i0.ɵɵelement(11, "div", 3);
277
- i0.ɵɵconditionalCreate(12, MjFormToolbarComponent_Conditional_1_Conditional_12_Template, 10, 8, "div", 23);
278
- i0.ɵɵconditionalCreate(13, MjFormToolbarComponent_Conditional_1_Conditional_13_Template, 1, 1, "ng-container", 24);
266
+ i0.ɵɵconditionalCreate(9, MjFormToolbarComponent_Conditional_1_Conditional_9_Template, 1, 0, "div", 22);
267
+ i0.ɵɵconditionalCreate(10, MjFormToolbarComponent_Conditional_1_Conditional_10_Template, 6, 2, "div", 23);
268
+ i0.ɵɵelement(11, "div", 4);
269
+ i0.ɵɵconditionalCreate(12, MjFormToolbarComponent_Conditional_1_Conditional_12_Template, 10, 8, "div", 24);
270
+ i0.ɵɵconditionalCreate(13, MjFormToolbarComponent_Conditional_1_Conditional_13_Template, 1, 1, "ng-container", 25);
279
271
  i0.ɵɵprojection(14);
280
272
  i0.ɵɵelementEnd();
281
273
  } if (rf & 2) {
@@ -303,16 +295,16 @@ function MjFormToolbarComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
303
295
  i0.ɵɵconditional(ctx_r1.AdditionalActionsTemplate ? 13 : -1);
304
296
  } }
305
297
  function MjFormToolbarComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
306
- const _r19 = i0.ɵɵgetCurrentView();
298
+ const _r18 = i0.ɵɵgetCurrentView();
307
299
  i0.ɵɵelementStart(0, "div", 59);
308
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
300
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
309
301
  i0.ɵɵelementStart(1, "div", 60);
310
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
302
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r18); return i0.ɵɵresetView($event.stopPropagation()); });
311
303
  i0.ɵɵelementStart(2, "div", 61)(3, "h3");
312
304
  i0.ɵɵtext(4, "Discard Changes?");
313
305
  i0.ɵɵelementEnd();
314
306
  i0.ɵɵelementStart(5, "button", 62);
315
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
307
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
316
308
  i0.ɵɵelement(6, "i", 54);
317
309
  i0.ɵɵelementEnd()();
318
310
  i0.ɵɵelementStart(7, "div", 63)(8, "p");
@@ -323,12 +315,12 @@ function MjFormToolbarComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
323
315
  i0.ɵɵtext(12);
324
316
  i0.ɵɵelementEnd()();
325
317
  i0.ɵɵelementStart(13, "div", 64)(14, "button", 65);
326
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardConfirm()); });
327
- i0.ɵɵelement(15, "i", 9);
318
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardConfirm()); });
319
+ i0.ɵɵelement(15, "i", 10);
328
320
  i0.ɵɵtext(16, " Discard Changes ");
329
321
  i0.ɵɵelementEnd();
330
322
  i0.ɵɵelementStart(17, "button", 66);
331
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
323
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_2_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDiscardCancel()); });
332
324
  i0.ɵɵtext(18, " Keep Editing ");
333
325
  i0.ɵɵelementEnd()()()();
334
326
  } if (rf & 2) {
@@ -339,31 +331,100 @@ function MjFormToolbarComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
339
331
  i0.ɵɵtextInterpolate2(" unsaved change", ctx_r1.DirtyFieldDisplayNames.length === 1 ? "" : "s", ". Are you sure you want to discard ", ctx_r1.DirtyFieldDisplayNames.length === 1 ? "it" : "them", "?");
340
332
  } }
341
333
  function MjFormToolbarComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
342
- const _r20 = i0.ɵɵgetCurrentView();
334
+ const _r19 = i0.ɵɵgetCurrentView();
343
335
  i0.ɵɵelementStart(0, "div", 59);
344
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
336
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
345
337
  i0.ɵɵelementStart(1, "div", 60);
346
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r20); return i0.ɵɵresetView($event.stopPropagation()); });
338
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
347
339
  i0.ɵɵelementStart(2, "div", 61)(3, "h3");
348
340
  i0.ɵɵtext(4, "Confirm Deletion");
349
341
  i0.ɵɵelementEnd();
350
342
  i0.ɵɵelementStart(5, "button", 62);
351
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
343
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
352
344
  i0.ɵɵelement(6, "i", 54);
353
345
  i0.ɵɵelementEnd()();
354
346
  i0.ɵɵelementStart(7, "div", 63)(8, "p");
355
347
  i0.ɵɵtext(9, "Are you sure you want to delete this record? This action cannot be undone.");
356
348
  i0.ɵɵelementEnd()();
357
349
  i0.ɵɵelementStart(10, "div", 64)(11, "button", 65);
358
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteConfirm()); });
350
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteConfirm()); });
359
351
  i0.ɵɵelement(12, "i", 67);
360
352
  i0.ɵɵtext(13, " Delete ");
361
353
  i0.ɵɵelementEnd();
362
354
  i0.ɵɵelementStart(14, "button", 66);
363
- i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
355
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_Conditional_3_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDeleteCancel()); });
364
356
  i0.ɵɵtext(15, " Cancel ");
365
357
  i0.ɵɵelementEnd()()()();
366
358
  } }
359
+ function MjFormToolbarComponent_ng_template_4_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
360
+ i0.ɵɵelementContainer(0, 38);
361
+ } if (rf & 2) {
362
+ const items_r21 = i0.ɵɵnextContext(2).items;
363
+ i0.ɵɵnextContext();
364
+ const descendantTreeTpl_r12 = i0.ɵɵreference(5);
365
+ i0.ɵɵproperty("ngTemplateOutlet", descendantTreeTpl_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, items_r21[0].Children));
366
+ } }
367
+ function MjFormToolbarComponent_ng_template_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
368
+ const _r20 = i0.ɵɵgetCurrentView();
369
+ i0.ɵɵelementStart(0, "span", 41);
370
+ i0.ɵɵelement(1, "i", 42);
371
+ i0.ɵɵelementEnd();
372
+ i0.ɵɵelementStart(2, "a", 69);
373
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_ng_template_4_Conditional_0_Template_a_click_2_listener($event) { i0.ɵɵrestoreView(_r20); const items_r21 = i0.ɵɵnextContext().items; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDescendantBadgeClick(items_r21[0].EntityName, $event)); });
374
+ i0.ɵɵelement(3, "i", 70);
375
+ i0.ɵɵtext(4);
376
+ i0.ɵɵelementEnd();
377
+ i0.ɵɵconditionalCreate(5, MjFormToolbarComponent_ng_template_4_Conditional_0_Conditional_5_Template, 1, 4, "ng-container", 38);
378
+ } if (rf & 2) {
379
+ const items_r21 = i0.ɵɵnextContext().items;
380
+ i0.ɵɵadvance(2);
381
+ i0.ɵɵproperty("title", "Navigate to: " + items_r21[0].EntityName);
382
+ i0.ɵɵadvance(2);
383
+ i0.ɵɵtextInterpolate1(" ", items_r21[0].EntityName, " ");
384
+ i0.ɵɵadvance();
385
+ i0.ɵɵconditional(items_r21[0].Children.length > 0 ? 5 : -1);
386
+ } }
387
+ function MjFormToolbarComponent_ng_template_4_Conditional_1_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
388
+ i0.ɵɵelementContainer(0, 38);
389
+ } if (rf & 2) {
390
+ const item_r23 = i0.ɵɵnextContext().$implicit;
391
+ i0.ɵɵnextContext(3);
392
+ const descendantTreeTpl_r12 = i0.ɵɵreference(5);
393
+ i0.ɵɵproperty("ngTemplateOutlet", descendantTreeTpl_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c2, item_r23.Children));
394
+ } }
395
+ function MjFormToolbarComponent_ng_template_4_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
396
+ const _r22 = i0.ɵɵgetCurrentView();
397
+ i0.ɵɵelementStart(0, "div", 71)(1, "a", 69);
398
+ i0.ɵɵlistener("click", function MjFormToolbarComponent_ng_template_4_Conditional_1_For_2_Template_a_click_1_listener($event) { const item_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnDescendantBadgeClick(item_r23.EntityName, $event)); });
399
+ i0.ɵɵelement(2, "i", 70);
400
+ i0.ɵɵtext(3);
401
+ i0.ɵɵelementEnd();
402
+ i0.ɵɵconditionalCreate(4, MjFormToolbarComponent_ng_template_4_Conditional_1_For_2_Conditional_4_Template, 1, 4, "ng-container", 38);
403
+ i0.ɵɵelementEnd();
404
+ } if (rf & 2) {
405
+ const item_r23 = ctx.$implicit;
406
+ i0.ɵɵadvance();
407
+ i0.ɵɵproperty("title", "Navigate to: " + item_r23.EntityName);
408
+ i0.ɵɵadvance(2);
409
+ i0.ɵɵtextInterpolate1(" ", item_r23.EntityName, " ");
410
+ i0.ɵɵadvance();
411
+ i0.ɵɵconditional(item_r23.Children.length > 0 ? 4 : -1);
412
+ } }
413
+ function MjFormToolbarComponent_ng_template_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
414
+ i0.ɵɵelementStart(0, "div", 68);
415
+ i0.ɵɵrepeaterCreate(1, MjFormToolbarComponent_ng_template_4_Conditional_1_For_2_Template, 5, 3, "div", 71, _forTrack2);
416
+ i0.ɵɵelementEnd();
417
+ } if (rf & 2) {
418
+ const items_r21 = i0.ɵɵnextContext().items;
419
+ i0.ɵɵadvance();
420
+ i0.ɵɵrepeater(items_r21);
421
+ } }
422
+ function MjFormToolbarComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
423
+ i0.ɵɵconditionalCreate(0, MjFormToolbarComponent_ng_template_4_Conditional_0_Template, 6, 3)(1, MjFormToolbarComponent_ng_template_4_Conditional_1_Template, 3, 0, "div", 68);
424
+ } if (rf & 2) {
425
+ const items_r21 = ctx.items;
426
+ i0.ɵɵconditional(items_r21.length === 1 ? 0 : items_r21.length > 1 ? 1 : -1);
427
+ } }
367
428
  /**
368
429
  * Configurable form toolbar component.
369
430
  *
@@ -476,11 +537,16 @@ export class MjFormToolbarComponent {
476
537
  // ---- Internal state ----
477
538
  ShowDeleteDialog = false;
478
539
  ShowDiscardDialog = false;
540
+ /** Computed descendant tree for breadcrumb display */
541
+ DescendantTree = [];
542
+ _lastRecordForChains = null;
543
+ _chainsLoading = false;
479
544
  // ---- Lifecycle ----
480
545
  ngDoCheck() {
481
- if (!this._formRef)
482
- return;
483
- this.SyncFromFormRef();
546
+ if (this._formRef) {
547
+ this.SyncFromFormRef();
548
+ }
549
+ this.CheckDescendantChains();
484
550
  }
485
551
  /**
486
552
  * Sync toolbar state from the legacy form reference.
@@ -565,6 +631,9 @@ export class MjFormToolbarComponent {
565
631
  * Walks Record.ISAChild → ISAChild.ISAChild → ... collecting each child entity.
566
632
  * This differs from ChildEntities (metadata) because it represents the SPECIFIC
567
633
  * child type that exists for THIS record, not all possible subtypes.
634
+ *
635
+ * For overlapping subtype parents, this is empty (ISAChild returns null) —
636
+ * use OverlappingChildren instead.
568
637
  */
569
638
  get ChildChain() {
570
639
  if (!this.Record)
@@ -581,9 +650,21 @@ export class MjFormToolbarComponent {
581
650
  get HasLoadedChild() {
582
651
  return this.Record?.ISAChild != null;
583
652
  }
653
+ /**
654
+ * For overlapping subtype parents (AllowMultipleSubtypes = true), returns the
655
+ * list of child entity type names that have records for this PK.
656
+ * Populated by InitializeChildEntity() during record load.
657
+ */
658
+ get OverlappingChildren() {
659
+ return this.Record?.ISAChildren ?? [];
660
+ }
661
+ /** Whether the current record has overlapping child types discovered */
662
+ get HasOverlappingChildren() {
663
+ return this.OverlappingChildren.length > 0;
664
+ }
584
665
  /** Whether this entity is part of any IS-A hierarchy (parent or child side) */
585
666
  get IsInHierarchy() {
586
- return this.HasParentEntities || this.HasLoadedChild;
667
+ return this.HasParentEntities || this.HasLoadedChild || this.HasOverlappingChildren || this.DescendantTree.length > 0;
587
668
  }
588
669
  /** Display-friendly names of dirty fields for the edit banner */
589
670
  get DirtyFieldDisplayNames() {
@@ -606,6 +687,58 @@ export class MjFormToolbarComponent {
606
687
  }
607
688
  return this.Record.PrimaryKey.ToConcatenatedString();
608
689
  }
690
+ // ---- Descendant Chain Computation ----
691
+ /**
692
+ * Check if descendant chains need recomputation (called from DoCheck).
693
+ * Only triggers async computation when the record identity changes.
694
+ */
695
+ CheckDescendantChains() {
696
+ if (!this.Record) {
697
+ if (this.DescendantTree.length > 0) {
698
+ this.DescendantTree = [];
699
+ this._lastRecordForChains = null;
700
+ this.cdr.markForCheck();
701
+ }
702
+ return;
703
+ }
704
+ if (this.Record !== this._lastRecordForChains && !this._chainsLoading) {
705
+ this.ComputeDescendantChains();
706
+ }
707
+ }
708
+ /**
709
+ * Asynchronously discover all IS-A descendants and convert to chains
710
+ * for breadcrumb display. Each chain is a root-to-leaf path of entity names.
711
+ */
712
+ ComputeDescendantChains() {
713
+ this._lastRecordForChains = this.Record;
714
+ if (!this.Record?.EntityInfo?.IsParentType) {
715
+ this.DescendantTree = [];
716
+ return;
717
+ }
718
+ this._chainsLoading = true;
719
+ DiscoverISADescendants(this.Record).then(descendants => {
720
+ this.DescendantTree = BuildDescendantTree(descendants);
721
+ this._chainsLoading = false;
722
+ this.cdr.markForCheck();
723
+ }).catch(() => {
724
+ this.DescendantTree = [];
725
+ this._chainsLoading = false;
726
+ this.cdr.markForCheck();
727
+ });
728
+ }
729
+ /**
730
+ * Navigate to a descendant entity record in the IS-A hierarchy.
731
+ */
732
+ OnDescendantBadgeClick(entityName, event) {
733
+ if (!this.Record)
734
+ return;
735
+ this.Navigate.emit({
736
+ Kind: 'entity-hierarchy',
737
+ EntityName: entityName,
738
+ PrimaryKey: this.Record.PrimaryKey,
739
+ Direction: 'child'
740
+ });
741
+ }
609
742
  // ---- Actions ----
610
743
  OnEdit() {
611
744
  if (this.DispatchToFormRef('StartEditMode'))
@@ -771,6 +904,21 @@ export class MjFormToolbarComponent {
771
904
  Direction: 'child'
772
905
  });
773
906
  }
907
+ /**
908
+ * Navigate to an overlapping child entity record.
909
+ * Used when the parent has AllowMultipleSubtypes = true and multiple child
910
+ * types coexist for the same PK.
911
+ */
912
+ OnOverlappingChildClick(childEntityName, event) {
913
+ if (!this.Record)
914
+ return;
915
+ this.Navigate.emit({
916
+ Kind: 'entity-hierarchy',
917
+ EntityName: childEntityName,
918
+ PrimaryKey: this.Record.PrimaryKey,
919
+ Direction: 'child'
920
+ });
921
+ }
774
922
  // ---- Section Controls ----
775
923
  OnFilterInput(event) {
776
924
  const input = event.target;
@@ -799,12 +947,13 @@ export class MjFormToolbarComponent {
799
947
  this.ManageSectionsRequested.emit();
800
948
  }
801
949
  static ɵfac = function MjFormToolbarComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MjFormToolbarComponent)(); };
802
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormToolbarComponent, selectors: [["mj-form-toolbar"]], inputs: { Form: "Form", _deprecatedForm: [0, "form", "_deprecatedForm"], Record: "Record", EditMode: "EditMode", UserCanEdit: "UserCanEdit", UserCanDelete: "UserCanDelete", IsFavorite: "IsFavorite", FavoriteInitDone: "FavoriteInitDone", IsDirty: "IsDirty", DirtyFieldNames: "DirtyFieldNames", ListCount: "ListCount", EntityInfo: "EntityInfo", Config: "Config", IsSaving: "IsSaving", VisibleSectionCount: "VisibleSectionCount", TotalSectionCount: "TotalSectionCount", ExpandedSectionCount: "ExpandedSectionCount", SearchFilter: "SearchFilter", ShowEmptyFields: "ShowEmptyFields", WidthMode: "WidthMode", HasCustomSectionOrder: "HasCustomSectionOrder", AdditionalActionsTemplate: "AdditionalActionsTemplate" }, outputs: { Navigate: "Navigate", EditModeChange: "EditModeChange", BeforeSave: "BeforeSave", SaveRequested: "SaveRequested", BeforeCancel: "BeforeCancel", CancelRequested: "CancelRequested", BeforeDelete: "BeforeDelete", DeleteRequested: "DeleteRequested", FavoriteToggled: "FavoriteToggled", BeforeHistoryView: "BeforeHistoryView", HistoryRequested: "HistoryRequested", BeforeListManagement: "BeforeListManagement", ListManagementRequested: "ListManagementRequested", ShowChangesRequested: "ShowChangesRequested", CustomButtonClick: "CustomButtonClick", FilterChange: "FilterChange", ExpandAllRequested: "ExpandAllRequested", CollapseAllRequested: "CollapseAllRequested", ShowEmptyFieldsChange: "ShowEmptyFieldsChange", WidthModeChange: "WidthModeChange", ResetSectionOrderRequested: "ResetSectionOrderRequested", ManageSectionsRequested: "ManageSectionsRequested" }, standalone: false, ngContentSelectors: _c1, decls: 4, vars: 4, consts: [[1, "mj-forms-edit-banner"], [1, "mj-forms-toolbar", 3, "mj-forms-toolbar--sticky"], [1, "mj-dialog-overlay"], [1, "mj-forms-toolbar-spacer"], [1, "mj-forms-edit-banner-actions"], ["title", "Save Changes", 1, "mj-forms-btn", "mj-forms-btn--primary", 3, "click", "disabled"], [1, "fa-solid", "fa-floppy-disk"], [1, "mj-forms-btn-text"], ["title", "Discard Changes", 1, "mj-forms-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], [1, "fa-solid", "fa-circle-exclamation", "mj-forms-edit-banner-icon--dirty"], [1, "mj-forms-edit-banner-dirty"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-forms-edit-banner-text"], [1, "mj-forms-toolbar"], [1, "mj-forms-toolbar-group"], ["title", "Edit this Record", 1, "mj-forms-btn"], ["title", "Delete this Record", 1, "mj-forms-btn"], [1, "mj-forms-btn", 3, "title"], ["title", "Record Changes", 1, "mj-forms-btn"], [1, "mj-forms-btn", "mj-forms-btn--list", 3, "title"], [1, "mj-forms-toolbar-separator"], [1, "mj-entity-hierarchy"], [1, "mj-forms-toolbar-group", "mj-section-controls"], [3, "ngTemplateOutlet"], ["title", "Edit this Record", 1, "mj-forms-btn", 3, "click"], ["title", "Delete this Record", 1, "mj-forms-btn", 3, "click"], [1, "fa-regular", "fa-trash-can"], [1, "mj-forms-btn", 3, "click", "title"], ["title", "Record Changes", 1, "mj-forms-btn", 3, "click"], [1, "fa-regular", "fa-clock"], [1, "mj-forms-btn", "mj-forms-btn--list", 3, "click", "title"], [1, "fa-regular", "fa-bookmark"], [1, "mj-list-count-badge"], [1, "mj-forms-btn", 3, "class", "disabled", "title"], [1, "mj-forms-btn", 3, "click", "disabled", "title"], [1, "mj-entity-badge", "mj-entity-badge--current"], [1, "mj-entity-badge", "mj-entity-badge--parent", 3, "click", "title"], [1, "fa-solid", "fa-arrow-up"], [1, "mj-hierarchy-arrow"], [1, "fa-solid", "fa-chevron-right"], [1, "mj-entity-badge", "mj-entity-badge--child", 3, "click", "title"], [1, "fa-solid", "fa-arrow-down"], [1, "mj-forms-search-wrapper"], ["title", "Expand all sections", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-angles-down"], ["title", "Collapse all sections", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-angles-up"], ["title", "Reset section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only"], ["title", "Manage section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only"], [1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "title"], ["type", "text", "placeholder", "Search sections...", 1, "mj-section-search", 3, "input", "value"], ["title", "Clear search", 1, "mj-clear-search"], ["title", "Clear search", 1, "mj-clear-search", 3, "click"], [1, "fa-solid", "fa-xmark"], ["title", "Reset section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click"], [1, "fa-solid", "fa-arrow-rotate-left"], ["title", "Manage section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click"], [1, "fa-solid", "fa-bars-staggered"], [1, "mj-dialog-overlay", 3, "click"], [1, "mj-dialog", 3, "click"], [1, "mj-dialog-header"], [1, "mj-dialog-close", 3, "click"], [1, "mj-dialog-body"], [1, "mj-dialog-footer"], [1, "mj-forms-btn", "mj-forms-btn--danger", 3, "click"], [1, "mj-forms-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"]], template: function MjFormToolbarComponent_Template(rf, ctx) { if (rf & 1) {
950
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjFormToolbarComponent, selectors: [["mj-form-toolbar"]], inputs: { Form: "Form", _deprecatedForm: [0, "form", "_deprecatedForm"], Record: "Record", EditMode: "EditMode", UserCanEdit: "UserCanEdit", UserCanDelete: "UserCanDelete", IsFavorite: "IsFavorite", FavoriteInitDone: "FavoriteInitDone", IsDirty: "IsDirty", DirtyFieldNames: "DirtyFieldNames", ListCount: "ListCount", EntityInfo: "EntityInfo", Config: "Config", IsSaving: "IsSaving", VisibleSectionCount: "VisibleSectionCount", TotalSectionCount: "TotalSectionCount", ExpandedSectionCount: "ExpandedSectionCount", SearchFilter: "SearchFilter", ShowEmptyFields: "ShowEmptyFields", WidthMode: "WidthMode", HasCustomSectionOrder: "HasCustomSectionOrder", AdditionalActionsTemplate: "AdditionalActionsTemplate" }, outputs: { Navigate: "Navigate", EditModeChange: "EditModeChange", BeforeSave: "BeforeSave", SaveRequested: "SaveRequested", BeforeCancel: "BeforeCancel", CancelRequested: "CancelRequested", BeforeDelete: "BeforeDelete", DeleteRequested: "DeleteRequested", FavoriteToggled: "FavoriteToggled", BeforeHistoryView: "BeforeHistoryView", HistoryRequested: "HistoryRequested", BeforeListManagement: "BeforeListManagement", ListManagementRequested: "ListManagementRequested", ShowChangesRequested: "ShowChangesRequested", CustomButtonClick: "CustomButtonClick", FilterChange: "FilterChange", ExpandAllRequested: "ExpandAllRequested", CollapseAllRequested: "CollapseAllRequested", ShowEmptyFieldsChange: "ShowEmptyFieldsChange", WidthModeChange: "WidthModeChange", ResetSectionOrderRequested: "ResetSectionOrderRequested", ManageSectionsRequested: "ManageSectionsRequested" }, standalone: false, ngContentSelectors: _c1, decls: 6, vars: 4, consts: [["descendantTreeTpl", ""], [1, "mj-forms-edit-banner"], [1, "mj-forms-toolbar", 3, "mj-forms-toolbar--sticky"], [1, "mj-dialog-overlay"], [1, "mj-forms-toolbar-spacer"], [1, "mj-forms-edit-banner-actions"], ["title", "Save Changes", 1, "mj-forms-btn", "mj-forms-btn--primary", 3, "click", "disabled"], [1, "fa-solid", "fa-floppy-disk"], [1, "mj-forms-btn-text"], ["title", "Discard Changes", 1, "mj-forms-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], [1, "fa-solid", "fa-circle-exclamation", "mj-forms-edit-banner-icon--dirty"], [1, "mj-forms-edit-banner-dirty"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-forms-edit-banner-text"], [1, "mj-forms-toolbar"], [1, "mj-forms-toolbar-group"], ["title", "Edit this Record", 1, "mj-forms-btn"], ["title", "Delete this Record", 1, "mj-forms-btn"], [1, "mj-forms-btn", 3, "title"], ["title", "MJ: Record Changes", 1, "mj-forms-btn"], [1, "mj-forms-btn", "mj-forms-btn--list", 3, "title"], [1, "mj-forms-toolbar-separator"], [1, "mj-entity-hierarchy"], [1, "mj-forms-toolbar-group", "mj-section-controls"], [3, "ngTemplateOutlet"], ["title", "Edit this Record", 1, "mj-forms-btn", 3, "click"], ["title", "Delete this Record", 1, "mj-forms-btn", 3, "click"], [1, "fa-regular", "fa-trash-can"], [1, "mj-forms-btn", 3, "click", "title"], ["title", "MJ: Record Changes", 1, "mj-forms-btn", 3, "click"], [1, "fa-regular", "fa-clock"], [1, "mj-forms-btn", "mj-forms-btn--list", 3, "click", "title"], [1, "fa-regular", "fa-bookmark"], [1, "mj-list-count-badge"], [1, "mj-forms-btn", 3, "class", "disabled", "title"], [1, "mj-forms-btn", 3, "click", "disabled", "title"], [1, "mj-entity-badge", "mj-entity-badge--current"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "mj-entity-badge", "mj-entity-badge--parent", 3, "click", "title"], [1, "fa-solid", "fa-arrow-up"], [1, "mj-hierarchy-arrow"], [1, "fa-solid", "fa-chevron-right"], [1, "mj-forms-search-wrapper"], ["title", "Expand all sections", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-angles-down"], ["title", "Collapse all sections", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-angles-up"], ["title", "Reset section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only"], ["title", "Manage section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only"], [1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click", "title"], ["type", "text", "placeholder", "Search sections...", 1, "mj-section-search", 3, "input", "value"], ["title", "Clear search", 1, "mj-clear-search"], ["title", "Clear search", 1, "mj-clear-search", 3, "click"], [1, "fa-solid", "fa-xmark"], ["title", "Reset section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click"], [1, "fa-solid", "fa-arrow-rotate-left"], ["title", "Manage section order", 1, "mj-forms-btn", "mj-forms-btn--ghost", "mj-forms-btn--icon-only", 3, "click"], [1, "fa-solid", "fa-bars-staggered"], [1, "mj-dialog-overlay", 3, "click"], [1, "mj-dialog", 3, "click"], [1, "mj-dialog-header"], [1, "mj-dialog-close", 3, "click"], [1, "mj-dialog-body"], [1, "mj-dialog-footer"], [1, "mj-forms-btn", "mj-forms-btn--danger", 3, "click"], [1, "mj-forms-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "mj-descendant-chains"], [1, "mj-entity-badge", "mj-entity-badge--child", 3, "click", "title"], [1, "fa-solid", "fa-arrow-down"], [1, "mj-descendant-chain"]], template: function MjFormToolbarComponent_Template(rf, ctx) { if (rf & 1) {
803
951
  i0.ɵɵprojectionDef(_c0);
804
- i0.ɵɵconditionalCreate(0, MjFormToolbarComponent_Conditional_0_Template, 13, 3, "div", 0);
805
- i0.ɵɵconditionalCreate(1, MjFormToolbarComponent_Conditional_1_Template, 15, 11, "div", 1);
806
- i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_2_Template, 19, 3, "div", 2);
807
- i0.ɵɵconditionalCreate(3, MjFormToolbarComponent_Conditional_3_Template, 16, 0, "div", 2);
952
+ i0.ɵɵconditionalCreate(0, MjFormToolbarComponent_Conditional_0_Template, 13, 3, "div", 1);
953
+ i0.ɵɵconditionalCreate(1, MjFormToolbarComponent_Conditional_1_Template, 15, 11, "div", 2);
954
+ i0.ɵɵconditionalCreate(2, MjFormToolbarComponent_Conditional_2_Template, 19, 3, "div", 3);
955
+ i0.ɵɵconditionalCreate(3, MjFormToolbarComponent_Conditional_3_Template, 16, 0, "div", 3);
956
+ i0.ɵɵtemplate(4, MjFormToolbarComponent_ng_template_4_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
808
957
  } if (rf & 2) {
809
958
  i0.ɵɵconditional(ctx.EditMode && ctx.Config.ShowEditBanner ? 0 : -1);
810
959
  i0.ɵɵadvance();
@@ -813,11 +962,11 @@ export class MjFormToolbarComponent {
813
962
  i0.ɵɵconditional(ctx.ShowDiscardDialog ? 2 : -1);
814
963
  i0.ɵɵadvance();
815
964
  i0.ɵɵconditional(ctx.ShowDeleteDialog ? 3 : -1);
816
- } }, dependencies: [i1.NgTemplateOutlet], styles: ["\n\n\n\n[_nghost-%COMP%] {\n --mj-forms-toolbar-bg: #f9fafb;\n --mj-card-bg: #ffffff;\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #6b7280;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-isa-parent: #8b5cf6;\n --mj-isa-child: #06b6d4;\n --mj-transition: 200ms;\n\n display: block;\n}\n\n\n\n\n\n.mj-forms-edit-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 16px;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n border-bottom: 2px solid var(--mj-accent);\n font-size: 13px;\n color: var(--mj-accent);\n font-weight: 500;\n}\n\n.mj-forms-edit-banner[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-icon--dirty[_ngcontent-%COMP%] {\n color: var(--mj-warning);\n font-size: 16px;\n}\n\n.mj-forms-edit-banner-text[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-dirty[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #374151;\n}\n\n.mj-forms-edit-banner-dirty[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-warning);\n font-weight: 700;\n}\n\n.mj-forms-edit-banner-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n\n\n.mj-forms-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 22px 16px;\n background: var(--mj-forms-toolbar-bg);\n border-bottom: 2px solid var(--mj-border);\n flex-wrap: wrap;\n z-index: 40;\n}\n\n.mj-forms-toolbar--sticky[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n}\n\n.mj-forms-toolbar--disabled[_ngcontent-%COMP%] {\n pointer-events: none;\n opacity: 0.7;\n}\n\n.mj-forms-toolbar-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-forms-toolbar-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 24px;\n background: var(--mj-border);\n margin: 0 4px;\n}\n\n.mj-forms-toolbar-spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n\n\n.mj-forms-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid var(--mj-border);\n background: var(--mj-card-bg);\n color: var(--mj-text-primary);\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n white-space: nowrap;\n font-family: inherit;\n line-height: 1;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n border-color: #9ca3af;\n box-shadow: 0 1px 3px rgba(0,0,0,0.08);\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n box-shadow: none;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n line-height: 1;\n}\n\n.mj-forms-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-accent);\n color: white;\n border-color: var(--mj-accent);\n}\n\n.mj-forms-btn--primary[_ngcontent-%COMP%]:hover {\n background: #5a6fd6;\n border-color: #5a6fd6;\n box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);\n}\n\n.mj-forms-btn--danger[_ngcontent-%COMP%] {\n color: var(--mj-error);\n border-color: #fecaca;\n background: #fef2f2;\n}\n\n.mj-forms-btn--danger[_ngcontent-%COMP%]:hover {\n background: #fee2e2;\n border-color: var(--mj-error);\n}\n\n.mj-forms-btn--ghost[_ngcontent-%COMP%] {\n border-color: transparent;\n background: transparent;\n}\n\n.mj-forms-btn--ghost[_ngcontent-%COMP%]:hover {\n background: var(--mj-accent-light);\n border-color: transparent;\n}\n\n.mj-forms-btn--icon-only[_ngcontent-%COMP%] {\n padding: 7px 9px;\n}\n\n.mj-forms-btn--sm[_ngcontent-%COMP%] {\n padding: 5px 12px;\n font-size: 12px;\n}\n\n.mj-forms-btn--sm[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.mj-forms-btn-text[_ngcontent-%COMP%] {\n margin-left: 2px;\n}\n\n.mj-icon--favorite[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n\n\n.mj-forms-btn--list[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.mj-list-count-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--mj-forms-toolbar-bg);\n}\n\n\n\n\n\n.mj-entity-hierarchy[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.mj-entity-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n text-decoration: none;\n border: 1px solid transparent;\n}\n\n.mj-entity-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.mj-entity-badge--parent[_ngcontent-%COMP%] {\n background: #f3f0ff;\n color: var(--mj-isa-parent);\n border-color: #e0d5ff;\n}\n\n.mj-entity-badge--parent[_ngcontent-%COMP%]:hover {\n background: #e8e0ff;\n border-color: var(--mj-isa-parent);\n box-shadow: 0 2px 6px rgba(139, 92, 246, 0.15);\n}\n\n.mj-entity-badge--current[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n padding: 4px 8px;\n background: #f3f4f6;\n border-radius: 6px;\n cursor: default;\n}\n\n.mj-entity-badge--child[_ngcontent-%COMP%] {\n background: #ecfeff;\n color: var(--mj-isa-child);\n border-color: #cffafe;\n}\n\n.mj-entity-badge--child[_ngcontent-%COMP%]:hover {\n background: #cffafe;\n border-color: var(--mj-isa-child);\n box-shadow: 0 2px 6px rgba(6, 182, 212, 0.15);\n}\n\n.mj-child-count[_ngcontent-%COMP%] {\n background: var(--mj-isa-child);\n color: white;\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 8px;\n font-weight: 700;\n}\n\n.mj-entity-badge--leaf[_ngcontent-%COMP%] {\n border-style: dashed;\n}\n\n.mj-entity-badge--root[_ngcontent-%COMP%] {\n border-style: dashed;\n}\n\n.mj-hierarchy-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n\n\n\n\n\n\n\n\n.mj-section-controls[_ngcontent-%COMP%] {\n gap: 6px;\n}\n\n.mj-forms-search-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.mj-section-search[_ngcontent-%COMP%] {\n max-width: 180px;\n font-size: 13px;\n padding: 6px 28px 6px 8px;\n border: 1px solid var(--mj-border);\n border-radius: 6px;\n background: white;\n outline: none;\n font-family: inherit;\n transition: all var(--mj-transition);\n}\n\n.mj-section-search[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);\n}\n\n\n\n.mj-section-search--active[_ngcontent-%COMP%] {\n background-color: #fef08a;\n border-color: #eab308;\n color: #854d0e;\n font-weight: 600;\n box-shadow: 0 0 0 2px rgba(254, 240, 138, 0.5);\n}\n\n.mj-section-search[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 4px;\n padding: 4px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 12px;\n line-height: 1;\n}\n\n.mj-clear-search[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n\n\n\n\n.mj-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_mj-fade-in 150ms ease;\n}\n\n.mj-dialog[_ngcontent-%COMP%] {\n background: var(--mj-card-bg);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n min-width: 400px;\n max-width: 550px;\n animation: _ngcontent-%COMP%_mj-slide-up 200ms ease;\n}\n\n.mj-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border);\n}\n\n.mj-dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mj-dialog-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n font-size: 16px;\n transition: color var(--mj-transition);\n}\n\n.mj-dialog-close[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mj-dialog-body[_ngcontent-%COMP%] {\n padding: 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.mj-dialog-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.mj-dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border);\n}\n\n@keyframes _ngcontent-%COMP%_mj-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes _ngcontent-%COMP%_mj-slide-up {\n from { transform: translateY(8px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}"], changeDetection: 0 });
965
+ } }, dependencies: [i1.NgTemplateOutlet], styles: ["\n\n\n\n[_nghost-%COMP%] {\n --mj-forms-toolbar-bg: #f9fafb;\n --mj-card-bg: #ffffff;\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #6b7280;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-isa-parent: #8b5cf6;\n --mj-isa-child: #06b6d4;\n --mj-transition: 200ms;\n\n display: block;\n}\n\n\n\n\n\n.mj-forms-edit-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 16px;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n border-bottom: 2px solid var(--mj-accent);\n font-size: 13px;\n color: var(--mj-accent);\n font-weight: 500;\n}\n\n.mj-forms-edit-banner[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-icon--dirty[_ngcontent-%COMP%] {\n color: var(--mj-warning);\n font-size: 16px;\n}\n\n.mj-forms-edit-banner-text[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-dirty[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #374151;\n}\n\n.mj-forms-edit-banner-dirty[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-warning);\n font-weight: 700;\n}\n\n.mj-forms-edit-banner-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n\n\n.mj-forms-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 22px 16px;\n background: var(--mj-forms-toolbar-bg);\n border-bottom: 2px solid var(--mj-border);\n flex-wrap: wrap;\n z-index: 40;\n}\n\n.mj-forms-toolbar--sticky[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n}\n\n.mj-forms-toolbar--disabled[_ngcontent-%COMP%] {\n pointer-events: none;\n opacity: 0.7;\n}\n\n.mj-forms-toolbar-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-forms-toolbar-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 24px;\n background: var(--mj-border);\n margin: 0 4px;\n}\n\n.mj-forms-toolbar-spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n\n\n.mj-forms-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid var(--mj-border);\n background: var(--mj-card-bg);\n color: var(--mj-text-primary);\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n white-space: nowrap;\n font-family: inherit;\n line-height: 1;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n border-color: #9ca3af;\n box-shadow: 0 1px 3px rgba(0,0,0,0.08);\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n box-shadow: none;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mj-forms-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n line-height: 1;\n}\n\n.mj-forms-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-accent);\n color: white;\n border-color: var(--mj-accent);\n}\n\n.mj-forms-btn--primary[_ngcontent-%COMP%]:hover {\n background: #5a6fd6;\n border-color: #5a6fd6;\n box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);\n}\n\n.mj-forms-btn--danger[_ngcontent-%COMP%] {\n color: var(--mj-error);\n border-color: #fecaca;\n background: #fef2f2;\n}\n\n.mj-forms-btn--danger[_ngcontent-%COMP%]:hover {\n background: #fee2e2;\n border-color: var(--mj-error);\n}\n\n.mj-forms-btn--ghost[_ngcontent-%COMP%] {\n border-color: transparent;\n background: transparent;\n}\n\n.mj-forms-btn--ghost[_ngcontent-%COMP%]:hover {\n background: var(--mj-accent-light);\n border-color: transparent;\n}\n\n.mj-forms-btn--icon-only[_ngcontent-%COMP%] {\n padding: 7px 9px;\n}\n\n.mj-forms-btn--sm[_ngcontent-%COMP%] {\n padding: 5px 12px;\n font-size: 12px;\n}\n\n.mj-forms-btn--sm[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.mj-forms-btn-text[_ngcontent-%COMP%] {\n margin-left: 2px;\n}\n\n.mj-icon--favorite[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n\n\n.mj-forms-btn--list[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.mj-list-count-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--mj-forms-toolbar-bg);\n}\n\n\n\n\n\n.mj-entity-hierarchy[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.mj-entity-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n text-decoration: none;\n border: 1px solid transparent;\n}\n\n.mj-entity-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.mj-entity-badge--parent[_ngcontent-%COMP%] {\n background: #f3f0ff;\n color: var(--mj-isa-parent);\n border-color: #e0d5ff;\n}\n\n.mj-entity-badge--parent[_ngcontent-%COMP%]:hover {\n background: #e8e0ff;\n border-color: var(--mj-isa-parent);\n box-shadow: 0 2px 6px rgba(139, 92, 246, 0.15);\n}\n\n.mj-entity-badge--current[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n padding: 4px 8px;\n background: #f3f4f6;\n border-radius: 6px;\n cursor: default;\n}\n\n.mj-entity-badge--child[_ngcontent-%COMP%] {\n background: #ecfeff;\n color: var(--mj-isa-child);\n border-color: #cffafe;\n}\n\n.mj-entity-badge--child[_ngcontent-%COMP%]:hover {\n background: #cffafe;\n border-color: var(--mj-isa-child);\n box-shadow: 0 2px 6px rgba(6, 182, 212, 0.15);\n}\n\n.mj-entity-badge--overlapping[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: #d97706;\n border-color: #fde68a;\n}\n\n.mj-entity-badge--overlapping[_ngcontent-%COMP%]:hover {\n background: #fef3c7;\n border-color: #d97706;\n box-shadow: 0 2px 6px rgba(217, 119, 6, 0.15);\n}\n\n.mj-entity-badge-group[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.mj-child-count[_ngcontent-%COMP%] {\n background: var(--mj-isa-child);\n color: white;\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 8px;\n font-weight: 700;\n}\n\n.mj-entity-badge--leaf[_ngcontent-%COMP%] {\n border-style: dashed;\n}\n\n.mj-entity-badge--root[_ngcontent-%COMP%] {\n border-style: dashed;\n}\n\n.mj-hierarchy-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n\n\n\n.mj-descendant-chains[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n position: relative;\n padding-left: 20px;\n}\n\n\n\n.mj-descendant-chains[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -4px;\n top: 50%;\n width: 4px;\n border-top: 1.5px solid var(--mj-text-muted);\n}\n\n.mj-descendant-chain[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n position: relative;\n padding: 2px 0;\n}\n\n\n\n.mj-descendant-chain[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -20px;\n top: 50%;\n width: 18px;\n border-top: 1.5px solid var(--mj-text-muted);\n}\n\n\n\n.mj-descendant-chain[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: -20px;\n top: 0;\n bottom: 0;\n border-left: 1.5px solid var(--mj-text-muted);\n}\n\n\n\n.mj-descendant-chain[_ngcontent-%COMP%]:first-child::after {\n top: 50%;\n}\n\n\n\n.mj-descendant-chain[_ngcontent-%COMP%]:last-child::after {\n bottom: 50%;\n}\n\n\n\n\n\n\n\n\n.mj-section-controls[_ngcontent-%COMP%] {\n gap: 6px;\n}\n\n.mj-forms-search-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.mj-section-search[_ngcontent-%COMP%] {\n max-width: 180px;\n font-size: 13px;\n padding: 6px 28px 6px 8px;\n border: 1px solid var(--mj-border);\n border-radius: 6px;\n background: white;\n outline: none;\n font-family: inherit;\n transition: all var(--mj-transition);\n}\n\n.mj-section-search[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);\n}\n\n\n\n.mj-section-search--active[_ngcontent-%COMP%] {\n background-color: #fef08a;\n border-color: #eab308;\n color: #854d0e;\n font-weight: 600;\n box-shadow: 0 0 0 2px rgba(254, 240, 138, 0.5);\n}\n\n.mj-section-search[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-clear-search[_ngcontent-%COMP%] {\n position: absolute;\n right: 4px;\n padding: 4px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 12px;\n line-height: 1;\n}\n\n.mj-clear-search[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n\n\n\n\n.mj-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_mj-fade-in 150ms ease;\n}\n\n.mj-dialog[_ngcontent-%COMP%] {\n background: var(--mj-card-bg);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n min-width: 400px;\n max-width: 550px;\n animation: _ngcontent-%COMP%_mj-slide-up 200ms ease;\n}\n\n.mj-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border);\n}\n\n.mj-dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mj-dialog-close[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n font-size: 16px;\n transition: color var(--mj-transition);\n}\n\n.mj-dialog-close[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.mj-dialog-body[_ngcontent-%COMP%] {\n padding: 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.mj-dialog-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.mj-dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border);\n}\n\n@keyframes _ngcontent-%COMP%_mj-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes _ngcontent-%COMP%_mj-slide-up {\n from { transform: translateY(8px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}"], changeDetection: 0 });
817
966
  }
818
967
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjFormToolbarComponent, [{
819
968
  type: Component,
820
- args: [{ standalone: false, selector: 'mj-form-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- ============================================\n EDIT MODE BANNER (shows above toolbar when editing)\n ============================================ -->\n@if (EditMode && Config.ShowEditBanner) {\n <div class=\"mj-forms-edit-banner\">\n @if (DirtyFieldDisplayNames.length > 0) {\n <i class=\"fa-solid fa-circle-exclamation mj-forms-edit-banner-icon--dirty\"></i>\n <span class=\"mj-forms-edit-banner-dirty\">\n <strong>{{ DirtyFieldDisplayNames.length }}</strong>\n field{{ DirtyFieldDisplayNames.length === 1 ? '' : 's' }} modified\n &mdash; {{ DirtyFieldDisplayNames.join(', ') }}\n </span>\n } @else {\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span class=\"mj-forms-edit-banner-text\">Editing: {{ RecordDisplayName }}</span>\n }\n <div class=\"mj-forms-toolbar-spacer\"></div>\n <div class=\"mj-forms-edit-banner-actions\">\n <button class=\"mj-forms-btn mj-forms-btn--primary\" (click)=\"OnSave()\" [disabled]=\"IsSaving\" title=\"Save Changes\">\n <i class=\"fa-solid fa-floppy-disk\"></i>\n <span class=\"mj-forms-btn-text\">Save Changes</span>\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnCancel()\" [disabled]=\"IsSaving\" title=\"Discard Changes\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n <span class=\"mj-forms-btn-text\">Discard</span>\n </button>\n </div>\n </div>\n}\n\n<!-- ============================================\n MAIN TOOLBAR (read mode only \u2014 hidden in edit mode)\n ============================================ -->\n@if (!EditMode) {\n <div class=\"mj-forms-toolbar\" [class.mj-forms-toolbar--sticky]=\"Config.StickyToolbar\">\n\n <!-- Action buttons -->\n <div class=\"mj-forms-toolbar-group\">\n @if (Config.ShowEditButton && UserCanEdit) {\n <button class=\"mj-forms-btn\" (click)=\"OnEdit()\" title=\"Edit this Record\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n </button>\n }\n @if (Config.ShowDeleteButton && UserCanDelete) {\n <button class=\"mj-forms-btn\" (click)=\"OnDeleteClick()\" title=\"Delete this Record\">\n <i class=\"fa-regular fa-trash-can\"></i>\n </button>\n }\n @if (Config.ShowFavoriteButton && FavoriteInitDone) {\n <button class=\"mj-forms-btn\" (click)=\"OnFavoriteToggle()\" [title]=\"IsFavorite ? 'Remove Favorite' : 'Make Favorite'\">\n <i [class]=\"IsFavorite ? 'fa-solid fa-star mj-icon--favorite' : 'fa-regular fa-star'\"></i>\n </button>\n }\n @if (Config.ShowHistoryButton && TracksChanges) {\n <button class=\"mj-forms-btn\" (click)=\"OnHistory()\" title=\"Record Changes\">\n <i class=\"fa-regular fa-clock\"></i>\n </button>\n }\n @if (Config.ShowListButton) {\n <button class=\"mj-forms-btn mj-forms-btn--list\" (click)=\"OnListManagement()\"\n [title]=\"ListCount > 0 ? 'Member of ' + ListCount + ' list(s)' : 'Add to a list'\">\n <i class=\"fa-regular fa-bookmark\"></i>\n @if (ListCount > 0) {\n <span class=\"mj-list-count-badge\">{{ ListCount }}</span>\n }\n </button>\n }\n\n <!-- Custom toolbar buttons -->\n @for (button of Config.CustomButtons; track button.Key) {\n @if (button.Visible !== false) {\n <button class=\"mj-forms-btn\"\n [class]=\"button.CssClass || ''\"\n [disabled]=\"button.Disabled || false\"\n [title]=\"button.Description\"\n (click)=\"OnCustomButtonClick(button)\">\n <i [class]=\"button.Icon\"></i>\n </button>\n }\n }\n </div>\n\n <!-- Separator before hierarchy -->\n @if (Config.ShowEntityHierarchy && IsInHierarchy) {\n <div class=\"mj-forms-toolbar-separator\"></div>\n }\n\n <!-- IS-A Entity Hierarchy Breadcrumb (bidirectional: Root \u2192 ... \u2192 Current \u2192 ... \u2192 Leaf) -->\n @if (Config.ShowEntityHierarchy && IsInHierarchy) {\n <div class=\"mj-entity-hierarchy\">\n <!-- Parent chain (root \u2192 ... \u2192 immediate parent) -->\n @for (parent of ParentChain; track parent.ID) {\n <a class=\"mj-entity-badge mj-entity-badge--parent\"\n [title]=\"'Navigate to parent: ' + parent.Name\"\n (click)=\"OnParentBadgeClick(parent, $event)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n {{ parent.Name }}\n </a>\n <span class=\"mj-hierarchy-arrow\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n }\n\n <!-- Current entity (always shown) -->\n <span class=\"mj-entity-badge mj-entity-badge--current\">{{ EntityInfo?.Name }}</span>\n\n <!-- Child chain (immediate child \u2192 ... \u2192 leaf) -->\n @for (child of ChildChain; track child.EntityInfo.ID) {\n <span class=\"mj-hierarchy-arrow\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n <a class=\"mj-entity-badge mj-entity-badge--child\"\n [title]=\"'Navigate to child: ' + child.EntityInfo.Name\"\n (click)=\"OnChildBadgeClick(child, $event)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n {{ child.EntityInfo.Name }}\n </a>\n }\n </div>\n }\n\n <!-- Spacer pushes section controls to the right -->\n <div class=\"mj-forms-toolbar-spacer\"></div>\n\n <!-- Section Controls -->\n @if (Config.ShowSectionControls) {\n <div class=\"mj-forms-toolbar-group mj-section-controls\">\n @if (Config.ShowSectionFilter) {\n <div class=\"mj-forms-search-wrapper\">\n <input type=\"text\"\n class=\"mj-section-search\"\n [class.mj-section-search--active]=\"SearchFilter\"\n [value]=\"SearchFilter\"\n (input)=\"OnFilterInput($event)\"\n placeholder=\"Search sections...\">\n @if (SearchFilter) {\n <button class=\"mj-clear-search\" (click)=\"OnClearFilter()\" title=\"Clear search\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n [disabled]=\"ExpandedSectionCount >= VisibleSectionCount\"\n (click)=\"OnExpandAll()\" title=\"Expand all sections\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n [disabled]=\"ExpandedSectionCount === 0\"\n (click)=\"OnCollapseAll()\" title=\"Collapse all sections\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n @if (HasCustomSectionOrder) {\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\" (click)=\"OnResetSectionOrder()\" title=\"Reset section order\">\n <i class=\"fa-solid fa-arrow-rotate-left\"></i>\n </button>\n }\n @if (Config.ShowSectionManager) {\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n (click)=\"OnManageSections()\" title=\"Manage section order\">\n <i class=\"fa-solid fa-bars-staggered\"></i>\n </button>\n }\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n (click)=\"OnToggleWidthMode()\"\n [title]=\"WidthMode === 'centered' ? 'Expand to full width' : 'Center content'\">\n <i [class]=\"WidthMode === 'centered' ? 'fa-solid fa-arrows-left-right-to-line' : 'fa-solid fa-compress'\"></i>\n </button>\n </div>\n }\n\n <!-- Additional actions slot -->\n @if (AdditionalActionsTemplate) {\n <ng-container [ngTemplateOutlet]=\"AdditionalActionsTemplate\"></ng-container>\n }\n <ng-content select=\"[toolbar-additional-controls]\"></ng-content>\n </div>\n}\n\n<!-- ============================================\n DISCARD CHANGES CONFIRMATION DIALOG\n ============================================ -->\n@if (ShowDiscardDialog) {\n <div class=\"mj-dialog-overlay\" (click)=\"OnDiscardCancel()\">\n <div class=\"mj-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-dialog-header\">\n <h3>Discard Changes?</h3>\n <button class=\"mj-dialog-close\" (click)=\"OnDiscardCancel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"mj-dialog-body\">\n <p>You have <strong>{{ DirtyFieldDisplayNames.length }}</strong> unsaved change{{ DirtyFieldDisplayNames.length === 1 ? '' : 's' }}. Are you sure you want to discard {{ DirtyFieldDisplayNames.length === 1 ? 'it' : 'them' }}?</p>\n </div>\n <div class=\"mj-dialog-footer\">\n <button class=\"mj-forms-btn mj-forms-btn--danger\" (click)=\"OnDiscardConfirm()\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n Discard Changes\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnDiscardCancel()\">\n Keep Editing\n </button>\n </div>\n </div>\n </div>\n}\n\n<!-- ============================================\n DELETE CONFIRMATION DIALOG\n ============================================ -->\n@if (ShowDeleteDialog) {\n <div class=\"mj-dialog-overlay\" (click)=\"OnDeleteCancel()\">\n <div class=\"mj-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-dialog-header\">\n <h3>Confirm Deletion</h3>\n <button class=\"mj-dialog-close\" (click)=\"OnDeleteCancel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"mj-dialog-body\">\n <p>Are you sure you want to delete this record? This action cannot be undone.</p>\n </div>\n <div class=\"mj-dialog-footer\">\n <button class=\"mj-forms-btn mj-forms-btn--danger\" (click)=\"OnDeleteConfirm()\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnDeleteCancel()\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n}\n", styles: ["/* ============================================\n CSS VARIABLES (theming hooks)\n ============================================ */\n:host {\n --mj-forms-toolbar-bg: #f9fafb;\n --mj-card-bg: #ffffff;\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #6b7280;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-isa-parent: #8b5cf6;\n --mj-isa-child: #06b6d4;\n --mj-transition: 200ms;\n\n display: block;\n}\n\n/* ============================================\n EDIT BANNER\n ============================================ */\n.mj-forms-edit-banner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 16px;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n border-bottom: 2px solid var(--mj-accent);\n font-size: 13px;\n color: var(--mj-accent);\n font-weight: 500;\n}\n\n.mj-forms-edit-banner > i {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-icon--dirty {\n color: var(--mj-warning);\n font-size: 16px;\n}\n\n.mj-forms-edit-banner-text {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-dirty {\n font-size: 14px;\n color: #374151;\n}\n\n.mj-forms-edit-banner-dirty strong {\n color: var(--mj-warning);\n font-weight: 700;\n}\n\n.mj-forms-edit-banner-actions {\n display: flex;\n gap: 8px;\n}\n\n/* ============================================\n MAIN TOOLBAR\n ============================================ */\n.mj-forms-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 22px 16px;\n background: var(--mj-forms-toolbar-bg);\n border-bottom: 2px solid var(--mj-border);\n flex-wrap: wrap;\n z-index: 40;\n}\n\n.mj-forms-toolbar--sticky {\n position: sticky;\n top: 0;\n}\n\n.mj-forms-toolbar--disabled {\n pointer-events: none;\n opacity: 0.7;\n}\n\n.mj-forms-toolbar-group {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-forms-toolbar-separator {\n width: 1px;\n height: 24px;\n background: var(--mj-border);\n margin: 0 4px;\n}\n\n.mj-forms-toolbar-spacer {\n flex: 1;\n}\n\n/* ============================================\n BUTTONS\n ============================================ */\n.mj-forms-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid var(--mj-border);\n background: var(--mj-card-bg);\n color: var(--mj-text-primary);\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n white-space: nowrap;\n font-family: inherit;\n line-height: 1;\n}\n\n.mj-forms-btn:hover {\n background: #f3f4f6;\n border-color: #9ca3af;\n box-shadow: 0 1px 3px rgba(0,0,0,0.08);\n}\n\n.mj-forms-btn:active {\n transform: translateY(0);\n box-shadow: none;\n}\n\n.mj-forms-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mj-forms-btn i {\n font-size: 15px;\n line-height: 1;\n}\n\n.mj-forms-btn--primary {\n background: var(--mj-accent);\n color: white;\n border-color: var(--mj-accent);\n}\n\n.mj-forms-btn--primary:hover {\n background: #5a6fd6;\n border-color: #5a6fd6;\n box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);\n}\n\n.mj-forms-btn--danger {\n color: var(--mj-error);\n border-color: #fecaca;\n background: #fef2f2;\n}\n\n.mj-forms-btn--danger:hover {\n background: #fee2e2;\n border-color: var(--mj-error);\n}\n\n.mj-forms-btn--ghost {\n border-color: transparent;\n background: transparent;\n}\n\n.mj-forms-btn--ghost:hover {\n background: var(--mj-accent-light);\n border-color: transparent;\n}\n\n.mj-forms-btn--icon-only {\n padding: 7px 9px;\n}\n\n.mj-forms-btn--sm {\n padding: 5px 12px;\n font-size: 12px;\n}\n\n.mj-forms-btn--sm i {\n font-size: 12px;\n}\n\n.mj-forms-btn-text {\n margin-left: 2px;\n}\n\n.mj-icon--favorite {\n color: #f59e0b;\n}\n\n/* List button with count badge */\n.mj-forms-btn--list {\n position: relative;\n}\n\n.mj-list-count-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--mj-forms-toolbar-bg);\n}\n\n/* ============================================\n IS-A ENTITY HIERARCHY\n ============================================ */\n.mj-entity-hierarchy {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.mj-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n text-decoration: none;\n border: 1px solid transparent;\n}\n\n.mj-entity-badge i {\n font-size: 11px;\n}\n\n.mj-entity-badge--parent {\n background: #f3f0ff;\n color: var(--mj-isa-parent);\n border-color: #e0d5ff;\n}\n\n.mj-entity-badge--parent:hover {\n background: #e8e0ff;\n border-color: var(--mj-isa-parent);\n box-shadow: 0 2px 6px rgba(139, 92, 246, 0.15);\n}\n\n.mj-entity-badge--current {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n padding: 4px 8px;\n background: #f3f4f6;\n border-radius: 6px;\n cursor: default;\n}\n\n.mj-entity-badge--child {\n background: #ecfeff;\n color: var(--mj-isa-child);\n border-color: #cffafe;\n}\n\n.mj-entity-badge--child:hover {\n background: #cffafe;\n border-color: var(--mj-isa-child);\n box-shadow: 0 2px 6px rgba(6, 182, 212, 0.15);\n}\n\n.mj-child-count {\n background: var(--mj-isa-child);\n color: white;\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 8px;\n font-weight: 700;\n}\n\n.mj-entity-badge--leaf {\n border-style: dashed;\n}\n\n.mj-entity-badge--root {\n border-style: dashed;\n}\n\n.mj-hierarchy-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n\n/* (dirty summary removed \u2014 now inline in edit banner) */\n\n/* ============================================\n SECTION CONTROLS\n ============================================ */\n.mj-section-controls {\n gap: 6px;\n}\n\n.mj-forms-search-wrapper {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.mj-section-search {\n max-width: 180px;\n font-size: 13px;\n padding: 6px 28px 6px 8px;\n border: 1px solid var(--mj-border);\n border-radius: 6px;\n background: white;\n outline: none;\n font-family: inherit;\n transition: all var(--mj-transition);\n}\n\n.mj-section-search:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);\n}\n\n/* Active filter highlight \u2014 matches the yellow used on matched panel/field names */\n.mj-section-search--active {\n background-color: #fef08a;\n border-color: #eab308;\n color: #854d0e;\n font-weight: 600;\n box-shadow: 0 0 0 2px rgba(254, 240, 138, 0.5);\n}\n\n.mj-section-search::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-clear-search {\n position: absolute;\n right: 4px;\n padding: 4px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 12px;\n line-height: 1;\n}\n\n.mj-clear-search:hover {\n color: var(--mj-text-secondary);\n}\n\n/* ============================================\n DIALOG (lightweight inline)\n ============================================ */\n.mj-dialog-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: mj-fade-in 150ms ease;\n}\n\n.mj-dialog {\n background: var(--mj-card-bg);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n min-width: 400px;\n max-width: 550px;\n animation: mj-slide-up 200ms ease;\n}\n\n.mj-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border);\n}\n\n.mj-dialog-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mj-dialog-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n font-size: 16px;\n transition: color var(--mj-transition);\n}\n\n.mj-dialog-close:hover {\n color: var(--mj-text-primary);\n}\n\n.mj-dialog-body {\n padding: 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.mj-dialog-body p {\n margin: 0;\n}\n\n.mj-dialog-footer {\n display: flex;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border);\n}\n\n@keyframes mj-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes mj-slide-up {\n from { transform: translateY(8px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n"] }]
969
+ args: [{ standalone: false, selector: 'mj-form-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- ============================================\n EDIT MODE BANNER (shows above toolbar when editing)\n ============================================ -->\n@if (EditMode && Config.ShowEditBanner) {\n <div class=\"mj-forms-edit-banner\">\n @if (DirtyFieldDisplayNames.length > 0) {\n <i class=\"fa-solid fa-circle-exclamation mj-forms-edit-banner-icon--dirty\"></i>\n <span class=\"mj-forms-edit-banner-dirty\">\n <strong>{{ DirtyFieldDisplayNames.length }}</strong>\n field{{ DirtyFieldDisplayNames.length === 1 ? '' : 's' }} modified\n &mdash; {{ DirtyFieldDisplayNames.join(', ') }}\n </span>\n } @else {\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span class=\"mj-forms-edit-banner-text\">Editing: {{ RecordDisplayName }}</span>\n }\n <div class=\"mj-forms-toolbar-spacer\"></div>\n <div class=\"mj-forms-edit-banner-actions\">\n <button class=\"mj-forms-btn mj-forms-btn--primary\" (click)=\"OnSave()\" [disabled]=\"IsSaving\" title=\"Save Changes\">\n <i class=\"fa-solid fa-floppy-disk\"></i>\n <span class=\"mj-forms-btn-text\">Save Changes</span>\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnCancel()\" [disabled]=\"IsSaving\" title=\"Discard Changes\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n <span class=\"mj-forms-btn-text\">Discard</span>\n </button>\n </div>\n </div>\n}\n\n<!-- ============================================\n MAIN TOOLBAR (read mode only \u2014 hidden in edit mode)\n ============================================ -->\n@if (!EditMode) {\n <div class=\"mj-forms-toolbar\" [class.mj-forms-toolbar--sticky]=\"Config.StickyToolbar\">\n\n <!-- Action buttons -->\n <div class=\"mj-forms-toolbar-group\">\n @if (Config.ShowEditButton && UserCanEdit) {\n <button class=\"mj-forms-btn\" (click)=\"OnEdit()\" title=\"Edit this Record\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n </button>\n }\n @if (Config.ShowDeleteButton && UserCanDelete) {\n <button class=\"mj-forms-btn\" (click)=\"OnDeleteClick()\" title=\"Delete this Record\">\n <i class=\"fa-regular fa-trash-can\"></i>\n </button>\n }\n @if (Config.ShowFavoriteButton && FavoriteInitDone) {\n <button class=\"mj-forms-btn\" (click)=\"OnFavoriteToggle()\" [title]=\"IsFavorite ? 'Remove Favorite' : 'Make Favorite'\">\n <i [class]=\"IsFavorite ? 'fa-solid fa-star mj-icon--favorite' : 'fa-regular fa-star'\"></i>\n </button>\n }\n @if (Config.ShowHistoryButton && TracksChanges) {\n <button class=\"mj-forms-btn\" (click)=\"OnHistory()\" title=\"MJ: Record Changes\">\n <i class=\"fa-regular fa-clock\"></i>\n </button>\n }\n @if (Config.ShowListButton) {\n <button class=\"mj-forms-btn mj-forms-btn--list\" (click)=\"OnListManagement()\"\n [title]=\"ListCount > 0 ? 'Member of ' + ListCount + ' list(s)' : 'Add to a list'\">\n <i class=\"fa-regular fa-bookmark\"></i>\n @if (ListCount > 0) {\n <span class=\"mj-list-count-badge\">{{ ListCount }}</span>\n }\n </button>\n }\n\n <!-- Custom toolbar buttons -->\n @for (button of Config.CustomButtons; track button.Key) {\n @if (button.Visible !== false) {\n <button class=\"mj-forms-btn\"\n [class]=\"button.CssClass || ''\"\n [disabled]=\"button.Disabled || false\"\n [title]=\"button.Description\"\n (click)=\"OnCustomButtonClick(button)\">\n <i [class]=\"button.Icon\"></i>\n </button>\n }\n }\n </div>\n\n <!-- Separator before hierarchy -->\n @if (Config.ShowEntityHierarchy && IsInHierarchy) {\n <div class=\"mj-forms-toolbar-separator\"></div>\n }\n\n <!-- IS-A Entity Hierarchy Breadcrumb (bidirectional: Root \u2192 ... \u2192 Current \u2192 ... \u2192 Leaf) -->\n @if (Config.ShowEntityHierarchy && IsInHierarchy) {\n <div class=\"mj-entity-hierarchy\">\n <!-- Parent chain (root \u2192 ... \u2192 immediate parent) -->\n @for (parent of ParentChain; track parent.ID) {\n <a class=\"mj-entity-badge mj-entity-badge--parent\"\n [title]=\"'Navigate to parent: ' + parent.Name\"\n (click)=\"OnParentBadgeClick(parent, $event)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n {{ parent.Name }}\n </a>\n <span class=\"mj-hierarchy-arrow\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n }\n\n <!-- Current entity (always shown) -->\n <span class=\"mj-entity-badge mj-entity-badge--current\">{{ EntityInfo?.Name }}</span>\n\n <!-- Descendant tree (recursive: inline for single paths, branching for multiple) -->\n @if (DescendantTree.length > 0) {\n <ng-container [ngTemplateOutlet]=\"descendantTreeTpl\"\n [ngTemplateOutletContext]=\"{ items: DescendantTree }\"></ng-container>\n }\n </div>\n }\n\n <!-- Spacer pushes section controls to the right -->\n <div class=\"mj-forms-toolbar-spacer\"></div>\n\n <!-- Section Controls -->\n @if (Config.ShowSectionControls) {\n <div class=\"mj-forms-toolbar-group mj-section-controls\">\n @if (Config.ShowSectionFilter) {\n <div class=\"mj-forms-search-wrapper\">\n <input type=\"text\"\n class=\"mj-section-search\"\n [class.mj-section-search--active]=\"SearchFilter\"\n [value]=\"SearchFilter\"\n (input)=\"OnFilterInput($event)\"\n placeholder=\"Search sections...\">\n @if (SearchFilter) {\n <button class=\"mj-clear-search\" (click)=\"OnClearFilter()\" title=\"Clear search\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n [disabled]=\"ExpandedSectionCount >= VisibleSectionCount\"\n (click)=\"OnExpandAll()\" title=\"Expand all sections\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n [disabled]=\"ExpandedSectionCount === 0\"\n (click)=\"OnCollapseAll()\" title=\"Collapse all sections\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n @if (HasCustomSectionOrder) {\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\" (click)=\"OnResetSectionOrder()\" title=\"Reset section order\">\n <i class=\"fa-solid fa-arrow-rotate-left\"></i>\n </button>\n }\n @if (Config.ShowSectionManager) {\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n (click)=\"OnManageSections()\" title=\"Manage section order\">\n <i class=\"fa-solid fa-bars-staggered\"></i>\n </button>\n }\n <button class=\"mj-forms-btn mj-forms-btn--ghost mj-forms-btn--icon-only\"\n (click)=\"OnToggleWidthMode()\"\n [title]=\"WidthMode === 'centered' ? 'Expand to full width' : 'Center content'\">\n <i [class]=\"WidthMode === 'centered' ? 'fa-solid fa-arrows-left-right-to-line' : 'fa-solid fa-compress'\"></i>\n </button>\n </div>\n }\n\n <!-- Additional actions slot -->\n @if (AdditionalActionsTemplate) {\n <ng-container [ngTemplateOutlet]=\"AdditionalActionsTemplate\"></ng-container>\n }\n <ng-content select=\"[toolbar-additional-controls]\"></ng-content>\n </div>\n}\n\n<!-- ============================================\n DISCARD CHANGES CONFIRMATION DIALOG\n ============================================ -->\n@if (ShowDiscardDialog) {\n <div class=\"mj-dialog-overlay\" (click)=\"OnDiscardCancel()\">\n <div class=\"mj-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-dialog-header\">\n <h3>Discard Changes?</h3>\n <button class=\"mj-dialog-close\" (click)=\"OnDiscardCancel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"mj-dialog-body\">\n <p>You have <strong>{{ DirtyFieldDisplayNames.length }}</strong> unsaved change{{ DirtyFieldDisplayNames.length === 1 ? '' : 's' }}. Are you sure you want to discard {{ DirtyFieldDisplayNames.length === 1 ? 'it' : 'them' }}?</p>\n </div>\n <div class=\"mj-dialog-footer\">\n <button class=\"mj-forms-btn mj-forms-btn--danger\" (click)=\"OnDiscardConfirm()\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n Discard Changes\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnDiscardCancel()\">\n Keep Editing\n </button>\n </div>\n </div>\n </div>\n}\n\n<!-- ============================================\n DELETE CONFIRMATION DIALOG\n ============================================ -->\n@if (ShowDeleteDialog) {\n <div class=\"mj-dialog-overlay\" (click)=\"OnDeleteCancel()\">\n <div class=\"mj-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-dialog-header\">\n <h3>Confirm Deletion</h3>\n <button class=\"mj-dialog-close\" (click)=\"OnDeleteCancel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"mj-dialog-body\">\n <p>Are you sure you want to delete this record? This action cannot be undone.</p>\n </div>\n <div class=\"mj-dialog-footer\">\n <button class=\"mj-forms-btn mj-forms-btn--danger\" (click)=\"OnDeleteConfirm()\">\n <i class=\"fa-solid fa-trash-can\"></i>\n Delete\n </button>\n <button class=\"mj-forms-btn\" (click)=\"OnDeleteCancel()\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n}\n\n<!-- Recursive template for IS-A descendant tree rendering.\n Single child at a level \u2192 inline with chevron.\n Multiple children at a level \u2192 tree branch with CSS connector lines. -->\n<ng-template #descendantTreeTpl let-items=\"items\">\n @if (items.length === 1) {\n <span class=\"mj-hierarchy-arrow\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n <a class=\"mj-entity-badge mj-entity-badge--child\"\n [title]=\"'Navigate to: ' + items[0].EntityName\"\n (click)=\"OnDescendantBadgeClick(items[0].EntityName, $event)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n {{ items[0].EntityName }}\n </a>\n @if (items[0].Children.length > 0) {\n <ng-container [ngTemplateOutlet]=\"descendantTreeTpl\"\n [ngTemplateOutletContext]=\"{ items: items[0].Children }\"></ng-container>\n }\n } @else if (items.length > 1) {\n <div class=\"mj-descendant-chains\">\n @for (item of items; track item.EntityName) {\n <div class=\"mj-descendant-chain\">\n <a class=\"mj-entity-badge mj-entity-badge--child\"\n [title]=\"'Navigate to: ' + item.EntityName\"\n (click)=\"OnDescendantBadgeClick(item.EntityName, $event)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n {{ item.EntityName }}\n </a>\n @if (item.Children.length > 0) {\n <ng-container [ngTemplateOutlet]=\"descendantTreeTpl\"\n [ngTemplateOutletContext]=\"{ items: item.Children }\"></ng-container>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: ["/* ============================================\n CSS VARIABLES (theming hooks)\n ============================================ */\n:host {\n --mj-forms-toolbar-bg: #f9fafb;\n --mj-card-bg: #ffffff;\n --mj-accent: #667eea;\n --mj-accent-light: rgba(102, 126, 234, 0.08);\n --mj-text-primary: #1f2937;\n --mj-text-secondary: #6b7280;\n --mj-text-muted: #9ca3af;\n --mj-border: #e5e7eb;\n --mj-error: #ef4444;\n --mj-warning: #f59e0b;\n --mj-isa-parent: #8b5cf6;\n --mj-isa-child: #06b6d4;\n --mj-transition: 200ms;\n\n display: block;\n}\n\n/* ============================================\n EDIT BANNER\n ============================================ */\n.mj-forms-edit-banner {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 16px;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n border-bottom: 2px solid var(--mj-accent);\n font-size: 13px;\n color: var(--mj-accent);\n font-weight: 500;\n}\n\n.mj-forms-edit-banner > i {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-icon--dirty {\n color: var(--mj-warning);\n font-size: 16px;\n}\n\n.mj-forms-edit-banner-text {\n font-size: 14px;\n}\n\n.mj-forms-edit-banner-dirty {\n font-size: 14px;\n color: #374151;\n}\n\n.mj-forms-edit-banner-dirty strong {\n color: var(--mj-warning);\n font-weight: 700;\n}\n\n.mj-forms-edit-banner-actions {\n display: flex;\n gap: 8px;\n}\n\n/* ============================================\n MAIN TOOLBAR\n ============================================ */\n.mj-forms-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 22px 16px;\n background: var(--mj-forms-toolbar-bg);\n border-bottom: 2px solid var(--mj-border);\n flex-wrap: wrap;\n z-index: 40;\n}\n\n.mj-forms-toolbar--sticky {\n position: sticky;\n top: 0;\n}\n\n.mj-forms-toolbar--disabled {\n pointer-events: none;\n opacity: 0.7;\n}\n\n.mj-forms-toolbar-group {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.mj-forms-toolbar-separator {\n width: 1px;\n height: 24px;\n background: var(--mj-border);\n margin: 0 4px;\n}\n\n.mj-forms-toolbar-spacer {\n flex: 1;\n}\n\n/* ============================================\n BUTTONS\n ============================================ */\n.mj-forms-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid var(--mj-border);\n background: var(--mj-card-bg);\n color: var(--mj-text-primary);\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n white-space: nowrap;\n font-family: inherit;\n line-height: 1;\n}\n\n.mj-forms-btn:hover {\n background: #f3f4f6;\n border-color: #9ca3af;\n box-shadow: 0 1px 3px rgba(0,0,0,0.08);\n}\n\n.mj-forms-btn:active {\n transform: translateY(0);\n box-shadow: none;\n}\n\n.mj-forms-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mj-forms-btn i {\n font-size: 15px;\n line-height: 1;\n}\n\n.mj-forms-btn--primary {\n background: var(--mj-accent);\n color: white;\n border-color: var(--mj-accent);\n}\n\n.mj-forms-btn--primary:hover {\n background: #5a6fd6;\n border-color: #5a6fd6;\n box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);\n}\n\n.mj-forms-btn--danger {\n color: var(--mj-error);\n border-color: #fecaca;\n background: #fef2f2;\n}\n\n.mj-forms-btn--danger:hover {\n background: #fee2e2;\n border-color: var(--mj-error);\n}\n\n.mj-forms-btn--ghost {\n border-color: transparent;\n background: transparent;\n}\n\n.mj-forms-btn--ghost:hover {\n background: var(--mj-accent-light);\n border-color: transparent;\n}\n\n.mj-forms-btn--icon-only {\n padding: 7px 9px;\n}\n\n.mj-forms-btn--sm {\n padding: 5px 12px;\n font-size: 12px;\n}\n\n.mj-forms-btn--sm i {\n font-size: 12px;\n}\n\n.mj-forms-btn-text {\n margin-left: 2px;\n}\n\n.mj-icon--favorite {\n color: #f59e0b;\n}\n\n/* List button with count badge */\n.mj-forms-btn--list {\n position: relative;\n}\n\n.mj-list-count-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--mj-forms-toolbar-bg);\n}\n\n/* ============================================\n IS-A ENTITY HIERARCHY\n ============================================ */\n.mj-entity-hierarchy {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.mj-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n font-size: 12px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n transition: all var(--mj-transition) ease;\n text-decoration: none;\n border: 1px solid transparent;\n}\n\n.mj-entity-badge i {\n font-size: 11px;\n}\n\n.mj-entity-badge--parent {\n background: #f3f0ff;\n color: var(--mj-isa-parent);\n border-color: #e0d5ff;\n}\n\n.mj-entity-badge--parent:hover {\n background: #e8e0ff;\n border-color: var(--mj-isa-parent);\n box-shadow: 0 2px 6px rgba(139, 92, 246, 0.15);\n}\n\n.mj-entity-badge--current {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n padding: 4px 8px;\n background: #f3f4f6;\n border-radius: 6px;\n cursor: default;\n}\n\n.mj-entity-badge--child {\n background: #ecfeff;\n color: var(--mj-isa-child);\n border-color: #cffafe;\n}\n\n.mj-entity-badge--child:hover {\n background: #cffafe;\n border-color: var(--mj-isa-child);\n box-shadow: 0 2px 6px rgba(6, 182, 212, 0.15);\n}\n\n.mj-entity-badge--overlapping {\n background: #fffbeb;\n color: #d97706;\n border-color: #fde68a;\n}\n\n.mj-entity-badge--overlapping:hover {\n background: #fef3c7;\n border-color: #d97706;\n box-shadow: 0 2px 6px rgba(217, 119, 6, 0.15);\n}\n\n.mj-entity-badge-group {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.mj-child-count {\n background: var(--mj-isa-child);\n color: white;\n font-size: 10px;\n padding: 1px 5px;\n border-radius: 8px;\n font-weight: 700;\n}\n\n.mj-entity-badge--leaf {\n border-style: dashed;\n}\n\n.mj-entity-badge--root {\n border-style: dashed;\n}\n\n.mj-hierarchy-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n}\n\n/* Descendant chain tree (connecting lines when multiple chains branch) */\n.mj-descendant-chains {\n display: flex;\n flex-direction: column;\n gap: 6px;\n position: relative;\n padding-left: 20px;\n}\n\n/* Horizontal connector from parent entity badge to tree trunk */\n.mj-descendant-chains::before {\n content: '';\n position: absolute;\n left: -4px;\n top: 50%;\n width: 4px;\n border-top: 1.5px solid var(--mj-text-muted);\n}\n\n.mj-descendant-chain {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n position: relative;\n padding: 2px 0;\n}\n\n/* Horizontal branch line from trunk to chain content */\n.mj-descendant-chain::before {\n content: '';\n position: absolute;\n left: -20px;\n top: 50%;\n width: 18px;\n border-top: 1.5px solid var(--mj-text-muted);\n}\n\n/* Vertical trunk segment (each chain draws its portion) */\n.mj-descendant-chain::after {\n content: '';\n position: absolute;\n left: -20px;\n top: 0;\n bottom: 0;\n border-left: 1.5px solid var(--mj-text-muted);\n}\n\n/* First chain: trunk starts from center */\n.mj-descendant-chain:first-child::after {\n top: 50%;\n}\n\n/* Last chain: trunk ends at center */\n.mj-descendant-chain:last-child::after {\n bottom: 50%;\n}\n\n/* (dirty summary removed \u2014 now inline in edit banner) */\n\n/* ============================================\n SECTION CONTROLS\n ============================================ */\n.mj-section-controls {\n gap: 6px;\n}\n\n.mj-forms-search-wrapper {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.mj-section-search {\n max-width: 180px;\n font-size: 13px;\n padding: 6px 28px 6px 8px;\n border: 1px solid var(--mj-border);\n border-radius: 6px;\n background: white;\n outline: none;\n font-family: inherit;\n transition: all var(--mj-transition);\n}\n\n.mj-section-search:focus {\n border-color: var(--mj-accent);\n box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);\n}\n\n/* Active filter highlight \u2014 matches the yellow used on matched panel/field names */\n.mj-section-search--active {\n background-color: #fef08a;\n border-color: #eab308;\n color: #854d0e;\n font-weight: 600;\n box-shadow: 0 0 0 2px rgba(254, 240, 138, 0.5);\n}\n\n.mj-section-search::placeholder {\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n.mj-clear-search {\n position: absolute;\n right: 4px;\n padding: 4px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 12px;\n line-height: 1;\n}\n\n.mj-clear-search:hover {\n color: var(--mj-text-secondary);\n}\n\n/* ============================================\n DIALOG (lightweight inline)\n ============================================ */\n.mj-dialog-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: mj-fade-in 150ms ease;\n}\n\n.mj-dialog {\n background: var(--mj-card-bg);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n min-width: 400px;\n max-width: 550px;\n animation: mj-slide-up 200ms ease;\n}\n\n.mj-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border);\n}\n\n.mj-dialog-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.mj-dialog-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n font-size: 16px;\n transition: color var(--mj-transition);\n}\n\n.mj-dialog-close:hover {\n color: var(--mj-text-primary);\n}\n\n.mj-dialog-body {\n padding: 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n line-height: 1.6;\n}\n\n.mj-dialog-body p {\n margin: 0;\n}\n\n.mj-dialog-footer {\n display: flex;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border);\n}\n\n@keyframes mj-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes mj-slide-up {\n from { transform: translateY(8px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n}\n"] }]
821
970
  }], null, { Form: [{
822
971
  type: Input
823
972
  }], _deprecatedForm: [{
@@ -908,5 +1057,5 @@ export class MjFormToolbarComponent {
908
1057
  }], ManageSectionsRequested: [{
909
1058
  type: Output
910
1059
  }] }); })();
911
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjFormToolbarComponent, { className: "MjFormToolbarComponent", filePath: "src/lib/toolbar/form-toolbar.component.ts", lineNumber: 45 }); })();
1060
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjFormToolbarComponent, { className: "MjFormToolbarComponent", filePath: "src/lib/toolbar/form-toolbar.component.ts", lineNumber: 46 }); })();
912
1061
  //# sourceMappingURL=form-toolbar.component.js.map