@memberjunction/ng-base-forms 6.1.0-edge.2 → 6.1.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +180 -4
- package/README.md +4 -1
- package/dist/lib/base-form-component.d.ts +93 -3
- package/dist/lib/base-form-component.d.ts.map +1 -1
- package/dist/lib/base-form-component.js +240 -9
- package/dist/lib/base-form-component.js.map +1 -1
- package/dist/lib/chrome/base-form-policy.d.ts +26 -0
- package/dist/lib/chrome/base-form-policy.d.ts.map +1 -0
- package/dist/lib/chrome/base-form-policy.js +9 -0
- package/dist/lib/chrome/base-form-policy.js.map +1 -0
- package/dist/lib/chrome/clipped-title.d.ts +8 -0
- package/dist/lib/chrome/clipped-title.d.ts.map +1 -0
- package/dist/lib/chrome/clipped-title.js +18 -0
- package/dist/lib/chrome/clipped-title.js.map +1 -0
- package/dist/lib/chrome/form-chrome-coordinator.service.d.ts +35 -0
- package/dist/lib/chrome/form-chrome-coordinator.service.d.ts.map +1 -0
- package/dist/lib/chrome/form-chrome-coordinator.service.js +96 -0
- package/dist/lib/chrome/form-chrome-coordinator.service.js.map +1 -0
- package/dist/lib/chrome/form-chrome-rail-pref.d.ts +24 -0
- package/dist/lib/chrome/form-chrome-rail-pref.d.ts.map +1 -0
- package/dist/lib/chrome/form-chrome-rail-pref.js +52 -0
- package/dist/lib/chrome/form-chrome-rail-pref.js.map +1 -0
- package/dist/lib/chrome/form-chrome.d.ts +59 -0
- package/dist/lib/chrome/form-chrome.d.ts.map +1 -0
- package/dist/lib/chrome/form-chrome.js +37 -0
- package/dist/lib/chrome/form-chrome.js.map +1 -0
- package/dist/lib/chrome/load-form-chrome-rules.d.ts +8 -0
- package/dist/lib/chrome/load-form-chrome-rules.d.ts.map +1 -0
- package/dist/lib/chrome/load-form-chrome-rules.js +70 -0
- package/dist/lib/chrome/load-form-chrome-rules.js.map +1 -0
- package/dist/lib/chrome/resolve-form-chrome.d.ts +114 -0
- package/dist/lib/chrome/resolve-form-chrome.d.ts.map +1 -0
- package/dist/lib/chrome/resolve-form-chrome.js +713 -0
- package/dist/lib/chrome/resolve-form-chrome.js.map +1 -0
- package/dist/lib/container/record-form-container.component.d.ts +170 -6
- package/dist/lib/container/record-form-container.component.d.ts.map +1 -1
- package/dist/lib/container/record-form-container.component.js +1194 -62
- package/dist/lib/container/record-form-container.component.js.map +1 -1
- package/dist/lib/explorer-entity-data-grid.component.d.ts +54 -1
- package/dist/lib/explorer-entity-data-grid.component.d.ts.map +1 -1
- package/dist/lib/explorer-entity-data-grid.component.js +143 -7
- package/dist/lib/explorer-entity-data-grid.component.js.map +1 -1
- package/dist/lib/form-record-refresh.coordinator.d.ts +27 -0
- package/dist/lib/form-record-refresh.coordinator.d.ts.map +1 -0
- package/dist/lib/form-record-refresh.coordinator.js +33 -0
- package/dist/lib/form-record-refresh.coordinator.js.map +1 -0
- package/dist/lib/form-state.interface.d.ts +4 -0
- package/dist/lib/form-state.interface.d.ts.map +1 -1
- package/dist/lib/form-state.interface.js.map +1 -1
- package/dist/lib/form-state.service.d.ts +5 -0
- package/dist/lib/form-state.service.d.ts.map +1 -1
- package/dist/lib/form-state.service.js +23 -2
- package/dist/lib/form-state.service.js.map +1 -1
- package/dist/lib/host/entity-form-host.component.d.ts +5 -1
- package/dist/lib/host/entity-form-host.component.d.ts.map +1 -1
- package/dist/lib/host/entity-form-host.component.js +16 -2
- package/dist/lib/host/entity-form-host.component.js.map +1 -1
- package/dist/lib/isa-related-panel/isa-related-panel.component.d.ts +6 -2
- package/dist/lib/isa-related-panel/isa-related-panel.component.d.ts.map +1 -1
- package/dist/lib/isa-related-panel/isa-related-panel.component.js +15 -1
- package/dist/lib/isa-related-panel/isa-related-panel.component.js.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.d.ts +24 -2
- package/dist/lib/panel/collapsible-panel.component.d.ts.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.js +104 -10
- package/dist/lib/panel/collapsible-panel.component.js.map +1 -1
- package/dist/lib/panel-slot/base-form-panel.d.ts +85 -1
- package/dist/lib/panel-slot/base-form-panel.d.ts.map +1 -1
- package/dist/lib/panel-slot/base-form-panel.js +72 -3
- package/dist/lib/panel-slot/base-form-panel.js.map +1 -1
- package/dist/lib/panel-slot/collect-form-panel-registrations.d.ts +8 -0
- package/dist/lib/panel-slot/collect-form-panel-registrations.d.ts.map +1 -0
- package/dist/lib/panel-slot/collect-form-panel-registrations.js +19 -0
- package/dist/lib/panel-slot/collect-form-panel-registrations.js.map +1 -0
- package/dist/lib/panel-slot/form-contribution.d.ts +79 -0
- package/dist/lib/panel-slot/form-contribution.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-contribution.js +253 -0
- package/dist/lib/panel-slot/form-contribution.js.map +1 -0
- package/dist/lib/panel-slot/form-contributions.component.d.ts +27 -0
- package/dist/lib/panel-slot/form-contributions.component.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-contributions.component.js +83 -0
- package/dist/lib/panel-slot/form-contributions.component.js.map +1 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts +2 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts.map +1 -1
- package/dist/lib/panel-slot/form-panel-slot.component.js +35 -4
- package/dist/lib/panel-slot/form-panel-slot.component.js.map +1 -1
- package/dist/lib/panel-slot/related-entity-grid-panel.component.d.ts +22 -0
- package/dist/lib/panel-slot/related-entity-grid-panel.component.d.ts.map +1 -0
- package/dist/lib/panel-slot/related-entity-grid-panel.component.js +78 -0
- package/dist/lib/panel-slot/related-entity-grid-panel.component.js.map +1 -0
- package/dist/lib/related-grid-height.d.ts +20 -0
- package/dist/lib/related-grid-height.d.ts.map +1 -0
- package/dist/lib/related-grid-height.js +30 -0
- package/dist/lib/related-grid-height.js.map +1 -0
- package/dist/lib/section-manager/section-manager.component.d.ts +20 -1
- package/dist/lib/section-manager/section-manager.component.d.ts.map +1 -1
- package/dist/lib/section-manager/section-manager.component.js +204 -25
- package/dist/lib/section-manager/section-manager.component.js.map +1 -1
- package/dist/lib/toolbar/form-toolbar.component.d.ts +55 -4
- package/dist/lib/toolbar/form-toolbar.component.d.ts.map +1 -1
- package/dist/lib/toolbar/form-toolbar.component.js +734 -306
- package/dist/lib/toolbar/form-toolbar.component.js.map +1 -1
- package/dist/lib/types/form-events.d.ts +35 -0
- package/dist/lib/types/form-events.d.ts.map +1 -1
- package/dist/lib/types/form-events.js +45 -0
- package/dist/lib/types/form-events.js.map +1 -1
- package/dist/lib/types/form-toolbar-item.d.ts +145 -0
- package/dist/lib/types/form-toolbar-item.d.ts.map +1 -0
- package/dist/lib/types/form-toolbar-item.js +2 -0
- package/dist/lib/types/form-toolbar-item.js.map +1 -0
- package/dist/lib/types/form-types.d.ts +8 -0
- package/dist/lib/types/form-types.d.ts.map +1 -1
- package/dist/lib/types/form-types.js.map +1 -1
- package/dist/lib/types/toolbar-config.d.ts +7 -2
- package/dist/lib/types/toolbar-config.d.ts.map +1 -1
- package/dist/lib/types/toolbar-config.js +6 -0
- package/dist/lib/types/toolbar-config.js.map +1 -1
- package/dist/module.d.ts +17 -14
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +14 -0
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +13 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +14 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +19 -18
|
@@ -5,6 +5,7 @@ import { IsFormSectionHidden } from '../types/entity-form-config';
|
|
|
5
5
|
import { MjFormFieldComponent } from '../field/form-field.component';
|
|
6
6
|
import { CompositeKey } from '@memberjunction/core';
|
|
7
7
|
import { EscapeHTML, HighlightSearchMatches } from '@memberjunction/global';
|
|
8
|
+
import { FormChromeCoordinator } from '../chrome/form-chrome-coordinator.service';
|
|
8
9
|
import * as i0 from "@angular/core";
|
|
9
10
|
const _c0 = ["panelContent"];
|
|
10
11
|
const _c1 = ["*"];
|
|
@@ -81,6 +82,7 @@ export class MjCollapsiblePanelComponent {
|
|
|
81
82
|
cdr = inject(ChangeDetectorRef);
|
|
82
83
|
elementRef = inject(ElementRef);
|
|
83
84
|
ngZone = inject(NgZone);
|
|
85
|
+
chrome = inject(FormChromeCoordinator, { optional: true });
|
|
84
86
|
/** Unique key for state persistence */
|
|
85
87
|
SectionKey = '';
|
|
86
88
|
/** Display name shown in the panel header */
|
|
@@ -152,6 +154,15 @@ export class MjCollapsiblePanelComponent {
|
|
|
152
154
|
DisplayName = '';
|
|
153
155
|
FieldNames = '';
|
|
154
156
|
IsVisible = true;
|
|
157
|
+
get HostSectionKey() {
|
|
158
|
+
return this.SectionKey;
|
|
159
|
+
}
|
|
160
|
+
get HostVariant() {
|
|
161
|
+
return this.Variant;
|
|
162
|
+
}
|
|
163
|
+
get HostIcon() {
|
|
164
|
+
return this.Icon;
|
|
165
|
+
}
|
|
155
166
|
get HostClass() {
|
|
156
167
|
const classes = [`mj-panel--${this.Variant}`];
|
|
157
168
|
if (!this.IsVisible)
|
|
@@ -160,6 +171,15 @@ export class MjCollapsiblePanelComponent {
|
|
|
160
171
|
classes.push('mj-dragging');
|
|
161
172
|
if (this.IsDragOver)
|
|
162
173
|
classes.push('mj-drag-over');
|
|
174
|
+
if (this.chrome?.Spec.RelatedRoles.get(this.SectionKey) === 'Detail') {
|
|
175
|
+
classes.push('mj-form-role-detail');
|
|
176
|
+
}
|
|
177
|
+
if (this.chrome?.HidesAccordionChrome(this.SectionKey)) {
|
|
178
|
+
classes.push('mj-chrome-plain');
|
|
179
|
+
}
|
|
180
|
+
if (!this.hasRenderableContent()) {
|
|
181
|
+
classes.push('mj-panel-empty');
|
|
182
|
+
}
|
|
163
183
|
return classes.join(' ');
|
|
164
184
|
}
|
|
165
185
|
get CssOrder() {
|
|
@@ -171,6 +191,7 @@ export class MjCollapsiblePanelComponent {
|
|
|
171
191
|
// ---- Event relay ----
|
|
172
192
|
/** Signals re-subscription when ContentChildren change */
|
|
173
193
|
fieldNavReset$ = new Subject();
|
|
194
|
+
destroy$ = new Subject();
|
|
174
195
|
// ---- Panel content resize ----
|
|
175
196
|
panelContentRef;
|
|
176
197
|
resizeObserver;
|
|
@@ -178,14 +199,28 @@ export class MjCollapsiblePanelComponent {
|
|
|
178
199
|
/** ResizeObserver fires once synchronously on observe(); that initial measurement is not a user resize. */
|
|
179
200
|
resizeObserverPrimed = false;
|
|
180
201
|
/**
|
|
181
|
-
* Persisted
|
|
182
|
-
*
|
|
202
|
+
* Persisted accordion resize height for related-entity panels.
|
|
203
|
+
* Related grids size themselves from row count (accordion and left-nav),
|
|
204
|
+
* so a pinned pixel height — especially 0 / toolbar-only measured while
|
|
205
|
+
* collapsed — would clip the grid. Only honor a user drag that is at
|
|
206
|
+
* least the CSS min-height.
|
|
183
207
|
*/
|
|
184
208
|
get PanelContentHeight() {
|
|
185
209
|
if (this.Variant !== 'related-entity')
|
|
186
210
|
return undefined;
|
|
211
|
+
if (this.hidesAccordionChrome())
|
|
212
|
+
return undefined;
|
|
187
213
|
const formRef = this.Form;
|
|
188
|
-
|
|
214
|
+
const persisted = formRef?.GetSectionPanelHeight?.(this.SectionKey);
|
|
215
|
+
if (persisted == null || persisted < 120)
|
|
216
|
+
return undefined;
|
|
217
|
+
return persisted;
|
|
218
|
+
}
|
|
219
|
+
hidesAccordionChrome() {
|
|
220
|
+
if (this.chrome?.HidesAccordionChrome(this.SectionKey))
|
|
221
|
+
return true;
|
|
222
|
+
const el = this.elementRef.nativeElement;
|
|
223
|
+
return !!el?.classList.contains('mj-chrome-show');
|
|
189
224
|
}
|
|
190
225
|
/** Whether drag-to-reorder is allowed (from FormContext) */
|
|
191
226
|
get ReorderAllowed() {
|
|
@@ -198,6 +233,9 @@ export class MjCollapsiblePanelComponent {
|
|
|
198
233
|
* that lock sections open). Undefined / true means collapsible.
|
|
199
234
|
*/
|
|
200
235
|
get Collapsible() {
|
|
236
|
+
// Selected left-nav item has no accordion chrome. More keeps collapse/expand.
|
|
237
|
+
if (this.hidesAccordionChrome())
|
|
238
|
+
return false;
|
|
201
239
|
return this.FormContext?.collapsibleSections !== false;
|
|
202
240
|
}
|
|
203
241
|
/** Whether the panel is expanded (delegates to form state; always true when not collapsible) */
|
|
@@ -210,6 +248,9 @@ export class MjCollapsiblePanelComponent {
|
|
|
210
248
|
// ---- Lifecycle ----
|
|
211
249
|
ngOnInit() {
|
|
212
250
|
this.DisplayName = this.SectionName;
|
|
251
|
+
this.chrome?.Changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
252
|
+
this.UpdateVisibilityAndHighlighting();
|
|
253
|
+
});
|
|
213
254
|
}
|
|
214
255
|
ngAfterContentInit() {
|
|
215
256
|
this.UpdateFieldNames();
|
|
@@ -238,6 +279,8 @@ export class MjCollapsiblePanelComponent {
|
|
|
238
279
|
ngOnDestroy() {
|
|
239
280
|
this.fieldNavReset$.next();
|
|
240
281
|
this.fieldNavReset$.complete();
|
|
282
|
+
this.destroy$.next();
|
|
283
|
+
this.destroy$.complete();
|
|
241
284
|
this.resizeObserver?.disconnect();
|
|
242
285
|
if (this.resizeDebounceTimer) {
|
|
243
286
|
clearTimeout(this.resizeDebounceTimer);
|
|
@@ -333,6 +376,41 @@ export class MjCollapsiblePanelComponent {
|
|
|
333
376
|
formRef.setSectionOrder(newOrder);
|
|
334
377
|
this.cdr.markForCheck();
|
|
335
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Field panels whose only children are empty/hidden (e.g. leftover
|
|
381
|
+
* `Details` with just unused geo columns) should not take space.
|
|
382
|
+
* Custom widgets and related grids have no FieldComponents — keep them.
|
|
383
|
+
*/
|
|
384
|
+
/**
|
|
385
|
+
* Whether this panel matches a section-search term by title or field
|
|
386
|
+
* name. Ignores chrome hide/show — the rail uses this to decide if the
|
|
387
|
+
* *group* matches, even when another section is currently selected.
|
|
388
|
+
*/
|
|
389
|
+
MatchesSearch(term) {
|
|
390
|
+
const filter = (term || '').toLowerCase().trim();
|
|
391
|
+
if (!filter)
|
|
392
|
+
return true;
|
|
393
|
+
if (this.SectionName.toLowerCase().includes(filter))
|
|
394
|
+
return true;
|
|
395
|
+
if (this.SectionKey.toLowerCase().includes(filter))
|
|
396
|
+
return true;
|
|
397
|
+
return this.FieldNames.includes(filter);
|
|
398
|
+
}
|
|
399
|
+
hasRenderableContent() {
|
|
400
|
+
if (this.Variant === 'related-entity')
|
|
401
|
+
return true;
|
|
402
|
+
if (!this.FieldComponents || this.FieldComponents.length === 0)
|
|
403
|
+
return true;
|
|
404
|
+
return this.FieldComponents.some((field) => !field.ShouldHideField);
|
|
405
|
+
}
|
|
406
|
+
isHiddenByChrome() {
|
|
407
|
+
if (!this.chrome)
|
|
408
|
+
return false;
|
|
409
|
+
if (this.Variant === 'related-entity') {
|
|
410
|
+
return !this.chrome.IsRelatedSectionVisible(this.SectionKey);
|
|
411
|
+
}
|
|
412
|
+
return !this.chrome.IsFirstClassSectionVisible(this.SectionKey);
|
|
413
|
+
}
|
|
336
414
|
UpdateFieldNames() {
|
|
337
415
|
if (this.FieldComponents) {
|
|
338
416
|
const names = [];
|
|
@@ -379,10 +457,16 @@ export class MjCollapsiblePanelComponent {
|
|
|
379
457
|
// the resize handle. Ignore reflows while collapsed (e.g. content settling on load).
|
|
380
458
|
if (!this.Expanded)
|
|
381
459
|
return;
|
|
460
|
+
// Left-nav sizes the grid from the leftover column. Persisting that
|
|
461
|
+
// computed height would write ~0 (or the toolbar) and then pin it.
|
|
462
|
+
if (this.hidesAccordionChrome())
|
|
463
|
+
return;
|
|
382
464
|
const entry = entries[0];
|
|
383
465
|
if (!entry)
|
|
384
466
|
return;
|
|
385
467
|
const newHeight = Math.round(entry.contentRect.height);
|
|
468
|
+
if (newHeight < 120)
|
|
469
|
+
return;
|
|
386
470
|
this.DebouncePersistHeight(newHeight);
|
|
387
471
|
});
|
|
388
472
|
this.resizeObserver.observe(el);
|
|
@@ -405,7 +489,7 @@ export class MjCollapsiblePanelComponent {
|
|
|
405
489
|
// `Hidden` input OR the form config's section-visibility rules carried on
|
|
406
490
|
// FormContext (which also reach slot-injected BaseFormPanels, since every
|
|
407
491
|
// panel receives FormContext).
|
|
408
|
-
if (this._hidden || IsFormSectionHidden(this.FormContext, this.SectionKey, this.Variant)) {
|
|
492
|
+
if (this._hidden || IsFormSectionHidden(this.FormContext, this.SectionKey, this.Variant) || this.isHiddenByChrome()) {
|
|
409
493
|
this.IsVisible = false;
|
|
410
494
|
this.DisplayName = EscapeHTML(this.SectionName);
|
|
411
495
|
this.cdr.markForCheck();
|
|
@@ -413,14 +497,14 @@ export class MjCollapsiblePanelComponent {
|
|
|
413
497
|
}
|
|
414
498
|
const searchTerm = (this.FormContext?.sectionFilter || '').toLowerCase().trim();
|
|
415
499
|
if (!searchTerm) {
|
|
416
|
-
this.IsVisible =
|
|
500
|
+
this.IsVisible = this.hasRenderableContent();
|
|
417
501
|
this.DisplayName = this.SectionName;
|
|
418
502
|
this.cdr.markForCheck();
|
|
419
503
|
return;
|
|
420
504
|
}
|
|
421
505
|
const sectionMatches = this.SectionName.toLowerCase().includes(searchTerm);
|
|
422
506
|
const fieldsMatch = this.FieldNames.includes(searchTerm);
|
|
423
|
-
this.IsVisible =
|
|
507
|
+
this.IsVisible = this.MatchesSearch(searchTerm);
|
|
424
508
|
// DisplayName is bound to `[innerHTML]` in the template — must always be HTML-safe.
|
|
425
509
|
this.DisplayName =
|
|
426
510
|
this.IsVisible && sectionMatches
|
|
@@ -439,9 +523,10 @@ export class MjCollapsiblePanelComponent {
|
|
|
439
523
|
} if (rf & 2) {
|
|
440
524
|
let _t;
|
|
441
525
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.panelContentRef = _t.first);
|
|
442
|
-
} }, hostVars:
|
|
526
|
+
} }, hostVars: 7, hostBindings: function MjCollapsiblePanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
443
527
|
i0.ɵɵlistener("dragover", function MjCollapsiblePanelComponent_dragover_HostBindingHandler($event) { return ctx.OnDragOver($event); })("dragleave", function MjCollapsiblePanelComponent_dragleave_HostBindingHandler($event) { return ctx.OnDragLeave($event); })("drop", function MjCollapsiblePanelComponent_drop_HostBindingHandler($event) { return ctx.OnDrop($event); });
|
|
444
528
|
} if (rf & 2) {
|
|
529
|
+
i0.ɵɵattribute("data-section-key", ctx.HostSectionKey)("data-variant", ctx.HostVariant)("data-icon", ctx.HostIcon);
|
|
445
530
|
i0.ɵɵclassMap(ctx.HostClass);
|
|
446
531
|
i0.ɵɵstyleProp("order", ctx.CssOrder);
|
|
447
532
|
} }, inputs: { SectionKey: "SectionKey", SectionName: "SectionName", Icon: "Icon", Form: "Form", FormContext: "FormContext", Variant: "Variant", BadgeCount: "BadgeCount", DefaultExpanded: "DefaultExpanded", InheritedFromEntity: "InheritedFromEntity", InheritedRecordPrimaryKey: "InheritedRecordPrimaryKey", Hidden: "Hidden", _deprecatedSectionKey: [0, "sectionKey", "_deprecatedSectionKey"], _deprecatedSectionName: [0, "sectionName", "_deprecatedSectionName"], _deprecatedIcon: [0, "icon", "_deprecatedIcon"], _deprecatedForm: [0, "form", "_deprecatedForm"], _deprecatedFormContext: [0, "formContext", "_deprecatedFormContext"] }, outputs: { DragStarted: "DragStarted", DragEnded: "DragEnded", PanelDrop: "PanelDrop", Navigate: "Navigate" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c1, decls: 14, vars: 20, consts: [["panelContent", ""], [1, "mj-forms-panel"], [1, "mj-forms-panel-header", 3, "click"], ["title", "Drag to reorder sections", "draggable", "true", 1, "mj-forms-drag-handle"], [1, "mj-forms-panel-title-group"], [1, "mj-forms-panel-icon"], [1, "mj-forms-panel-title"], [3, "innerHTML"], [1, "mj-forms-row-count-badge", 3, "mj-forms-row-count-badge--zero"], [1, "mj-forms-inherited-badge", 3, "title"], [1, "mj-forms-panel-chevron"], [1, "mj-forms-panel-body"], [1, "mj-forms-panel-content"], ["title", "Drag to reorder sections", "draggable", "true", 1, "mj-forms-drag-handle", 3, "dragstart", "dragend", "click"], [1, "fa-solid", "fa-grip-vertical"], [1, "mj-forms-row-count-badge"], [1, "mj-forms-inherited-badge", 3, "click", "title"], [1, "fa-solid", "fa-arrow-up"]], template: function MjCollapsiblePanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -484,11 +569,11 @@ export class MjCollapsiblePanelComponent {
|
|
|
484
569
|
i0.ɵɵclassProp("mj-forms-panel-body--collapsed", !ctx.Expanded);
|
|
485
570
|
i0.ɵɵadvance();
|
|
486
571
|
i0.ɵɵstyleProp("height", ctx.PanelContentHeight, "px");
|
|
487
|
-
} }, styles: ["mj-collapsible-panel {\n display: block;\n}\n\nmj-collapsible-panel.mj-search-hidden {\n display: none;\n}\n\nmj-collapsible-panel.mj-drag-over {\n border: 2px dashed var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n}\n\n/* ============================================\n PANEL CARD\n ============================================ */\n.mj-forms-panel {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n/* ============================================\n HEADER\n ============================================ */\n.mj-forms-panel-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-elevated);\n border-bottom: 2px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.mj-forms-panel-header:hover {\n background: var(--mj-bg-surface-hover);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Static header \u2014 sections locked open (Config.collapsibleSections === false) */\n.mj-forms-panel-header--static {\n cursor: default;\n}\n\n.mj-forms-panel-header--static:hover {\n background: var(--mj-bg-surface-elevated);\n border-bottom-color: var(--mj-border-default);\n}\n\n/* Drag handle */\n.mj-forms-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0;\n height: 24px;\n color: var(--mj-text-muted);\n cursor: grab;\n opacity: 0;\n overflow: hidden;\n transition: width var(--mj-transition-base) ease, opacity var(--mj-transition-base) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-panel-header:hover .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n}\n\n.mj-forms-drag-handle:hover {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-drag-handle:active {\n cursor: grabbing;\n}\n\nmj-collapsible-panel.mj-dragging .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Title group */\n.mj-forms-panel-title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.mj-forms-panel-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n width: 24px;\n text-align: center;\n}\n\n.mj-forms-panel-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mj-forms-panel-chevron {\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: transform 0.3s ease;\n padding: 4px;\n}\n\n/* Row count badge */\n.mj-forms-row-count-badge {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n line-height: 1;\n}\n\n.mj-forms-row-count-badge--zero {\n background: var(--mj-text-muted);\n}\n\n/* ============================================\n INHERITED VARIANT (IS-A parent fields)\n ============================================ */\n.mj-forms-panel--inherited {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-inherited-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n cursor: pointer;\n transition: all var(--mj-transition-base) ease;\n text-decoration: none;\n}\n\n.mj-forms-inherited-badge:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.mj-forms-inherited-badge i {\n font-size: 10px;\n}\n\n/* ============================================\n RELATED ENTITY VARIANT\n ============================================ */\n.mj-forms-panel--related {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--related .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Related entity content
|
|
572
|
+
} }, styles: ["mj-collapsible-panel {\n display: block;\n}\n\nmj-collapsible-panel.mj-search-hidden {\n display: none;\n}\n\nmj-collapsible-panel.mj-drag-over {\n border: 2px dashed var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n}\n\n/* ============================================\n PANEL CARD\n ============================================ */\n.mj-forms-panel {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n/* ============================================\n HEADER\n ============================================ */\n.mj-forms-panel-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-elevated);\n border-bottom: 2px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.mj-forms-panel-header:hover {\n background: var(--mj-bg-surface-hover);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Static header \u2014 sections locked open (Config.collapsibleSections === false) */\n.mj-forms-panel-header--static {\n cursor: default;\n}\n\n.mj-forms-panel-header--static:hover {\n background: var(--mj-bg-surface-elevated);\n border-bottom-color: var(--mj-border-default);\n}\n\n/* Drag handle */\n.mj-forms-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0;\n height: 24px;\n color: var(--mj-text-muted);\n cursor: grab;\n opacity: 0;\n overflow: hidden;\n transition: width var(--mj-transition-base) ease, opacity var(--mj-transition-base) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-panel-header:hover .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n}\n\n.mj-forms-drag-handle:hover {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-drag-handle:active {\n cursor: grabbing;\n}\n\nmj-collapsible-panel.mj-dragging .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Title group */\n.mj-forms-panel-title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.mj-forms-panel-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n width: 24px;\n text-align: center;\n}\n\n.mj-forms-panel-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mj-forms-panel-chevron {\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: transform 0.3s ease;\n padding: 4px;\n}\n\n/* Row count badge */\n.mj-forms-row-count-badge {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n line-height: 1;\n}\n\n.mj-forms-row-count-badge--zero {\n background: var(--mj-text-muted);\n}\n\n/* ============================================\n INHERITED VARIANT (IS-A parent fields)\n ============================================ */\n.mj-forms-panel--inherited {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-inherited-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n cursor: pointer;\n transition: all var(--mj-transition-base) ease;\n text-decoration: none;\n}\n\n.mj-forms-inherited-badge:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.mj-forms-inherited-badge i {\n font-size: 10px;\n}\n\n/* ============================================\n RELATED ENTITY VARIANT\n ============================================ */\n.mj-forms-panel--related {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--related .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Related entity content hugs the grid (toolbar + header + rows).\n A fixed 400px box left a hollow slab when AG Grid's viewport was 0,\n and a persisted 0/toolbar height clipped the rows after expand. */\n.mj-forms-panel--related .mj-forms-panel-content {\n height: auto;\n padding: 0;\n overflow: hidden;\n resize: vertical;\n min-height: 0;\n max-height: 800px;\n}\n\n/* AG Grid must fill the 400px / leftover box. Do not stretch every\n descendant \u2014 custom widgets (relationship list) put their section\n header as the first child, and height:100% on it parks the title\n mid-column and hides the list below the fold. */\n.mj-forms-panel--related .mj-forms-panel-content > mj-explorer-entity-data-grid,\n.mj-forms-panel--related .mj-forms-panel-content > .ng-star-inserted > mj-explorer-entity-data-grid {\n height: 100%;\n}\n\n/* Related entity panels need the body to not clip the resize handle */\n.mj-forms-panel--related .mj-forms-panel-body {\n overflow: visible;\n}\n\n/* ============================================\n BODY (collapsible)\n ============================================ */\n.mj-forms-panel-body {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.mj-forms-panel-body--collapsed {\n max-height: 0 !important;\n padding: 0 !important;\n opacity: 0 !important;\n overflow: hidden !important;\n pointer-events: none;\n}\n\n.mj-forms-panel-body--collapsed .mj-forms-panel-content {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n max-height: 0 !important;\n overflow: hidden !important;\n}\n\n.mj-forms-panel-content {\n padding: 20px;\n overflow: auto;\n max-height: 600px;\n}\n\n/* ============================================\n SEARCH HIGHLIGHTING\n ============================================ */\n.mj-forms-panel-title ::ng-deep .mj-forms-search-highlight {\n /* Muted, theme-aware highlight (semantic token) \u2014 consistent with the field\n label + FK dropdown highlights. Replaces the old bright-yellow primitive. */\n background-color: var(--mj-search-highlight-bg);\n color: var(--mj-search-highlight-text);\n border-radius: 2px;\n padding: 0 1px;\n font-weight: 600;\n}\n"], encapsulation: 2, changeDetection: 0 });
|
|
488
573
|
}
|
|
489
574
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjCollapsiblePanelComponent, [{
|
|
490
575
|
type: Component,
|
|
491
|
-
args: [{ standalone: false, selector: 'mj-collapsible-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"mj-forms-panel\"\n [class.mj-forms-panel--related]=\"Variant === 'related-entity'\"\n [class.mj-forms-panel--inherited]=\"Variant === 'inherited'\"\n [attr.data-section-key]=\"SectionKey\">\n\n <!-- Panel Header -->\n <div class=\"mj-forms-panel-header\"\n [class.mj-forms-panel-header--static]=\"!Collapsible\"\n [attr.role]=\"Collapsible ? 'button' : null\"\n [attr.tabindex]=\"Collapsible ? 0 : null\"\n (click)=\"Toggle()\">\n <!-- Drag Handle (hidden when reorder disabled) -->\n @if (ReorderAllowed) {\n <div class=\"mj-forms-drag-handle\"\n title=\"Drag to reorder sections\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n }\n\n <!-- Icon + Title -->\n <div class=\"mj-forms-panel-title-group\">\n <i [class]=\"Icon\" class=\"mj-forms-panel-icon\"></i>\n <h3 class=\"mj-forms-panel-title\">\n <span [innerHTML]=\"DisplayName\"></span>\n <!-- Row count badge for related entities -->\n @if (BadgeCount !== undefined) {\n <span class=\"mj-forms-row-count-badge\" [class.mj-forms-row-count-badge--zero]=\"BadgeCount === 0\">\n {{ BadgeCount }}\n </span>\n }\n </h3>\n </div>\n\n <!-- Inherited From badge (IS-A) -->\n @if (Variant === 'inherited' && InheritedFromEntity) {\n <a class=\"mj-forms-inherited-badge\" (click)=\"OnInheritedBadgeClick($event)\"\n [title]=\"'View parent record: ' + InheritedFromEntity\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n Inherited from {{ InheritedFromEntity }}\n </a>\n }\n\n <!-- Chevron (hidden when sections are locked open) -->\n @if (Collapsible) {\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\n }\n </div>\n\n <!-- Panel Body -->\n <div class=\"mj-forms-panel-body\" [class.mj-forms-panel-body--collapsed]=\"!Expanded\">\n <div class=\"mj-forms-panel-content\"\n #panelContent\n [style.height.px]=\"PanelContentHeight\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: ["mj-collapsible-panel {\n display: block;\n}\n\nmj-collapsible-panel.mj-search-hidden {\n display: none;\n}\n\nmj-collapsible-panel.mj-drag-over {\n border: 2px dashed var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n}\n\n/* ============================================\n PANEL CARD\n ============================================ */\n.mj-forms-panel {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n/* ============================================\n HEADER\n ============================================ */\n.mj-forms-panel-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-elevated);\n border-bottom: 2px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.mj-forms-panel-header:hover {\n background: var(--mj-bg-surface-hover);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Static header \u2014 sections locked open (Config.collapsibleSections === false) */\n.mj-forms-panel-header--static {\n cursor: default;\n}\n\n.mj-forms-panel-header--static:hover {\n background: var(--mj-bg-surface-elevated);\n border-bottom-color: var(--mj-border-default);\n}\n\n/* Drag handle */\n.mj-forms-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0;\n height: 24px;\n color: var(--mj-text-muted);\n cursor: grab;\n opacity: 0;\n overflow: hidden;\n transition: width var(--mj-transition-base) ease, opacity var(--mj-transition-base) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-panel-header:hover .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n}\n\n.mj-forms-drag-handle:hover {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-drag-handle:active {\n cursor: grabbing;\n}\n\nmj-collapsible-panel.mj-dragging .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Title group */\n.mj-forms-panel-title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.mj-forms-panel-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n width: 24px;\n text-align: center;\n}\n\n.mj-forms-panel-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mj-forms-panel-chevron {\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: transform 0.3s ease;\n padding: 4px;\n}\n\n/* Row count badge */\n.mj-forms-row-count-badge {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n line-height: 1;\n}\n\n.mj-forms-row-count-badge--zero {\n background: var(--mj-text-muted);\n}\n\n/* ============================================\n INHERITED VARIANT (IS-A parent fields)\n ============================================ */\n.mj-forms-panel--inherited {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-inherited-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n cursor: pointer;\n transition: all var(--mj-transition-base) ease;\n text-decoration: none;\n}\n\n.mj-forms-inherited-badge:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.mj-forms-inherited-badge i {\n font-size: 10px;\n}\n\n/* ============================================\n RELATED ENTITY VARIANT\n ============================================ */\n.mj-forms-panel--related {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--related .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Related entity content
|
|
576
|
+
args: [{ standalone: false, selector: 'mj-collapsible-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"mj-forms-panel\"\n [class.mj-forms-panel--related]=\"Variant === 'related-entity'\"\n [class.mj-forms-panel--inherited]=\"Variant === 'inherited'\"\n [attr.data-section-key]=\"SectionKey\">\n\n <!-- Panel Header -->\n <div class=\"mj-forms-panel-header\"\n [class.mj-forms-panel-header--static]=\"!Collapsible\"\n [attr.role]=\"Collapsible ? 'button' : null\"\n [attr.tabindex]=\"Collapsible ? 0 : null\"\n (click)=\"Toggle()\">\n <!-- Drag Handle (hidden when reorder disabled) -->\n @if (ReorderAllowed) {\n <div class=\"mj-forms-drag-handle\"\n title=\"Drag to reorder sections\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n }\n\n <!-- Icon + Title -->\n <div class=\"mj-forms-panel-title-group\">\n <i [class]=\"Icon\" class=\"mj-forms-panel-icon\"></i>\n <h3 class=\"mj-forms-panel-title\">\n <span [innerHTML]=\"DisplayName\"></span>\n <!-- Row count badge for related entities -->\n @if (BadgeCount !== undefined) {\n <span class=\"mj-forms-row-count-badge\" [class.mj-forms-row-count-badge--zero]=\"BadgeCount === 0\">\n {{ BadgeCount }}\n </span>\n }\n </h3>\n </div>\n\n <!-- Inherited From badge (IS-A) -->\n @if (Variant === 'inherited' && InheritedFromEntity) {\n <a class=\"mj-forms-inherited-badge\" (click)=\"OnInheritedBadgeClick($event)\"\n [title]=\"'View parent record: ' + InheritedFromEntity\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n Inherited from {{ InheritedFromEntity }}\n </a>\n }\n\n <!-- Chevron (hidden when sections are locked open) -->\n @if (Collapsible) {\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\n }\n </div>\n\n <!-- Panel Body -->\n <div class=\"mj-forms-panel-body\" [class.mj-forms-panel-body--collapsed]=\"!Expanded\">\n <div class=\"mj-forms-panel-content\"\n #panelContent\n [style.height.px]=\"PanelContentHeight\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n", styles: ["mj-collapsible-panel {\n display: block;\n}\n\nmj-collapsible-panel.mj-search-hidden {\n display: none;\n}\n\nmj-collapsible-panel.mj-drag-over {\n border: 2px dashed var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n}\n\n/* ============================================\n PANEL CARD\n ============================================ */\n.mj-forms-panel {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n transition: all 0.3s ease;\n}\n\n/* ============================================\n HEADER\n ============================================ */\n.mj-forms-panel-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n background: var(--mj-bg-surface-elevated);\n border-bottom: 2px solid var(--mj-border-default);\n cursor: pointer;\n user-select: none;\n transition: all 0.3s ease;\n}\n\n.mj-forms-panel-header:hover {\n background: var(--mj-bg-surface-hover);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n/* Static header \u2014 sections locked open (Config.collapsibleSections === false) */\n.mj-forms-panel-header--static {\n cursor: default;\n}\n\n.mj-forms-panel-header--static:hover {\n background: var(--mj-bg-surface-elevated);\n border-bottom-color: var(--mj-border-default);\n}\n\n/* Drag handle */\n.mj-forms-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 0;\n height: 24px;\n color: var(--mj-text-muted);\n cursor: grab;\n opacity: 0;\n overflow: hidden;\n transition: width var(--mj-transition-base) ease, opacity var(--mj-transition-base) ease;\n flex-shrink: 0;\n}\n\n.mj-forms-panel-header:hover .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n}\n\n.mj-forms-drag-handle:hover {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-drag-handle:active {\n cursor: grabbing;\n}\n\nmj-collapsible-panel.mj-dragging .mj-forms-drag-handle {\n width: 24px;\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n/* Title group */\n.mj-forms-panel-title-group {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n}\n\n.mj-forms-panel-icon {\n font-size: 18px;\n color: var(--mj-brand-primary);\n width: 24px;\n text-align: center;\n}\n\n.mj-forms-panel-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mj-forms-panel-chevron {\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: transform 0.3s ease;\n padding: 4px;\n}\n\n/* Row count badge */\n.mj-forms-row-count-badge {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n padding: 2px 8px;\n border-radius: var(--mj-radius-full);\n font-size: 12px;\n font-weight: 600;\n margin-left: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n line-height: 1;\n}\n\n.mj-forms-row-count-badge--zero {\n background: var(--mj-text-muted);\n}\n\n/* ============================================\n INHERITED VARIANT (IS-A parent fields)\n ============================================ */\n.mj-forms-panel--inherited {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--inherited .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-forms-inherited-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n cursor: pointer;\n transition: all var(--mj-transition-base) ease;\n text-decoration: none;\n}\n\n.mj-forms-inherited-badge:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.mj-forms-inherited-badge i {\n font-size: 10px;\n}\n\n/* ============================================\n RELATED ENTITY VARIANT\n ============================================ */\n.mj-forms-panel--related {\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-header {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface-elevated));\n}\n\n.mj-forms-panel--related .mj-forms-panel-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface-elevated));\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.mj-forms-panel--related .mj-forms-panel-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Related entity content hugs the grid (toolbar + header + rows).\n A fixed 400px box left a hollow slab when AG Grid's viewport was 0,\n and a persisted 0/toolbar height clipped the rows after expand. */\n.mj-forms-panel--related .mj-forms-panel-content {\n height: auto;\n padding: 0;\n overflow: hidden;\n resize: vertical;\n min-height: 0;\n max-height: 800px;\n}\n\n/* AG Grid must fill the 400px / leftover box. Do not stretch every\n descendant \u2014 custom widgets (relationship list) put their section\n header as the first child, and height:100% on it parks the title\n mid-column and hides the list below the fold. */\n.mj-forms-panel--related .mj-forms-panel-content > mj-explorer-entity-data-grid,\n.mj-forms-panel--related .mj-forms-panel-content > .ng-star-inserted > mj-explorer-entity-data-grid {\n height: 100%;\n}\n\n/* Related entity panels need the body to not clip the resize handle */\n.mj-forms-panel--related .mj-forms-panel-body {\n overflow: visible;\n}\n\n/* ============================================\n BODY (collapsible)\n ============================================ */\n.mj-forms-panel-body {\n max-height: 2000px;\n overflow: hidden;\n transition: max-height 0.4s ease, padding 0.4s ease, opacity 0.3s ease;\n opacity: 1;\n}\n\n.mj-forms-panel-body--collapsed {\n max-height: 0 !important;\n padding: 0 !important;\n opacity: 0 !important;\n overflow: hidden !important;\n pointer-events: none;\n}\n\n.mj-forms-panel-body--collapsed .mj-forms-panel-content {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n max-height: 0 !important;\n overflow: hidden !important;\n}\n\n.mj-forms-panel-content {\n padding: 20px;\n overflow: auto;\n max-height: 600px;\n}\n\n/* ============================================\n SEARCH HIGHLIGHTING\n ============================================ */\n.mj-forms-panel-title ::ng-deep .mj-forms-search-highlight {\n /* Muted, theme-aware highlight (semantic token) \u2014 consistent with the field\n label + FK dropdown highlights. Replaces the old bright-yellow primitive. */\n background-color: var(--mj-search-highlight-bg);\n color: var(--mj-search-highlight-text);\n border-radius: 2px;\n padding: 0 1px;\n font-weight: 600;\n}\n"] }]
|
|
492
577
|
}], null, { SectionKey: [{
|
|
493
578
|
type: Input
|
|
494
579
|
}], SectionName: [{
|
|
@@ -537,6 +622,15 @@ export class MjCollapsiblePanelComponent {
|
|
|
537
622
|
}], FieldComponents: [{
|
|
538
623
|
type: ContentChildren,
|
|
539
624
|
args: [MjFormFieldComponent, { descendants: true }]
|
|
625
|
+
}], HostSectionKey: [{
|
|
626
|
+
type: HostBinding,
|
|
627
|
+
args: ['attr.data-section-key']
|
|
628
|
+
}], HostVariant: [{
|
|
629
|
+
type: HostBinding,
|
|
630
|
+
args: ['attr.data-variant']
|
|
631
|
+
}], HostIcon: [{
|
|
632
|
+
type: HostBinding,
|
|
633
|
+
args: ['attr.data-icon']
|
|
540
634
|
}], HostClass: [{
|
|
541
635
|
type: HostBinding,
|
|
542
636
|
args: ['class']
|
|
@@ -556,5 +650,5 @@ export class MjCollapsiblePanelComponent {
|
|
|
556
650
|
type: HostListener,
|
|
557
651
|
args: ['drop', ['$event']]
|
|
558
652
|
}] }); })();
|
|
559
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjCollapsiblePanelComponent, { className: "MjCollapsiblePanelComponent", filePath: "src/lib/panel/collapsible-panel.component.ts", lineNumber:
|
|
653
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjCollapsiblePanelComponent, { className: "MjCollapsiblePanelComponent", filePath: "src/lib/panel/collapsible-panel.component.ts", lineNumber: 56 }); })();
|
|
560
654
|
//# sourceMappingURL=collapsible-panel.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapsible-panel.component.js","sourceRoot":"","sources":["../../../src/lib/panel/collapsible-panel.component.ts","../../../src/lib/panel/collapsible-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component, Input, Output, EventEmitter,\n ChangeDetectionStrategy, ChangeDetectorRef, inject,\n OnChanges, SimpleChanges, OnInit, AfterContentInit, AfterViewInit, OnDestroy,\n ContentChildren, QueryList, HostBinding, HostListener, ElementRef,\n ViewChild, NgZone, ViewEncapsulation\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { FormContext, PanelVariant, PanelDragStartEvent, PanelDropEvent } from '../types/form-types';\nimport { IsFormSectionHidden } from '../types/entity-form-config';\nimport { FormNavigationEvent } from '../types/navigation-events';\nimport { MjFormFieldComponent } from '../field/form-field.component';\nimport { CompositeKey } from '@memberjunction/core';\nimport { EscapeHTML, HighlightSearchMatches } from '@memberjunction/global';\n\n/**\n * Reusable collapsible panel for form sections.\n *\n * Supports three visual variants:\n * - **default**: White card with accent border (standard field sections)\n * - **related-entity**: Blue-accented card with row count badge (related entity grids)\n * - **inherited**: Purple-accented card with \"Inherited from X\" badge (IS-A parent field sections)\n *\n * Features:\n * - Expand/collapse with smooth animation\n * - Search filtering (hides non-matching panels, highlights matched names)\n * - Drag-to-reorder sections\n * - Inheritable \"Inherited from X\" badge with navigation event\n * - Row count badge for related entity sections\n *\n * @example\n * ```html\n * <mj-collapsible-panel\n * SectionKey=\"productDetails\"\n * SectionName=\"Product Details\"\n * Icon=\"fa fa-box\"\n * Variant=\"inherited\"\n * InheritedFromEntity=\"Products\"\n * [Form]=\"formComponent\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\">\n * <mj-form-field ...></mj-form-field>\n * </mj-collapsible-panel>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-collapsible-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None, // Required to style projected content (grids, etc.)\n templateUrl: './collapsible-panel.component.html',\n styleUrls: ['./collapsible-panel.component.css']\n})\nexport class MjCollapsiblePanelComponent implements OnInit, OnChanges, AfterContentInit, AfterViewInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private elementRef = inject(ElementRef);\n private ngZone = inject(NgZone);\n\n /** Unique key for state persistence */\n @Input() SectionKey = '';\n\n /** Display name shown in the panel header */\n @Input() SectionName = '';\n\n /** Font Awesome icon class for the panel header */\n @Input() Icon = 'fa fa-folder';\n\n /**\n * Reference to the parent form component for state delegation.\n * Expected to have IsSectionExpanded, SetSectionExpanded, getSectionDisplayOrder methods.\n */\n @Input() Form: unknown;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n /** Panel visual variant */\n @Input() Variant: PanelVariant = 'default';\n\n /** Row count badge for related entity sections */\n @Input() BadgeCount: number | undefined;\n\n /** Default expanded state when no persisted state exists */\n @Input() DefaultExpanded: boolean | undefined;\n\n /**\n * For 'inherited' variant: the parent entity name this section's fields come from.\n * Displayed as \"Inherited from X\" badge and used for navigation.\n */\n @Input() InheritedFromEntity = '';\n\n /**\n * For 'inherited' variant: the primary key to navigate to when clicking the badge.\n * (Shared PK in IS-A relationships.)\n */\n @Input() InheritedRecordPrimaryKey?: CompositeKey;\n\n /**\n * Container-driven hard hide. When true the panel is removed from view\n * regardless of search state — used by the record-form container to honor\n * `EntityFormConfig.showRelatedEntities` / `hiddenSectionKeys` /\n * `visibleSectionKeys`. Composes with (overrides) search visibility so all\n * existing `IsVisible`-based section counts stay correct.\n */\n @Input()\n set Hidden(value: boolean) {\n if (value !== this._hidden) {\n this._hidden = value;\n // Recompute visibility if content has initialized (FieldComponents present).\n if (this.FieldComponents) {\n this.UpdateVisibilityAndHighlighting();\n }\n }\n }\n get Hidden(): boolean {\n return this._hidden;\n }\n private _hidden = false;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [SectionKey] instead */\n @Input('sectionKey') set _deprecatedSectionKey(value: string) { this.SectionKey = value; }\n\n /** @deprecated Use [SectionName] instead */\n @Input('sectionName') set _deprecatedSectionName(value: string) { this.SectionName = value; }\n\n /** @deprecated Use [Icon] instead */\n @Input('icon') set _deprecatedIcon(value: string) { this.Icon = value; }\n\n /** @deprecated Use [Form] instead */\n @Input('form') set _deprecatedForm(value: unknown) { this.Form = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n // ---- Outputs ----\n\n @Output() DragStarted = new EventEmitter<PanelDragStartEvent>();\n @Output() DragEnded = new EventEmitter<void>();\n @Output() PanelDrop = new EventEmitter<PanelDropEvent>();\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Content Children ----\n\n @ContentChildren(MjFormFieldComponent, { descendants: true }) FieldComponents!: QueryList<MjFormFieldComponent>;\n\n // ---- State ----\n\n DisplayName = '';\n FieldNames = '';\n IsVisible = true;\n\n @HostBinding('class')\n get HostClass(): string {\n const classes = [`mj-panel--${this.Variant}`];\n if (!this.IsVisible) classes.push('mj-search-hidden');\n if (this.IsDragging) classes.push('mj-dragging');\n if (this.IsDragOver) classes.push('mj-drag-over');\n return classes.join(' ');\n }\n\n @HostBinding('style.order')\n get CssOrder(): number {\n const formRef = this.Form as { getSectionDisplayOrder?: (key: string) => number };\n return formRef?.getSectionDisplayOrder ? formRef.getSectionDisplayOrder(this.SectionKey) : 0;\n }\n\n IsDragging = false;\n IsDragOver = false;\n\n // ---- Event relay ----\n\n /** Signals re-subscription when ContentChildren change */\n private fieldNavReset$ = new Subject<void>();\n\n // ---- Panel content resize ----\n\n @ViewChild('panelContent') private panelContentRef?: ElementRef<HTMLElement>;\n private resizeObserver?: ResizeObserver;\n private resizeDebounceTimer?: ReturnType<typeof setTimeout>;\n /** ResizeObserver fires once synchronously on observe(); that initial measurement is not a user resize. */\n private resizeObserverPrimed = false;\n\n /**\n * Persisted panel height for related-entity panels.\n * Returns undefined to let CSS default (400px) apply.\n */\n get PanelContentHeight(): number | undefined {\n if (this.Variant !== 'related-entity') return undefined;\n const formRef = this.Form as { GetSectionPanelHeight?: (key: string) => number | undefined };\n return formRef?.GetSectionPanelHeight?.(this.SectionKey);\n }\n\n /** Whether drag-to-reorder is allowed (from FormContext) */\n get ReorderAllowed(): boolean {\n return this.FormContext?.allowSectionReorder !== false;\n }\n\n /**\n * Whether this panel's header may collapse/expand. Driven by\n * `FormContext.collapsibleSections`; when false the panel renders\n * always-expanded with no toggle chevron (used by dialog/slide-in surfaces\n * that lock sections open). Undefined / true means collapsible.\n */\n get Collapsible(): boolean {\n return this.FormContext?.collapsibleSections !== false;\n }\n\n /** Whether the panel is expanded (delegates to form state; always true when not collapsible) */\n get Expanded(): boolean {\n if (!this.Collapsible) return true;\n const formRef = this.Form as { IsSectionExpanded?: (key: string, defaultExpanded?: boolean) => boolean };\n return formRef?.IsSectionExpanded ? formRef.IsSectionExpanded(this.SectionKey, this.DefaultExpanded) : true;\n }\n\n // ---- Lifecycle ----\n\n ngOnInit(): void {\n this.DisplayName = this.SectionName;\n }\n\n ngAfterContentInit(): void {\n this.UpdateFieldNames();\n this.SubscribeToFieldNavigateEvents();\n this.FieldComponents.changes.subscribe(() => {\n this.UpdateFieldNames();\n this.SubscribeToFieldNavigateEvents();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['SectionName']) {\n this.DisplayName = this.SectionName;\n }\n if (changes['SectionName'] || changes['FormContext']) {\n this.UpdateVisibilityAndHighlighting();\n }\n if (changes['FormContext'] && this.FieldComponents) {\n this.FieldComponents.forEach(field => {\n field.FormContext = this.FormContext;\n });\n }\n }\n\n ngAfterViewInit(): void {\n this.SetupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.fieldNavReset$.next();\n this.fieldNavReset$.complete();\n this.resizeObserver?.disconnect();\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer);\n }\n }\n\n // ---- Actions ----\n\n Toggle(): void {\n if (!this.Collapsible) return;\n const formRef = this.Form as { SetSectionExpanded?: (key: string, expanded: boolean) => void };\n if (formRef?.SetSectionExpanded) {\n formRef.SetSectionExpanded(this.SectionKey, !this.Expanded);\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Navigate to the parent entity when clicking the \"Inherited from X\" badge.\n * Derives the PrimaryKey from the Form's record when InheritedRecordPrimaryKey\n * is not explicitly provided (which is the common case in generated templates).\n */\n OnInheritedBadgeClick(event: MouseEvent): void {\n event.stopPropagation();\n if (!this.InheritedFromEntity) return;\n\n const primaryKey = this.InheritedRecordPrimaryKey\n ?? (this.Form as { record?: { PrimaryKey: CompositeKey } })?.record?.PrimaryKey\n ?? new CompositeKey([]);\n\n this.Navigate.emit({\n Kind: 'entity-hierarchy',\n EntityName: this.InheritedFromEntity,\n PrimaryKey: primaryKey,\n Direction: 'parent'\n });\n }\n\n // ---- Drag and Drop ----\n\n @HostListener('dragover', ['$event'])\n OnDragOver(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer?.types.includes('text/plain')) {\n this.IsDragOver = true;\n }\n }\n\n @HostListener('dragleave', ['$event'])\n OnDragLeave(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n this.IsDragOver = false;\n }\n\n @HostListener('drop', ['$event'])\n OnDrop(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n event.stopPropagation();\n this.IsDragOver = false;\n\n const sourceSectionKey = event.dataTransfer?.getData('text/plain');\n if (sourceSectionKey && sourceSectionKey !== this.SectionKey) {\n this.PanelDrop.emit({\n SourceSectionKey: sourceSectionKey,\n TargetSectionKey: this.SectionKey\n });\n this.ReorderSections(sourceSectionKey, this.SectionKey);\n }\n }\n\n OnDragStart(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n this.IsDragging = true;\n event.dataTransfer?.setData('text/plain', this.SectionKey);\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n }\n this.DragStarted.emit({ SectionKey: this.SectionKey, Event: event });\n }\n\n OnDragEnd(): void {\n this.IsDragging = false;\n this.DragEnded.emit();\n }\n\n // ---- Private Methods ----\n\n private ReorderSections(sourceSectionKey: string, targetSectionKey: string): void {\n const formRef = this.Form as {\n getSectionOrder?: () => string[];\n setSectionOrder?: (order: string[]) => void;\n };\n if (!formRef?.getSectionOrder || !formRef?.setSectionOrder) return;\n\n const currentOrder = formRef.getSectionOrder();\n const sourceIndex = currentOrder.indexOf(sourceSectionKey);\n const targetIndex = currentOrder.indexOf(targetSectionKey);\n if (sourceIndex === -1 || targetIndex === -1) return;\n\n const newOrder = [...currentOrder];\n newOrder.splice(sourceIndex, 1);\n newOrder.splice(targetIndex, 0, sourceSectionKey);\n formRef.setSectionOrder(newOrder);\n this.cdr.markForCheck();\n }\n\n private UpdateFieldNames(): void {\n if (this.FieldComponents) {\n const names: string[] = [];\n this.FieldComponents.forEach(field => {\n if (field.DisplayName) {\n names.push(field.DisplayName.toLowerCase());\n }\n });\n this.FieldNames = names.join(' ');\n this.UpdateVisibilityAndHighlighting();\n }\n }\n\n /**\n * Subscribes to Navigate events from all child form-field components\n * and relays them through this panel's Navigate output.\n */\n private SubscribeToFieldNavigateEvents(): void {\n this.fieldNavReset$.next(); // tear down previous subscriptions\n this.FieldComponents.forEach(field => {\n field.Navigate.pipe(takeUntil(this.fieldNavReset$)).subscribe((event: FormNavigationEvent) => {\n this.Navigate.emit(event);\n });\n });\n }\n\n /**\n * Sets up a ResizeObserver on the panel content div for related-entity panels.\n * When the user drags the CSS resize handle, we persist the new height.\n */\n private SetupResizeObserver(): void {\n if (this.Variant !== 'related-entity' || !this.panelContentRef) return;\n\n const el = this.panelContentRef.nativeElement;\n // Run outside Angular zone to avoid triggering change detection on every resize frame\n this.ngZone.runOutsideAngular(() => {\n this.resizeObserver = new ResizeObserver((entries) => {\n // Skip the synchronous initial fire emitted when observe() is called — it's the\n // panel's own first measurement on load, not a user-initiated resize. Persisting\n // it would write a spurious panelHeight for every panel on form open.\n if (!this.resizeObserverPrimed) {\n this.resizeObserverPrimed = true;\n return;\n }\n // Only a height change while the panel is expanded reflects a genuine user drag of\n // the resize handle. Ignore reflows while collapsed (e.g. content settling on load).\n if (!this.Expanded) return;\n const entry = entries[0];\n if (!entry) return;\n const newHeight = Math.round(entry.contentRect.height);\n this.DebouncePersistHeight(newHeight);\n });\n this.resizeObserver.observe(el);\n });\n }\n\n /**\n * Debounces height persistence so we don't write to DB on every resize frame.\n */\n private DebouncePersistHeight(height: number): void {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer);\n }\n this.resizeDebounceTimer = setTimeout(() => {\n const formRef = this.Form as { SetSectionPanelHeight?: (key: string, height: number) => void };\n formRef?.SetSectionPanelHeight?.(this.SectionKey, height);\n }, 500);\n }\n\n private UpdateVisibilityAndHighlighting(): void {\n // Hard hide takes precedence over search state. Driven by an explicit\n // `Hidden` input OR the form config's section-visibility rules carried on\n // FormContext (which also reach slot-injected BaseFormPanels, since every\n // panel receives FormContext).\n if (this._hidden || IsFormSectionHidden(this.FormContext, this.SectionKey, this.Variant)) {\n this.IsVisible = false;\n this.DisplayName = EscapeHTML(this.SectionName);\n this.cdr.markForCheck();\n return;\n }\n\n const searchTerm = (this.FormContext?.sectionFilter || '').toLowerCase().trim();\n\n if (!searchTerm) {\n this.IsVisible = true;\n this.DisplayName = this.SectionName;\n this.cdr.markForCheck();\n return;\n }\n\n const sectionMatches = this.SectionName.toLowerCase().includes(searchTerm);\n const fieldsMatch = this.FieldNames.includes(searchTerm);\n this.IsVisible = sectionMatches || fieldsMatch;\n\n // DisplayName is bound to `[innerHTML]` in the template — must always be HTML-safe.\n this.DisplayName =\n this.IsVisible && sectionMatches\n ? HighlightSearchMatches(this.SectionName, searchTerm, 'mj-forms-search-highlight')\n : EscapeHTML(this.SectionName);\n\n this.cdr.markForCheck();\n }\n}\n","<div class=\"mj-forms-panel\"\n [class.mj-forms-panel--related]=\"Variant === 'related-entity'\"\n [class.mj-forms-panel--inherited]=\"Variant === 'inherited'\"\n [attr.data-section-key]=\"SectionKey\">\n\n <!-- Panel Header -->\n <div class=\"mj-forms-panel-header\"\n [class.mj-forms-panel-header--static]=\"!Collapsible\"\n [attr.role]=\"Collapsible ? 'button' : null\"\n [attr.tabindex]=\"Collapsible ? 0 : null\"\n (click)=\"Toggle()\">\n <!-- Drag Handle (hidden when reorder disabled) -->\n @if (ReorderAllowed) {\n <div class=\"mj-forms-drag-handle\"\n title=\"Drag to reorder sections\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n }\n\n <!-- Icon + Title -->\n <div class=\"mj-forms-panel-title-group\">\n <i [class]=\"Icon\" class=\"mj-forms-panel-icon\"></i>\n <h3 class=\"mj-forms-panel-title\">\n <span [innerHTML]=\"DisplayName\"></span>\n <!-- Row count badge for related entities -->\n @if (BadgeCount !== undefined) {\n <span class=\"mj-forms-row-count-badge\" [class.mj-forms-row-count-badge--zero]=\"BadgeCount === 0\">\n {{ BadgeCount }}\n </span>\n }\n </h3>\n </div>\n\n <!-- Inherited From badge (IS-A) -->\n @if (Variant === 'inherited' && InheritedFromEntity) {\n <a class=\"mj-forms-inherited-badge\" (click)=\"OnInheritedBadgeClick($event)\"\n [title]=\"'View parent record: ' + InheritedFromEntity\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n Inherited from {{ InheritedFromEntity }}\n </a>\n }\n\n <!-- Chevron (hidden when sections are locked open) -->\n @if (Collapsible) {\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\n }\n </div>\n\n <!-- Panel Body -->\n <div class=\"mj-forms-panel-body\" [class.mj-forms-panel-body--collapsed]=\"!Expanded\">\n <div class=\"mj-forms-panel-content\"\n #panelContent\n [style.height.px]=\"PanelContentHeight\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"collapsible-panel.component.js","sourceRoot":"","sources":["../../../src/lib/panel/collapsible-panel.component.ts","../../../src/lib/panel/collapsible-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component, Input, Output, EventEmitter,\n ChangeDetectionStrategy, ChangeDetectorRef, inject,\n OnChanges, SimpleChanges, OnInit, AfterContentInit, AfterViewInit, OnDestroy,\n ContentChildren, QueryList, HostBinding, HostListener, ElementRef,\n ViewChild, NgZone, ViewEncapsulation\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { FormContext, PanelVariant, PanelDragStartEvent, PanelDropEvent } from '../types/form-types';\nimport { IsFormSectionHidden } from '../types/entity-form-config';\nimport { FormNavigationEvent } from '../types/navigation-events';\nimport { MjFormFieldComponent } from '../field/form-field.component';\nimport { CompositeKey } from '@memberjunction/core';\nimport { EscapeHTML, HighlightSearchMatches } from '@memberjunction/global';\nimport { FormChromeCoordinator } from '../chrome/form-chrome-coordinator.service';\n\n/**\n * Reusable collapsible panel for form sections.\n *\n * Supports three visual variants:\n * - **default**: White card with accent border (standard field sections)\n * - **related-entity**: Blue-accented card with row count badge (related entity grids)\n * - **inherited**: Purple-accented card with \"Inherited from X\" badge (IS-A parent field sections)\n *\n * Features:\n * - Expand/collapse with smooth animation\n * - Search filtering (hides non-matching panels, highlights matched names)\n * - Drag-to-reorder sections\n * - Inheritable \"Inherited from X\" badge with navigation event\n * - Row count badge for related entity sections\n *\n * @example\n * ```html\n * <mj-collapsible-panel\n * SectionKey=\"productDetails\"\n * SectionName=\"Product Details\"\n * Icon=\"fa fa-box\"\n * Variant=\"inherited\"\n * InheritedFromEntity=\"Products\"\n * [Form]=\"formComponent\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\">\n * <mj-form-field ...></mj-form-field>\n * </mj-collapsible-panel>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-collapsible-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None, // Required to style projected content (grids, etc.)\n templateUrl: './collapsible-panel.component.html',\n styleUrls: ['./collapsible-panel.component.css']\n})\nexport class MjCollapsiblePanelComponent implements OnInit, OnChanges, AfterContentInit, AfterViewInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private elementRef = inject(ElementRef);\n private ngZone = inject(NgZone);\n private chrome = inject(FormChromeCoordinator, { optional: true });\n\n /** Unique key for state persistence */\n @Input() SectionKey = '';\n\n /** Display name shown in the panel header */\n @Input() SectionName = '';\n\n /** Font Awesome icon class for the panel header */\n @Input() Icon = 'fa fa-folder';\n\n /**\n * Reference to the parent form component for state delegation.\n * Expected to have IsSectionExpanded, SetSectionExpanded, getSectionDisplayOrder methods.\n */\n @Input() Form: unknown;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n /** Panel visual variant */\n @Input() Variant: PanelVariant = 'default';\n\n /** Row count badge for related entity sections */\n @Input() BadgeCount: number | undefined;\n\n /** Default expanded state when no persisted state exists */\n @Input() DefaultExpanded: boolean | undefined;\n\n /**\n * For 'inherited' variant: the parent entity name this section's fields come from.\n * Displayed as \"Inherited from X\" badge and used for navigation.\n */\n @Input() InheritedFromEntity = '';\n\n /**\n * For 'inherited' variant: the primary key to navigate to when clicking the badge.\n * (Shared PK in IS-A relationships.)\n */\n @Input() InheritedRecordPrimaryKey?: CompositeKey;\n\n /**\n * Container-driven hard hide. When true the panel is removed from view\n * regardless of search state — used by the record-form container to honor\n * `EntityFormConfig.showRelatedEntities` / `hiddenSectionKeys` /\n * `visibleSectionKeys`. Composes with (overrides) search visibility so all\n * existing `IsVisible`-based section counts stay correct.\n */\n @Input()\n set Hidden(value: boolean) {\n if (value !== this._hidden) {\n this._hidden = value;\n // Recompute visibility if content has initialized (FieldComponents present).\n if (this.FieldComponents) {\n this.UpdateVisibilityAndHighlighting();\n }\n }\n }\n get Hidden(): boolean {\n return this._hidden;\n }\n private _hidden = false;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [SectionKey] instead */\n @Input('sectionKey') set _deprecatedSectionKey(value: string) { this.SectionKey = value; }\n\n /** @deprecated Use [SectionName] instead */\n @Input('sectionName') set _deprecatedSectionName(value: string) { this.SectionName = value; }\n\n /** @deprecated Use [Icon] instead */\n @Input('icon') set _deprecatedIcon(value: string) { this.Icon = value; }\n\n /** @deprecated Use [Form] instead */\n @Input('form') set _deprecatedForm(value: unknown) { this.Form = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n // ---- Outputs ----\n\n @Output() DragStarted = new EventEmitter<PanelDragStartEvent>();\n @Output() DragEnded = new EventEmitter<void>();\n @Output() PanelDrop = new EventEmitter<PanelDropEvent>();\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Content Children ----\n\n @ContentChildren(MjFormFieldComponent, { descendants: true }) FieldComponents!: QueryList<MjFormFieldComponent>;\n\n // ---- State ----\n\n DisplayName = '';\n FieldNames = '';\n IsVisible = true;\n\n @HostBinding('attr.data-section-key')\n get HostSectionKey(): string {\n return this.SectionKey;\n }\n\n @HostBinding('attr.data-variant')\n get HostVariant(): string {\n return this.Variant;\n }\n\n @HostBinding('attr.data-icon')\n get HostIcon(): string {\n return this.Icon;\n }\n\n @HostBinding('class')\n get HostClass(): string {\n const classes = [`mj-panel--${this.Variant}`];\n if (!this.IsVisible) classes.push('mj-search-hidden');\n if (this.IsDragging) classes.push('mj-dragging');\n if (this.IsDragOver) classes.push('mj-drag-over');\n if (this.chrome?.Spec.RelatedRoles.get(this.SectionKey) === 'Detail') {\n classes.push('mj-form-role-detail');\n }\n if (this.chrome?.HidesAccordionChrome(this.SectionKey)) {\n classes.push('mj-chrome-plain');\n }\n if (!this.hasRenderableContent()) {\n classes.push('mj-panel-empty');\n }\n return classes.join(' ');\n }\n\n @HostBinding('style.order')\n get CssOrder(): number {\n const formRef = this.Form as { getSectionDisplayOrder?: (key: string) => number };\n return formRef?.getSectionDisplayOrder ? formRef.getSectionDisplayOrder(this.SectionKey) : 0;\n }\n\n IsDragging = false;\n IsDragOver = false;\n\n // ---- Event relay ----\n\n /** Signals re-subscription when ContentChildren change */\n private fieldNavReset$ = new Subject<void>();\n private destroy$ = new Subject<void>();\n\n // ---- Panel content resize ----\n\n @ViewChild('panelContent') private panelContentRef?: ElementRef<HTMLElement>;\n private resizeObserver?: ResizeObserver;\n private resizeDebounceTimer?: ReturnType<typeof setTimeout>;\n /** ResizeObserver fires once synchronously on observe(); that initial measurement is not a user resize. */\n private resizeObserverPrimed = false;\n\n /**\n * Persisted accordion resize height for related-entity panels.\n * Related grids size themselves from row count (accordion and left-nav),\n * so a pinned pixel height — especially 0 / toolbar-only measured while\n * collapsed — would clip the grid. Only honor a user drag that is at\n * least the CSS min-height.\n */\n get PanelContentHeight(): number | undefined {\n if (this.Variant !== 'related-entity') return undefined;\n if (this.hidesAccordionChrome()) return undefined;\n const formRef = this.Form as { GetSectionPanelHeight?: (key: string) => number | undefined };\n const persisted = formRef?.GetSectionPanelHeight?.(this.SectionKey);\n if (persisted == null || persisted < 120) return undefined;\n return persisted;\n }\n\n private hidesAccordionChrome(): boolean {\n if (this.chrome?.HidesAccordionChrome(this.SectionKey)) return true;\n const el = this.elementRef.nativeElement as HTMLElement | undefined;\n return !!el?.classList.contains('mj-chrome-show');\n }\n\n /** Whether drag-to-reorder is allowed (from FormContext) */\n get ReorderAllowed(): boolean {\n return this.FormContext?.allowSectionReorder !== false;\n }\n\n /**\n * Whether this panel's header may collapse/expand. Driven by\n * `FormContext.collapsibleSections`; when false the panel renders\n * always-expanded with no toggle chevron (used by dialog/slide-in surfaces\n * that lock sections open). Undefined / true means collapsible.\n */\n get Collapsible(): boolean {\n // Selected left-nav item has no accordion chrome. More keeps collapse/expand.\n if (this.hidesAccordionChrome()) return false;\n return this.FormContext?.collapsibleSections !== false;\n }\n\n /** Whether the panel is expanded (delegates to form state; always true when not collapsible) */\n get Expanded(): boolean {\n if (!this.Collapsible) return true;\n const formRef = this.Form as { IsSectionExpanded?: (key: string, defaultExpanded?: boolean) => boolean };\n return formRef?.IsSectionExpanded ? formRef.IsSectionExpanded(this.SectionKey, this.DefaultExpanded) : true;\n }\n\n // ---- Lifecycle ----\n\n ngOnInit(): void {\n this.DisplayName = this.SectionName;\n this.chrome?.Changes.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.UpdateVisibilityAndHighlighting();\n });\n }\n\n ngAfterContentInit(): void {\n this.UpdateFieldNames();\n this.SubscribeToFieldNavigateEvents();\n this.FieldComponents.changes.subscribe(() => {\n this.UpdateFieldNames();\n this.SubscribeToFieldNavigateEvents();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['SectionName']) {\n this.DisplayName = this.SectionName;\n }\n if (changes['SectionName'] || changes['FormContext']) {\n this.UpdateVisibilityAndHighlighting();\n }\n if (changes['FormContext'] && this.FieldComponents) {\n this.FieldComponents.forEach(field => {\n field.FormContext = this.FormContext;\n });\n }\n }\n\n ngAfterViewInit(): void {\n this.SetupResizeObserver();\n }\n\n ngOnDestroy(): void {\n this.fieldNavReset$.next();\n this.fieldNavReset$.complete();\n this.destroy$.next();\n this.destroy$.complete();\n this.resizeObserver?.disconnect();\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer);\n }\n }\n\n // ---- Actions ----\n\n Toggle(): void {\n if (!this.Collapsible) return;\n const formRef = this.Form as { SetSectionExpanded?: (key: string, expanded: boolean) => void };\n if (formRef?.SetSectionExpanded) {\n formRef.SetSectionExpanded(this.SectionKey, !this.Expanded);\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Navigate to the parent entity when clicking the \"Inherited from X\" badge.\n * Derives the PrimaryKey from the Form's record when InheritedRecordPrimaryKey\n * is not explicitly provided (which is the common case in generated templates).\n */\n OnInheritedBadgeClick(event: MouseEvent): void {\n event.stopPropagation();\n if (!this.InheritedFromEntity) return;\n\n const primaryKey = this.InheritedRecordPrimaryKey\n ?? (this.Form as { record?: { PrimaryKey: CompositeKey } })?.record?.PrimaryKey\n ?? new CompositeKey([]);\n\n this.Navigate.emit({\n Kind: 'entity-hierarchy',\n EntityName: this.InheritedFromEntity,\n PrimaryKey: primaryKey,\n Direction: 'parent'\n });\n }\n\n // ---- Drag and Drop ----\n\n @HostListener('dragover', ['$event'])\n OnDragOver(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer?.types.includes('text/plain')) {\n this.IsDragOver = true;\n }\n }\n\n @HostListener('dragleave', ['$event'])\n OnDragLeave(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n this.IsDragOver = false;\n }\n\n @HostListener('drop', ['$event'])\n OnDrop(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n event.preventDefault();\n event.stopPropagation();\n this.IsDragOver = false;\n\n const sourceSectionKey = event.dataTransfer?.getData('text/plain');\n if (sourceSectionKey && sourceSectionKey !== this.SectionKey) {\n this.PanelDrop.emit({\n SourceSectionKey: sourceSectionKey,\n TargetSectionKey: this.SectionKey\n });\n this.ReorderSections(sourceSectionKey, this.SectionKey);\n }\n }\n\n OnDragStart(event: DragEvent): void {\n if (!this.ReorderAllowed) return;\n this.IsDragging = true;\n event.dataTransfer?.setData('text/plain', this.SectionKey);\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n }\n this.DragStarted.emit({ SectionKey: this.SectionKey, Event: event });\n }\n\n OnDragEnd(): void {\n this.IsDragging = false;\n this.DragEnded.emit();\n }\n\n // ---- Private Methods ----\n\n private ReorderSections(sourceSectionKey: string, targetSectionKey: string): void {\n const formRef = this.Form as {\n getSectionOrder?: () => string[];\n setSectionOrder?: (order: string[]) => void;\n };\n if (!formRef?.getSectionOrder || !formRef?.setSectionOrder) return;\n\n const currentOrder = formRef.getSectionOrder();\n const sourceIndex = currentOrder.indexOf(sourceSectionKey);\n const targetIndex = currentOrder.indexOf(targetSectionKey);\n if (sourceIndex === -1 || targetIndex === -1) return;\n\n const newOrder = [...currentOrder];\n newOrder.splice(sourceIndex, 1);\n newOrder.splice(targetIndex, 0, sourceSectionKey);\n formRef.setSectionOrder(newOrder);\n this.cdr.markForCheck();\n }\n\n /**\n * Field panels whose only children are empty/hidden (e.g. leftover\n * `Details` with just unused geo columns) should not take space.\n * Custom widgets and related grids have no FieldComponents — keep them.\n */\n /**\n * Whether this panel matches a section-search term by title or field\n * name. Ignores chrome hide/show — the rail uses this to decide if the\n * *group* matches, even when another section is currently selected.\n */\n public MatchesSearch(term: string): boolean {\n const filter = (term || '').toLowerCase().trim();\n if (!filter) return true;\n if (this.SectionName.toLowerCase().includes(filter)) return true;\n if (this.SectionKey.toLowerCase().includes(filter)) return true;\n return this.FieldNames.includes(filter);\n }\n\n private hasRenderableContent(): boolean {\n if (this.Variant === 'related-entity') return true;\n if (!this.FieldComponents || this.FieldComponents.length === 0) return true;\n return this.FieldComponents.some((field) => !field.ShouldHideField);\n }\n\n private isHiddenByChrome(): boolean {\n if (!this.chrome) return false;\n if (this.Variant === 'related-entity') {\n return !this.chrome.IsRelatedSectionVisible(this.SectionKey);\n }\n return !this.chrome.IsFirstClassSectionVisible(this.SectionKey);\n }\n\n private UpdateFieldNames(): void {\n if (this.FieldComponents) {\n const names: string[] = [];\n this.FieldComponents.forEach(field => {\n if (field.DisplayName) {\n names.push(field.DisplayName.toLowerCase());\n }\n });\n this.FieldNames = names.join(' ');\n this.UpdateVisibilityAndHighlighting();\n }\n }\n\n /**\n * Subscribes to Navigate events from all child form-field components\n * and relays them through this panel's Navigate output.\n */\n private SubscribeToFieldNavigateEvents(): void {\n this.fieldNavReset$.next(); // tear down previous subscriptions\n this.FieldComponents.forEach(field => {\n field.Navigate.pipe(takeUntil(this.fieldNavReset$)).subscribe((event: FormNavigationEvent) => {\n this.Navigate.emit(event);\n });\n });\n }\n\n /**\n * Sets up a ResizeObserver on the panel content div for related-entity panels.\n * When the user drags the CSS resize handle, we persist the new height.\n */\n private SetupResizeObserver(): void {\n if (this.Variant !== 'related-entity' || !this.panelContentRef) return;\n\n const el = this.panelContentRef.nativeElement;\n // Run outside Angular zone to avoid triggering change detection on every resize frame\n this.ngZone.runOutsideAngular(() => {\n this.resizeObserver = new ResizeObserver((entries) => {\n // Skip the synchronous initial fire emitted when observe() is called — it's the\n // panel's own first measurement on load, not a user-initiated resize. Persisting\n // it would write a spurious panelHeight for every panel on form open.\n if (!this.resizeObserverPrimed) {\n this.resizeObserverPrimed = true;\n return;\n }\n // Only a height change while the panel is expanded reflects a genuine user drag of\n // the resize handle. Ignore reflows while collapsed (e.g. content settling on load).\n if (!this.Expanded) return;\n // Left-nav sizes the grid from the leftover column. Persisting that\n // computed height would write ~0 (or the toolbar) and then pin it.\n if (this.hidesAccordionChrome()) return;\n const entry = entries[0];\n if (!entry) return;\n const newHeight = Math.round(entry.contentRect.height);\n if (newHeight < 120) return;\n this.DebouncePersistHeight(newHeight);\n });\n this.resizeObserver.observe(el);\n });\n }\n\n /**\n * Debounces height persistence so we don't write to DB on every resize frame.\n */\n private DebouncePersistHeight(height: number): void {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer);\n }\n this.resizeDebounceTimer = setTimeout(() => {\n const formRef = this.Form as { SetSectionPanelHeight?: (key: string, height: number) => void };\n formRef?.SetSectionPanelHeight?.(this.SectionKey, height);\n }, 500);\n }\n\n private UpdateVisibilityAndHighlighting(): void {\n // Hard hide takes precedence over search state. Driven by an explicit\n // `Hidden` input OR the form config's section-visibility rules carried on\n // FormContext (which also reach slot-injected BaseFormPanels, since every\n // panel receives FormContext).\n if (this._hidden || IsFormSectionHidden(this.FormContext, this.SectionKey, this.Variant) || this.isHiddenByChrome()) {\n this.IsVisible = false;\n this.DisplayName = EscapeHTML(this.SectionName);\n this.cdr.markForCheck();\n return;\n }\n\n const searchTerm = (this.FormContext?.sectionFilter || '').toLowerCase().trim();\n\n if (!searchTerm) {\n this.IsVisible = this.hasRenderableContent();\n this.DisplayName = this.SectionName;\n this.cdr.markForCheck();\n return;\n }\n\n const sectionMatches = this.SectionName.toLowerCase().includes(searchTerm);\n const fieldsMatch = this.FieldNames.includes(searchTerm);\n this.IsVisible = this.MatchesSearch(searchTerm);\n\n // DisplayName is bound to `[innerHTML]` in the template — must always be HTML-safe.\n this.DisplayName =\n this.IsVisible && sectionMatches\n ? HighlightSearchMatches(this.SectionName, searchTerm, 'mj-forms-search-highlight')\n : EscapeHTML(this.SectionName);\n\n this.cdr.markForCheck();\n }\n}\n","<div class=\"mj-forms-panel\"\n [class.mj-forms-panel--related]=\"Variant === 'related-entity'\"\n [class.mj-forms-panel--inherited]=\"Variant === 'inherited'\"\n [attr.data-section-key]=\"SectionKey\">\n\n <!-- Panel Header -->\n <div class=\"mj-forms-panel-header\"\n [class.mj-forms-panel-header--static]=\"!Collapsible\"\n [attr.role]=\"Collapsible ? 'button' : null\"\n [attr.tabindex]=\"Collapsible ? 0 : null\"\n (click)=\"Toggle()\">\n <!-- Drag Handle (hidden when reorder disabled) -->\n @if (ReorderAllowed) {\n <div class=\"mj-forms-drag-handle\"\n title=\"Drag to reorder sections\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n }\n\n <!-- Icon + Title -->\n <div class=\"mj-forms-panel-title-group\">\n <i [class]=\"Icon\" class=\"mj-forms-panel-icon\"></i>\n <h3 class=\"mj-forms-panel-title\">\n <span [innerHTML]=\"DisplayName\"></span>\n <!-- Row count badge for related entities -->\n @if (BadgeCount !== undefined) {\n <span class=\"mj-forms-row-count-badge\" [class.mj-forms-row-count-badge--zero]=\"BadgeCount === 0\">\n {{ BadgeCount }}\n </span>\n }\n </h3>\n </div>\n\n <!-- Inherited From badge (IS-A) -->\n @if (Variant === 'inherited' && InheritedFromEntity) {\n <a class=\"mj-forms-inherited-badge\" (click)=\"OnInheritedBadgeClick($event)\"\n [title]=\"'View parent record: ' + InheritedFromEntity\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n Inherited from {{ InheritedFromEntity }}\n </a>\n }\n\n <!-- Chevron (hidden when sections are locked open) -->\n @if (Collapsible) {\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\n }\n </div>\n\n <!-- Panel Body -->\n <div class=\"mj-forms-panel-body\" [class.mj-forms-panel-body--collapsed]=\"!Expanded\">\n <div class=\"mj-forms-panel-content\"\n #panelContent\n [style.height.px]=\"PanelContentHeight\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { BaseEntity, ValidationResult } from '@memberjunction/core';
|
|
1
|
+
import { BaseEntity, ValidationResult, type FormInclusion } from '@memberjunction/core';
|
|
2
2
|
import { BaseFormComponent } from '../base-form-component';
|
|
3
3
|
import { FormContext } from '../types/form-types';
|
|
4
|
+
import { FormToolbarItemConfig, FormToolbarItemKey } from '../types/form-toolbar-item';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
/**
|
|
6
7
|
* Well-known slot positions where panels can be injected into a generated
|
|
@@ -53,6 +54,43 @@ export interface FormPanelRegistrationMetadata extends Record<string, unknown> {
|
|
|
53
54
|
entity: string;
|
|
54
55
|
slot: FormPanelSlot;
|
|
55
56
|
sortKey?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Identity for last-wins collapse. Two registrations with the same key
|
|
59
|
+
* compete; highest ClassFactory `Priority` wins. Omit to derive:
|
|
60
|
+
* `related:${relatedEntity}:${relatedJoinField}` when claiming a
|
|
61
|
+
* relationship, otherwise the registration is unique and never collapses.
|
|
62
|
+
*/
|
|
63
|
+
contributionKey?: string;
|
|
64
|
+
/**
|
|
65
|
+
* When set, this panel **replaces** the default related-entity grid for
|
|
66
|
+
* that relationship on `entity`'s form. The baked CodeGen panel (if any)
|
|
67
|
+
* is hidden; the stock fill-in grid is not mounted.
|
|
68
|
+
*/
|
|
69
|
+
relatedEntity?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Disambiguates two FKs to the same related entity (BillTo vs ShipTo).
|
|
72
|
+
* Compared after stripping wrapping `[]`.
|
|
73
|
+
*/
|
|
74
|
+
relatedJoinField?: string;
|
|
75
|
+
/**
|
|
76
|
+
* CodeGen `SectionKey` of a baked field (or other) panel this contribution
|
|
77
|
+
* replaces — e.g. `'details'`, `'personalIdentity'`. Hidden at runtime via
|
|
78
|
+
* `HiddenSectionKeys`. Use with `slot: 'before-fields'` for a form hero that
|
|
79
|
+
* is not a collapsible panel. Must name a concrete `entity` (not `'*'`).
|
|
80
|
+
*/
|
|
81
|
+
replacesSectionKey?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Pin this contribution to a chrome bucket instead of its own rail item.
|
|
84
|
+
* `'details'` — leftover own-fields group. `'more'` — overflow folder.
|
|
85
|
+
*/
|
|
86
|
+
chromeGroup?: 'details' | 'more';
|
|
87
|
+
/**
|
|
88
|
+
* L1 inclusion for this contribution (same verbs as relationships).
|
|
89
|
+
* `'Primary'` — own first-class rail item, in the lead band before Details.
|
|
90
|
+
* `'More'` — overflow folder. `'None'` — hidden.
|
|
91
|
+
* L3 `MJ: Form Chrome Rules` still wins. `chromeGroup` still merges.
|
|
92
|
+
*/
|
|
93
|
+
inclusion?: FormInclusion;
|
|
56
94
|
}
|
|
57
95
|
/**
|
|
58
96
|
* Abstract base for every dynamically-injectable form panel.
|
|
@@ -73,6 +111,12 @@ export interface FormPanelRegistrationMetadata extends Record<string, unknown> {
|
|
|
73
111
|
* record itself does can leave this method off.
|
|
74
112
|
*/
|
|
75
113
|
export declare abstract class BaseFormPanel<TRecord extends BaseEntity = BaseEntity> {
|
|
114
|
+
/**
|
|
115
|
+
* Slot-mounted hosts must not sit in the left-nav flex column — leftover
|
|
116
|
+
* height targets `mj-collapsible-panel` as a direct child of
|
|
117
|
+
* `.mj-forms-all-panels`. `display: contents` makes the inner panel that child.
|
|
118
|
+
*/
|
|
119
|
+
readonly HostDisplay = "contents";
|
|
76
120
|
/** The entity record being edited. Set by the slot host before view init. */
|
|
77
121
|
Record: TRecord;
|
|
78
122
|
/** The host form component (use for EditMode, dirty notifications, etc). Set by the slot host. */
|
|
@@ -94,6 +138,46 @@ export declare abstract class BaseFormPanel<TRecord extends BaseEntity = BaseEnt
|
|
|
94
138
|
* can leave this method off).
|
|
95
139
|
*/
|
|
96
140
|
validate(): ValidationResult;
|
|
141
|
+
/**
|
|
142
|
+
* Called after the parent form reloads the current record from the database.
|
|
143
|
+
* Default is a no-op. Override to refresh panel-owned data that is not a
|
|
144
|
+
* related-entity grid (those already subscribe to
|
|
145
|
+
* {@link FormRecordRefreshCoordinator} themselves).
|
|
146
|
+
*/
|
|
147
|
+
OnRecordRefreshed(_record: TRecord): void;
|
|
148
|
+
/**
|
|
149
|
+
* Registers a dynamic toolbar action item / button into the host form toolbar.
|
|
150
|
+
*/
|
|
151
|
+
RegisterToolbarItem(item: FormToolbarItemConfig): void;
|
|
152
|
+
/**
|
|
153
|
+
* Unregisters a previously registered dynamic toolbar item by key.
|
|
154
|
+
*/
|
|
155
|
+
UnregisterToolbarItem(key: string): void;
|
|
156
|
+
/**
|
|
157
|
+
* Configures overrides for any toolbar item (standard built-in items like 'edit',
|
|
158
|
+
* 'delete', 'favorite', 'history', etc., or custom items).
|
|
159
|
+
*/
|
|
160
|
+
ConfigureToolbarItem(key: FormToolbarItemKey, overrides: Partial<FormToolbarItemConfig>): void;
|
|
161
|
+
/**
|
|
162
|
+
* Dynamically hides a toolbar item by key.
|
|
163
|
+
*/
|
|
164
|
+
HideToolbarItem(key: FormToolbarItemKey): void;
|
|
165
|
+
/**
|
|
166
|
+
* Dynamically shows a toolbar item by key.
|
|
167
|
+
*/
|
|
168
|
+
ShowToolbarItem(key: FormToolbarItemKey): void;
|
|
169
|
+
/**
|
|
170
|
+
* Dynamically disables a toolbar item by key, with an optional reason string for the tooltip.
|
|
171
|
+
*/
|
|
172
|
+
DisableToolbarItem(key: FormToolbarItemKey, reason?: string): void;
|
|
173
|
+
/**
|
|
174
|
+
* Dynamically enables a toolbar item by key.
|
|
175
|
+
*/
|
|
176
|
+
EnableToolbarItem(key: FormToolbarItemKey): void;
|
|
177
|
+
/**
|
|
178
|
+
* Sets the numeric display order for a toolbar item.
|
|
179
|
+
*/
|
|
180
|
+
SetToolbarItemOrder(key: FormToolbarItemKey, order: number): void;
|
|
97
181
|
static ɵfac: i0.ɵɵFactoryDeclaration<BaseFormPanel<any>, never>;
|
|
98
182
|
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseFormPanel<any>, never, never, { "Record": { "alias": "Record"; "required": false; }; "FormComponent": { "alias": "FormComponent"; "required": false; }; "FormContext": { "alias": "FormContext"; "required": false; }; }, {}, never, never, true, never>;
|
|
99
183
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-form-panel.d.ts","sourceRoot":"","sources":["../../../src/lib/panel-slot/base-form-panel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"base-form-panel.d.ts","sourceRoot":"","sources":["../../../src/lib/panel-slot/base-form-panel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;;AAEvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,aAAa,GACnB,UAAU,GACV,eAAe,GACf,cAAc,GACd,eAAe,GACf,kBAAkB,CAAC;AAEzB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,6BAA8B,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,8BACsB,aAAa,CAAC,OAAO,SAAS,UAAU,GAAG,UAAU;IACvE;;;;OAIG;IAEH,QAAQ,CAAC,WAAW,cAAc;IAElC,6EAA6E;IACpE,MAAM,EAAG,OAAO,CAAC;IAC1B,kGAAkG;IACzF,aAAa,EAAG,iBAAiB,CAAC;IAC3C,qGAAqG;IAC5F,WAAW,CAAC,EAAE,WAAW,CAAC;IAEnC;;;;;OAKG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;;;OAMG;IACI,QAAQ,IAAI,gBAAgB;IAQnC;;;;;OAKG;IACI,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhD;;OAEG;IACI,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAI7D;;OAEG;IACI,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI/C;;;OAGG;IACI,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,EAAE,SAAS,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI;IAIrG;;OAEG;IACI,eAAe,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIrD;;OAEG;IACI,eAAe,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIrD;;OAEG;IACI,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAIzE;;OAEG;IACI,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIvD;;OAEG;IACI,mBAAmB,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;yCAxGtD,aAAa;2CAAb,aAAa;CA2GlC"}
|