@memberjunction/ng-base-forms 5.33.0 → 5.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/explorer-entity-data-grid.component.d.ts +11 -0
- package/dist/lib/explorer-entity-data-grid.component.d.ts.map +1 -1
- package/dist/lib/explorer-entity-data-grid.component.js +18 -4
- package/dist/lib/explorer-entity-data-grid.component.js.map +1 -1
- package/dist/lib/field/form-field.component.d.ts +1 -1
- package/dist/lib/field/form-field.component.d.ts.map +1 -1
- package/dist/lib/field/form-field.component.js +3 -7
- package/dist/lib/field/form-field.component.js.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.d.ts.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.js +7 -9
- package/dist/lib/panel/collapsible-panel.component.js.map +1 -1
- package/package.json +10 -10
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from '@angular/core';
|
|
2
2
|
import { RunViewParams } from '@memberjunction/core';
|
|
3
3
|
import { EntityDataGridComponent, AfterRowDoubleClickEventArgs, AfterRowClickEventArgs, AfterDataLoadEventArgs, GridToolbarConfig, GridSelectionMode } from '@memberjunction/ng-entity-viewer';
|
|
4
|
+
import { EntityInfo } from '@memberjunction/core';
|
|
4
5
|
import { FormNavigationEvent } from './types/navigation-events';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
/**
|
|
@@ -31,6 +32,16 @@ export declare class ExplorerEntityDataGridComponent {
|
|
|
31
32
|
onRowDoubleClick(event: AfterRowDoubleClickEventArgs): void;
|
|
32
33
|
onRowClick(event: AfterRowClickEventArgs): void;
|
|
33
34
|
onDataLoad(event: AfterDataLoadEventArgs): void;
|
|
35
|
+
/**
|
|
36
|
+
* The inner grid's "New" button bubbles up here. We re-emit as a
|
|
37
|
+
* `new-record` Navigate event so the host form (and Explorer's
|
|
38
|
+
* SingleRecordComponent) can call NavigationService.OpenNewEntityRecord
|
|
39
|
+
* and pre-populate the foreign-key fields from NewRecordValues.
|
|
40
|
+
*/
|
|
41
|
+
onNewRecordTabRequested(event: {
|
|
42
|
+
entityInfo: EntityInfo;
|
|
43
|
+
defaultValues: Record<string, unknown>;
|
|
44
|
+
}): void;
|
|
34
45
|
static ɵfac: i0.ɵɵFactoryDeclaration<ExplorerEntityDataGridComponent, never>;
|
|
35
46
|
static ɵcmp: i0.ɵɵComponentDeclaration<ExplorerEntityDataGridComponent, "mj-explorer-entity-data-grid", never, { "Params": { "alias": "Params"; "required": false; }; "NewRecordValues": { "alias": "NewRecordValues"; "required": false; }; "AllowLoad": { "alias": "AllowLoad"; "required": false; }; "ShowToolbar": { "alias": "ShowToolbar"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "ToolbarConfig": { "alias": "ToolbarConfig"; "required": false; }; "SelectionMode": { "alias": "SelectionMode"; "required": false; }; "NavigateOnDoubleClick": { "alias": "NavigateOnDoubleClick"; "required": false; }; }, { "AfterRowDoubleClick": "AfterRowDoubleClick"; "AfterRowClick": "AfterRowClick"; "AfterDataLoad": "AfterDataLoad"; "Navigate": "Navigate"; }, never, never, false, never>;
|
|
36
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-entity-data-grid.component.d.ts","sourceRoot":"","sources":["../../src/lib/explorer-entity-data-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAa,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACH,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EAEpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;;AAEhE;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"explorer-entity-data-grid.component.d.ts","sourceRoot":"","sources":["../../src/lib/explorer-entity-data-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAa,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACH,uBAAuB,EACvB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EAEpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;;AAEhE;;;;;GAKG;AACH,qBA2Ba,+BAA+B;IAChB,SAAS,EAAG,uBAAuB,CAAC;IAGnD,MAAM,EAAE,aAAa,GAAG,IAAI,CAAQ;IACpC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;IAC9C,SAAS,EAAE,OAAO,CAAQ;IAC1B,WAAW,EAAE,OAAO,CAAQ;IAC5B,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAU;IACjD,aAAa,EAAE,iBAAiB,CAAM;IACtC,aAAa,EAAE,iBAAiB,CAAY;IAErD;;;OAGG;IACM,qBAAqB,EAAE,OAAO,CAAQ;IAGrC,mBAAmB,6CAAoD;IACvE,aAAa,uCAA8C;IAC3D,aAAa,uCAA8C;IAErE,6EAA6E;IACnE,QAAQ,oCAA2C;IAE7D,gBAAgB,CAAC,KAAK,EAAE,4BAA4B,GAAG,IAAI;IAoB3D,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAK/C,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAK/C;;;;;OAKG;IACH,uBAAuB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI;yCA9D/F,+BAA+B;2CAA/B,+BAA+B;CAqE3C"}
|
|
@@ -55,16 +55,29 @@ export class ExplorerEntityDataGridComponent {
|
|
|
55
55
|
// Re-emit the event for any consumers
|
|
56
56
|
this.AfterDataLoad.emit(event);
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* The inner grid's "New" button bubbles up here. We re-emit as a
|
|
60
|
+
* `new-record` Navigate event so the host form (and Explorer's
|
|
61
|
+
* SingleRecordComponent) can call NavigationService.OpenNewEntityRecord
|
|
62
|
+
* and pre-populate the foreign-key fields from NewRecordValues.
|
|
63
|
+
*/
|
|
64
|
+
onNewRecordTabRequested(event) {
|
|
65
|
+
this.Navigate.emit({
|
|
66
|
+
Kind: 'new-record',
|
|
67
|
+
EntityName: event.entityInfo.Name,
|
|
68
|
+
DefaultValues: event.defaultValues,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
58
71
|
static ɵfac = function ExplorerEntityDataGridComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ExplorerEntityDataGridComponent)(); };
|
|
59
72
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ExplorerEntityDataGridComponent, selectors: [["mj-explorer-entity-data-grid"]], viewQuery: function ExplorerEntityDataGridComponent_Query(rf, ctx) { if (rf & 1) {
|
|
60
73
|
i0.ɵɵviewQuery(_c0, 5);
|
|
61
74
|
} if (rf & 2) {
|
|
62
75
|
let _t;
|
|
63
76
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.innerGrid = _t.first);
|
|
64
|
-
} }, inputs: { Params: "Params", NewRecordValues: "NewRecordValues", AllowLoad: "AllowLoad", ShowToolbar: "ShowToolbar", Height: "Height", ToolbarConfig: "ToolbarConfig", SelectionMode: "SelectionMode", NavigateOnDoubleClick: "NavigateOnDoubleClick" }, outputs: { AfterRowDoubleClick: "AfterRowDoubleClick", AfterRowClick: "AfterRowClick", AfterDataLoad: "AfterDataLoad", Navigate: "Navigate" }, standalone: false, decls: 2, vars: 7, consts: [["innerGrid", ""], [3, "AfterRowDoubleClick", "AfterRowClick", "AfterDataLoad", "Params", "NewRecordValues", "AllowLoad", "ShowToolbar", "Height", "ToolbarConfig", "SelectionMode"]], template: function ExplorerEntityDataGridComponent_Template(rf, ctx) { if (rf & 1) {
|
|
77
|
+
} }, inputs: { Params: "Params", NewRecordValues: "NewRecordValues", AllowLoad: "AllowLoad", ShowToolbar: "ShowToolbar", Height: "Height", ToolbarConfig: "ToolbarConfig", SelectionMode: "SelectionMode", NavigateOnDoubleClick: "NavigateOnDoubleClick" }, outputs: { AfterRowDoubleClick: "AfterRowDoubleClick", AfterRowClick: "AfterRowClick", AfterDataLoad: "AfterDataLoad", Navigate: "Navigate" }, standalone: false, decls: 2, vars: 7, consts: [["innerGrid", ""], [3, "AfterRowDoubleClick", "AfterRowClick", "AfterDataLoad", "NewRecordTabRequested", "Params", "NewRecordValues", "AllowLoad", "ShowToolbar", "Height", "ToolbarConfig", "SelectionMode"]], template: function ExplorerEntityDataGridComponent_Template(rf, ctx) { if (rf & 1) {
|
|
65
78
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
66
79
|
i0.ɵɵelementStart(0, "mj-entity-data-grid", 1, 0);
|
|
67
|
-
i0.ɵɵlistener("AfterRowDoubleClick", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterRowDoubleClick_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRowDoubleClick($event)); })("AfterRowClick", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterRowClick_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRowClick($event)); })("AfterDataLoad", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterDataLoad_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDataLoad($event)); });
|
|
80
|
+
i0.ɵɵlistener("AfterRowDoubleClick", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterRowDoubleClick_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRowDoubleClick($event)); })("AfterRowClick", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterRowClick_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onRowClick($event)); })("AfterDataLoad", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_AfterDataLoad_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onDataLoad($event)); })("NewRecordTabRequested", function ExplorerEntityDataGridComponent_Template_mj_entity_data_grid_NewRecordTabRequested_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNewRecordTabRequested($event)); });
|
|
68
81
|
i0.ɵɵelementEnd();
|
|
69
82
|
} if (rf & 2) {
|
|
70
83
|
i0.ɵɵproperty("Params", ctx.Params)("NewRecordValues", ctx.NewRecordValues)("AllowLoad", ctx.AllowLoad)("ShowToolbar", ctx.ShowToolbar)("Height", ctx.Height)("ToolbarConfig", ctx.ToolbarConfig)("SelectionMode", ctx.SelectionMode);
|
|
@@ -84,7 +97,8 @@ export class ExplorerEntityDataGridComponent {
|
|
|
84
97
|
[SelectionMode]="SelectionMode"
|
|
85
98
|
(AfterRowDoubleClick)="onRowDoubleClick($event)"
|
|
86
99
|
(AfterRowClick)="onRowClick($event)"
|
|
87
|
-
(AfterDataLoad)="onDataLoad($event)"
|
|
100
|
+
(AfterDataLoad)="onDataLoad($event)"
|
|
101
|
+
(NewRecordTabRequested)="onNewRecordTabRequested($event)">
|
|
88
102
|
</mj-entity-data-grid>
|
|
89
103
|
`, styles: ["\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n "] }]
|
|
90
104
|
}], null, { innerGrid: [{
|
|
@@ -115,5 +129,5 @@ export class ExplorerEntityDataGridComponent {
|
|
|
115
129
|
}], Navigate: [{
|
|
116
130
|
type: Output
|
|
117
131
|
}] }); })();
|
|
118
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExplorerEntityDataGridComponent, { className: "ExplorerEntityDataGridComponent", filePath: "src/lib/explorer-entity-data-grid.component.ts", lineNumber:
|
|
132
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ExplorerEntityDataGridComponent, { className: "ExplorerEntityDataGridComponent", filePath: "src/lib/explorer-entity-data-grid.component.ts", lineNumber: 48 }); })();
|
|
119
133
|
//# sourceMappingURL=explorer-entity-data-grid.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer-entity-data-grid.component.js","sourceRoot":"","sources":["../../src/lib/explorer-entity-data-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAOH,iBAAiB,EACpB,MAAM,kCAAkC,CAAC;;;;
|
|
1
|
+
{"version":3,"file":"explorer-entity-data-grid.component.js","sourceRoot":"","sources":["../../src/lib/explorer-entity-data-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAOH,iBAAiB,EACpB,MAAM,kCAAkC,CAAC;;;;AAI1C;;;;;GAKG;AA4BH,MAAM,OAAO,+BAA+B;IAChB,SAAS,CAA2B;IAE5D,mDAAmD;IAC1C,MAAM,GAAyB,IAAI,CAAC;IACpC,eAAe,GAA4B,EAAE,CAAC;IAC9C,SAAS,GAAY,IAAI,CAAC;IAC1B,WAAW,GAAY,IAAI,CAAC;IAC5B,MAAM,GAAoC,MAAM,CAAC;IACjD,aAAa,GAAsB,EAAE,CAAC;IACtC,aAAa,GAAsB,QAAQ,CAAC;IAErD;;;OAGG;IACM,qBAAqB,GAAY,IAAI,CAAC;IAE/C,6CAA6C;IACnC,mBAAmB,GAAG,IAAI,YAAY,EAAgC,CAAC;IACvE,aAAa,GAAG,IAAI,YAAY,EAA0B,CAAC;IAC3D,aAAa,GAAG,IAAI,YAAY,EAA0B,CAAC;IAErE,6EAA6E;IACnE,QAAQ,GAAG,IAAI,YAAY,EAAuB,CAAC;IAE7D,gBAAgB,CAAC,KAAmC;QAChD,sCAAsC;QACtC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAErC,mCAAmC;QACnC,IAAI,IAAI,CAAC,qBAAqB,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1C,yFAAyF;YACzF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;YAC9C,IAAI,CAAC,UAAU;gBAAE,OAAO;YAExB,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAEtD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,UAAU,CAAC,IAAI;gBAC3B,UAAU,EAAE,IAAI;aACnB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,UAAU,CAAC,KAA6B;QACpC,sCAAsC;QACtC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,KAA6B;QACpC,sCAAsC;QACtC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,uBAAuB,CAAC,KAAyE;QAC7F,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,YAAY;YAClB,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI;YACjC,aAAa,EAAE,KAAK,CAAC,aAAa;SACrC,CAAC,CAAC;IACP,CAAC;yHApEQ,+BAA+B;6DAA/B,+BAA+B;;;;;;;YAvBpC,iDAY8D;YAA1D,AADA,AADA,AADA,iMAAuB,4BAAwB,KAAC,wKAC/B,sBAAkB,KAAC,wKACnB,sBAAkB,KAAC,wLACX,mCAA+B,KAAC;YAC7D,iBAAsB;;YALlB,AADA,AADA,AADA,AADA,AADA,AADA,mCAAiB,wCACkB,4BACZ,gCACI,sBACV,oCACc,oCACA;;;iFAe9B,+BAA+B;cA3B3C,SAAS;6BACI,KAAK,YACL,8BAA8B,YAC9B;;;;;;;;;;;;;;;KAeT;;kBAUA,SAAS;mBAAC,WAAW;;kBAGrB,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAML,KAAK;;kBAGL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBAGN,MAAM;;kFAxBE,+BAA+B","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\nimport { RunViewParams } from '@memberjunction/core';\nimport {\n EntityDataGridComponent,\n AfterRowDoubleClickEventArgs,\n AfterRowClickEventArgs,\n AfterDataLoadEventArgs,\n GridToolbarConfig,\n GridSelectionMode,\n buildCompositeKey\n} from '@memberjunction/ng-entity-viewer';\nimport { EntityInfo } from '@memberjunction/core';\nimport { FormNavigationEvent } from './types/navigation-events';\n\n/**\n * Wrapper for EntityDataGridComponent that emits navigation events on row double-click.\n * The host application subscribes to Navigate events and maps them to its routing system.\n *\n * This component is used by CodeGen for related entity grids in forms.\n */\n@Component({\n standalone: false,\n selector: 'mj-explorer-entity-data-grid',\n template: `\n <mj-entity-data-grid\n #innerGrid\n [Params]=\"Params\"\n [NewRecordValues]=\"NewRecordValues\"\n [AllowLoad]=\"AllowLoad\"\n [ShowToolbar]=\"ShowToolbar\"\n [Height]=\"Height\"\n [ToolbarConfig]=\"ToolbarConfig\"\n [SelectionMode]=\"SelectionMode\"\n (AfterRowDoubleClick)=\"onRowDoubleClick($event)\"\n (AfterRowClick)=\"onRowClick($event)\"\n (AfterDataLoad)=\"onDataLoad($event)\"\n (NewRecordTabRequested)=\"onNewRecordTabRequested($event)\">\n </mj-entity-data-grid>\n `,\n styles: [`\n :host {\n display: block;\n height: 100%;\n width: 100%;\n }\n `]\n})\nexport class ExplorerEntityDataGridComponent {\n @ViewChild('innerGrid') innerGrid!: EntityDataGridComponent;\n\n // Pass-through inputs from EntityDataGridComponent\n @Input() Params: RunViewParams | null = null;\n @Input() NewRecordValues: Record<string, unknown> = {};\n @Input() AllowLoad: boolean = true;\n @Input() ShowToolbar: boolean = true;\n @Input() Height: number | 'auto' | 'fit-content' = 'auto';\n @Input() ToolbarConfig: GridToolbarConfig = {};\n @Input() SelectionMode: GridSelectionMode = 'single';\n\n /**\n * When true, double-clicking a row emits a Navigate event.\n * Defaults to true.\n */\n @Input() NavigateOnDoubleClick: boolean = true;\n\n // Re-emit events for consumers who need them\n @Output() AfterRowDoubleClick = new EventEmitter<AfterRowDoubleClickEventArgs>();\n @Output() AfterRowClick = new EventEmitter<AfterRowClickEventArgs>();\n @Output() AfterDataLoad = new EventEmitter<AfterDataLoadEventArgs>();\n\n /** Emitted when a row is double-clicked and NavigateOnDoubleClick is true */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n onRowDoubleClick(event: AfterRowDoubleClickEventArgs): void {\n // Re-emit the event for any consumers\n this.AfterRowDoubleClick.emit(event);\n\n // Emit navigation event if enabled\n if (this.NavigateOnDoubleClick && event.row) {\n // Use the inner grid's resolved EntityInfo - works for both ViewID and EntityName params\n const entityInfo = this.innerGrid?.EntityInfo;\n if (!entityInfo) return;\n\n const pkey = buildCompositeKey(event.row, entityInfo);\n\n this.Navigate.emit({\n Kind: 'record',\n EntityName: entityInfo.Name,\n PrimaryKey: pkey\n });\n }\n }\n\n onRowClick(event: AfterRowClickEventArgs): void {\n // Re-emit the event for any consumers\n this.AfterRowClick.emit(event);\n }\n\n onDataLoad(event: AfterDataLoadEventArgs): void {\n // Re-emit the event for any consumers\n this.AfterDataLoad.emit(event);\n }\n\n /**\n * The inner grid's \"New\" button bubbles up here. We re-emit as a\n * `new-record` Navigate event so the host form (and Explorer's\n * SingleRecordComponent) can call NavigationService.OpenNewEntityRecord\n * and pre-populate the foreign-key fields from NewRecordValues.\n */\n onNewRecordTabRequested(event: { entityInfo: EntityInfo; defaultValues: Record<string, unknown> }): void {\n this.Navigate.emit({\n Kind: 'new-record',\n EntityName: event.entityInfo.Name,\n DefaultValues: event.defaultValues,\n });\n }\n}\n"]}
|
|
@@ -92,7 +92,7 @@ export declare class MjFormFieldComponent extends BaseAngularComponent implement
|
|
|
92
92
|
get FieldInfo(): EntityFieldInfo | undefined;
|
|
93
93
|
/** Display name from metadata or override */
|
|
94
94
|
get DisplayName(): string;
|
|
95
|
-
/** Display name with search highlighting applied */
|
|
95
|
+
/** Display name with search highlighting applied. Output is bound to `[innerHTML]`. */
|
|
96
96
|
get HighlightedDisplayName(): string;
|
|
97
97
|
/** Current field value */
|
|
98
98
|
get Value(): unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.component.d.ts","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAsD,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAChK,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"form-field.component.d.ts","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
|
|
2
2
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
3
3
|
import { CompositeKey, KeyValuePair, RunView } from '@memberjunction/core';
|
|
4
|
+
import { HighlightSearchMatches } from '@memberjunction/global';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
import * as i1 from "@angular/common";
|
|
6
7
|
const _forTrack0 = ($index, $item) => $item.PrimaryKeyValue;
|
|
@@ -495,14 +496,9 @@ export class MjFormFieldComponent extends BaseAngularComponent {
|
|
|
495
496
|
}
|
|
496
497
|
return this.FieldInfo?.DisplayNameOrName ?? this.FieldName;
|
|
497
498
|
}
|
|
498
|
-
/** Display name with search highlighting applied */
|
|
499
|
+
/** Display name with search highlighting applied. Output is bound to `[innerHTML]`. */
|
|
499
500
|
get HighlightedDisplayName() {
|
|
500
|
-
|
|
501
|
-
if (!filter)
|
|
502
|
-
return this.DisplayName;
|
|
503
|
-
const escaped = filter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
504
|
-
const regex = new RegExp(escaped, 'gi');
|
|
505
|
-
return this.DisplayName.replace(regex, '<mark class="mj-forms-search-highlight">$&</mark>');
|
|
501
|
+
return HighlightSearchMatches(this.DisplayName, this.FormContext?.sectionFilter ?? '', 'mj-forms-search-highlight');
|
|
506
502
|
}
|
|
507
503
|
/** Current field value */
|
|
508
504
|
get Value() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.component.js","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts","../../../src/lib/field/form-field.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { BaseEntity, EntityFieldInfo, Metadata, CompositeKey, KeyValuePair, RunView } from '@memberjunction/core';\nimport { ValidationErrorInfo } from '@memberjunction/global';\nimport { FormContext } from '../types/form-types';\nimport { FormNavigationEvent } from '../types/navigation-events';\n\n/**\n * Represents a suggestion item for FK autocomplete search results.\n */\nexport interface FKSuggestion {\n PrimaryKeyValue: unknown;\n DisplayName: string;\n}\n\n/**\n * Modern form field component that renders entity fields in both read-only and edit modes.\n *\n * **Read mode**: Clean text display with optional hyperlinks (email, URL, record).\n * **Edit mode**: Native HTML inputs with custom-built select and autocomplete components.\n *\n * Uses:\n * - Native `<input>` for text, number, date\n * - Custom styled dropdown for value list selections\n * - Custom autocomplete with floating dropdown for foreign key search\n * - Custom-styled `<input type=\"checkbox\">` for booleans\n *\n * All navigation (clicking FK links, email links, URL links) is emitted as events.\n *\n * @example\n * ```html\n * <mj-form-field\n * [Record]=\"record\"\n * [EditMode]=\"editMode\"\n * FieldName=\"CustomerName\"\n * Type=\"textbox\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\"\n * (ValueChange)=\"onValueChange($event)\">\n * </mj-form-field>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-form-field',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './form-field.component.html',\n styleUrls: ['./form-field.component.css']\n})\nexport class MjFormFieldComponent extends BaseAngularComponent implements OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /** The entity record containing this field */\n @Input() Record!: BaseEntity;\n\n /** Whether the form is in edit mode */\n @Input() EditMode = false;\n\n /** The field code name (must match a field on the entity) */\n @Input() FieldName = '';\n\n /**\n * The control type to render in edit mode.\n * Determines which input component is used.\n *\n * Also accepts deprecated Kendo-style type names for backward compatibility:\n * - `'dropdownlist'` → `'select'`\n * - `'numerictextbox'` → `'number'`\n */\n @Input()\n set Type(value: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' | 'dropdownlist' | 'numerictextbox') {\n // Normalize deprecated Kendo type names to modern equivalents\n switch (value) {\n case 'dropdownlist': this._type = 'select'; break;\n case 'numerictextbox': this._type = 'number'; break;\n default: this._type = value; break;\n }\n }\n get Type(): 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' {\n return this._type;\n }\n private _type: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' = 'textbox';\n\n /**\n * Link type for read-only rendering.\n * - 'Email': renders as mailto link\n * - 'URL': renders as external hyperlink\n * - 'Record': renders as FK link to related entity record\n * - 'None': renders as plain text\n */\n @Input() LinkType: 'Email' | 'URL' | 'Record' | 'None' = 'None';\n\n /** Whether to show the field label */\n @Input() ShowLabel = true;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [Record] instead */\n @Input('record') set _deprecatedRecord(value: BaseEntity) { this.Record = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n /** Whether to hide this field when empty in read-only mode. Default: true */\n @Input() HideWhenEmptyInReadOnlyMode = true;\n\n /** Override display name (defaults to entity field metadata DisplayName) */\n @Input() DisplayNameOverride = '';\n\n /** Override possible values for select/autocomplete */\n @Input() PossibleValuesOverride: string[] | null = null;\n\n /** Emitted when the field value changes */\n @Output() ValueChange = new EventEmitter<{ FieldName: string; OldValue: unknown; NewValue: unknown }>();\n\n /** Emitted when a navigation action is triggered (FK link click, email click, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Computed Properties ----\n\n /** Get EntityFieldInfo metadata for this field */\n get FieldInfo(): EntityFieldInfo | undefined {\n return this.Record?.EntityInfo?.Fields?.find(f => f.Name === this.FieldName);\n }\n\n /** Display name from metadata or override */\n get DisplayName(): string {\n if (this.DisplayNameOverride) return this.DisplayNameOverride;\n\n // Friendly labels for standard MJ timestamp fields\n if (this.FieldName === '__mj_CreatedAt') return 'Created';\n if (this.FieldName === '__mj_UpdatedAt') return 'Updated';\n\n // For FK fields that have a mapped name field, use the name field's\n // friendly label (e.g., show \"Parent\" instead of \"Parent ID\")\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const nameField = this.Record?.EntityInfo?.Fields?.find(f => f.Name === nameFieldMap);\n if (nameField) {\n return nameField.DisplayNameOrName;\n }\n }\n\n return this.FieldInfo?.DisplayNameOrName ?? this.FieldName;\n }\n\n /** Display name with search highlighting applied */\n get HighlightedDisplayName(): string {\n const filter = this.FormContext?.sectionFilter?.trim();\n if (!filter) return this.DisplayName;\n\n const escaped = filter.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(escaped, 'gi');\n return this.DisplayName.replace(regex, '<mark class=\"mj-forms-search-highlight\">$&</mark>');\n }\n\n /** Current field value */\n get Value(): unknown {\n return this.Record?.Get(this.FieldName);\n }\n\n /** Set field value, mark touched, run validation, and emit change event */\n set Value(newValue: unknown) {\n if (!this.Record) return;\n const oldValue = this.Record.Get(this.FieldName);\n this.Record.Set(this.FieldName, newValue);\n this._touched = true;\n this.runFieldValidation();\n this.ValueChange.emit({ FieldName: this.FieldName, OldValue: oldValue, NewValue: newValue });\n }\n\n /** Whether this field is read-only based on entity metadata */\n get IsFieldReadOnly(): boolean {\n if (!this.FieldInfo) return false;\n return this.FieldInfo.ReadOnly;\n }\n\n /** Whether this field has been modified (dirty). Only shown for saved records (not new). */\n get IsDirty(): boolean {\n if (!this.Record || !this.Record.IsSaved) return false;\n const field = this.Record.Fields?.find(f => f.Name === this.FieldName);\n return field?.Dirty ?? false;\n }\n\n /** Whether this field is required (not nullable) */\n get IsRequired(): boolean {\n return this.FieldInfo?.AllowsNull === false;\n }\n\n /** Whether this is a required field that is currently empty (for validation styling) */\n get IsRequiredEmpty(): boolean {\n // Defer to the validation system when it has active errors for this field\n if (this.ShowErrors) return false;\n if (!this.IsRequired || !this.EditMode) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n // ---- INLINE VALIDATION ----\n\n /** Whether the user has interacted with (changed) this field */\n private _touched = false;\n\n /** Locally computed validation errors for this field */\n private _fieldErrors: ValidationErrorInfo[] = [];\n\n /** Validation errors for this field from the best available source */\n get FieldErrors(): ValidationErrorInfo[] {\n // If touched, use fresh local validation (covers real-time feedback)\n if (this._touched) {\n return this._fieldErrors;\n }\n // Otherwise use form-level errors from save failure (covers untouched fields)\n const contextErrors = this.FormContext?.validationErrors;\n if (contextErrors && contextErrors.length > 0) {\n return contextErrors.filter(e => e.Source === this.FieldName);\n }\n return [];\n }\n\n /** Whether to show validation messages (touched OR form-level showValidation) */\n get ShowValidation(): boolean {\n if (!this.EditMode || this.IsFieldReadOnly) return false;\n return this._touched || (this.FormContext?.showValidation === true);\n }\n\n /** Whether this field has active error-level validation failures to display */\n get ShowErrors(): boolean {\n return this.ShowValidation && this.FieldErrors.some(e => e.Type === 'Failure');\n }\n\n /** Whether this field has active warning-level validation issues to display */\n get ShowWarnings(): boolean {\n return this.ShowValidation && !this.ShowErrors && this.FieldErrors.some(e => e.Type === 'Warning');\n }\n\n /** Error messages to render in the template */\n get DisplayErrors(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Failure');\n }\n\n /** Warning messages to render in the template */\n get DisplayWarnings(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Warning');\n }\n\n /**\n * Runs validation for this field using the full Record.Validate() method.\n * This captures both built-in field checks and custom Validate() overrides\n * (including cross-field rules). Results are filtered to this field only.\n */\n private runFieldValidation(): void {\n if (!this.Record || !this.EditMode) {\n this._fieldErrors = [];\n return;\n }\n try {\n const result = this.Record.Validate();\n this._fieldErrors = result.Errors.filter(e => e.Source === this.FieldName);\n } catch {\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n\n /** Whether this field should be hidden (empty in read-only mode) */\n get ShouldHideField(): boolean {\n if (this.EditMode) return false;\n if (!this.HideWhenEmptyInReadOnlyMode) return false;\n if (this.FormContext?.showEmptyFields) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n /** Possible values for select/autocomplete from entity metadata or override */\n get PossibleValues(): string[] {\n if (this.PossibleValuesOverride) return this.PossibleValuesOverride;\n const values = this.FieldInfo?.EntityFieldValues;\n if (values && values.length > 0) {\n return values.map(v => v.Value);\n }\n return [];\n }\n\n /** Whether this field has a related entity (foreign key) */\n get HasRelatedEntity(): boolean {\n const re = this.FieldInfo?.RelatedEntity;\n return re != null && re.length > 0;\n }\n\n /**\n * For FK fields, returns the human-readable name to display instead of the raw ID.\n *\n * Resolution order:\n * 1. If `RelatedEntityNameFieldMap` exists, read the name from the joined field on the record (sync).\n * 2. Otherwise, fall back to an async `GetEntityRecordName` lookup (result cached in `_resolvedFKName`).\n */\n get FKDisplayName(): string | null {\n if (!this.Record || !this.HasRelatedEntity) return null;\n\n // If the FK value itself is null/empty, there's nothing to display\n // (the joined name field may still hold a stale cached value from the view)\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return null;\n\n // Fast path: name field is joined into our record's view\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const val = this.Record.Get(nameFieldMap);\n if (val != null && val !== '') return String(val);\n }\n\n // Async fallback: resolved via GetEntityRecordName\n if (this._resolvedFKName !== undefined) {\n return this._resolvedFKName;\n }\n\n // Kick off async resolution if not already in flight\n this.resolveFKNameAsync();\n return null; // will render once resolved\n }\n\n /**\n * Whether this FK field should display the related entity name\n * with a hyperlink instead of the raw ID value.\n */\n get IsFKWithNameField(): boolean {\n return this.HasRelatedEntity && this.FKDisplayName != null;\n }\n\n // ---- Async FK name resolution ----\n\n /** Cached result from GetEntityRecordName. undefined = not yet resolved. */\n private _resolvedFKName: string | null | undefined = undefined;\n\n /** Tracks which FK value we resolved so we can invalidate on record change */\n private _resolvedFKValue: unknown = undefined;\n\n /** Whether an async lookup is in flight */\n private _fkNameLoading = false;\n\n /**\n * Asynchronously resolves the display name for an FK field that lacks\n * a RelatedEntityNameFieldMap by calling Metadata.GetEntityRecordName.\n */\n private resolveFKNameAsync(): void {\n if (this._fkNameLoading) return;\n\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return;\n\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity || !fieldInfo?.RelatedEntityFieldName) return;\n\n this._fkNameLoading = true;\n this._resolvedFKValue = fkValue;\n\n const pk = new CompositeKey([{\n FieldName: fieldInfo.RelatedEntityFieldName,\n Value: fkValue\n }]);\n\n const md = this.ProviderToUse;\n md.GetEntityRecordName(fieldInfo.RelatedEntity, pk)\n .then(name => {\n this._resolvedFKName = name || null;\n this._fkNameLoading = false;\n this.cdr.markForCheck();\n })\n .catch(() => {\n this._resolvedFKName = null;\n this._fkNameLoading = false;\n });\n }\n\n // ============================================\n // DROPDOWN POSITIONING (shared by FK, value list, select)\n // ============================================\n\n /** Calculated position for fixed-position dropdowns */\n DropdownTop = 0;\n DropdownLeft = 0;\n DropdownWidth = 0;\n OpenAbove = false;\n\n /** Cleanup function for scroll/resize listeners */\n private _scrollCleanup: (() => void) | null = null;\n\n /** Inline style for the fixed-position dropdown */\n get DropdownPositionStyle(): Record<string, string> {\n if (this.OpenAbove) {\n return {\n 'position': 'fixed',\n 'bottom': (window.innerHeight - this.DropdownTop) + 'px',\n 'top': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n return {\n 'position': 'fixed',\n 'top': this.DropdownTop + 'px',\n 'bottom': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n\n /** Calculate dropdown position relative to viewport from anchor element */\n private updateDropdownPosition(anchorEl: HTMLElement): void {\n const rect = anchorEl.getBoundingClientRect();\n const dropdownMaxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n if (spaceBelow < dropdownMaxHeight && spaceAbove > spaceBelow) {\n this.OpenAbove = true;\n this.DropdownTop = rect.top - gap;\n } else {\n this.OpenAbove = false;\n this.DropdownTop = rect.bottom + gap;\n }\n this.DropdownLeft = rect.left;\n this.DropdownWidth = rect.width;\n }\n\n /** Start listening for scroll/resize to close dropdowns */\n private startScrollListener(): void {\n this.stopScrollListener();\n\n const onScroll = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n const onResize = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n\n document.addEventListener('scroll', onScroll, true); // capture phase catches all scrollable ancestors\n window.addEventListener('resize', onResize);\n\n this._scrollCleanup = () => {\n document.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onResize);\n };\n }\n\n /** Remove scroll/resize listeners */\n private stopScrollListener(): void {\n if (this._scrollCleanup) {\n this._scrollCleanup();\n this._scrollCleanup = null;\n }\n }\n\n /** Close all dropdown types */\n private closeAllDropdowns(): void {\n this.ShowFKDropdown = false;\n this.ShowValueListDropdown = false;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n }\n\n // ============================================\n // FK AUTOCOMPLETE (custom implementation)\n // ============================================\n\n /** Suggestions returned from the FK entity search */\n FKSuggestions: FKSuggestion[] = [];\n\n /** Whether the current FK value is a confirmed match (user selected from dropdown) */\n FKIsMatched = false;\n\n /** Whether the FK dropdown is visible */\n ShowFKDropdown = false;\n\n /** Text the user is currently typing in the FK search input. null = use display name. */\n private _fkInputText: string | null = null;\n\n /** Debounce timer for FK search */\n private _fkSearchTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Last known FK input element for position recalculation */\n private _lastFKInputEl: HTMLElement | null = null;\n\n /** The display text shown in the FK search input */\n get FKSearchText(): string {\n if (this._fkInputText !== null) return this._fkInputText;\n return this.FKDisplayName || '';\n }\n\n /** Handle typing in the FK search input */\n OnFKInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._fkInputText = input.value;\n this._lastFKInputEl = input;\n this.FKIsMatched = false;\n\n // Debounce search\n if (this._fkSearchTimeout) clearTimeout(this._fkSearchTimeout);\n this._fkSearchTimeout = setTimeout(() => {\n if (this._fkInputText && this._fkInputText.length >= 1) {\n this.searchRelatedEntity(this._fkInputText);\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n }, 300);\n }\n\n /** Show dropdown on focus if suggestions exist */\n OnFKFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this._lastFKInputEl = input;\n if (this.FKSuggestions.length > 0) {\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowFKDropdown = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Hide dropdown on blur, revert to matched name if user didn't select */\n OnFKBlur(): void {\n // Small delay so mousedown on dropdown items fires first\n setTimeout(() => {\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n // If user was typing but didn't select, revert to display name\n if (!this.FKIsMatched && this._fkInputText !== null) {\n this._fkInputText = null;\n }\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the FK dropdown */\n OnFKSelectItem(suggestion: FKSuggestion, event: MouseEvent): void {\n event.preventDefault();\n this._fkInputText = suggestion.DisplayName;\n this.Value = suggestion.PrimaryKeyValue;\n this.FKIsMatched = true;\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n\n // Update virtual name field for visual consistency after save\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, suggestion.DisplayName);\n }\n this.cdr.markForCheck();\n }\n\n /** Clear FK value via the X button */\n OnFKClearClick(event: MouseEvent): void {\n event.preventDefault();\n this.Value = null;\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, '');\n }\n this.cdr.markForCheck();\n }\n\n /**\n * Perform a RunView search on the related entity's name field.\n * Falls back to searching by primary key when no NameField exists (single-field PKs only).\n */\n private async searchRelatedEntity(query: string): Promise<void> {\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity) return;\n\n const md = this.ProviderToUse;\n const relatedEntity = md.Entities.find(e => e.Name === fieldInfo.RelatedEntity);\n if (!relatedEntity) return;\n\n const nameField = relatedEntity.NameField;\n const pkFields = relatedEntity.PrimaryKeys;\n\n // If no NameField, fall back to PK — but only for single-field PKs\n if (!nameField) {\n if (!pkFields || pkFields.length !== 1) return;\n }\n\n const nameFieldName = nameField ? nameField.Name : pkFields[0].Name;\n const pkFieldName = fieldInfo.RelatedEntityFieldName || 'ID';\n\n // Build Fields array, avoiding duplicates when nameField IS the PK\n const fields = nameFieldName === pkFieldName\n ? [pkFieldName]\n : [pkFieldName, nameFieldName];\n\n const escapedQuery = query.replace(/'/g, \"''\");\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: fieldInfo.RelatedEntity,\n ExtraFilter: `[${nameFieldName}] LIKE '%${escapedQuery}%'`,\n MaxRows: 20,\n ResultType: 'simple',\n Fields: fields\n });\n\n if (result.Success) {\n this.FKSuggestions = result.Results.map(r => ({\n PrimaryKeyValue: r[pkFieldName],\n DisplayName: String(r[nameFieldName] || '')\n }));\n if (this.FKSuggestions.length > 0 && this._lastFKInputEl) {\n this.updateDropdownPosition(this._lastFKInputEl);\n this.startScrollListener();\n }\n this.ShowFKDropdown = this.FKSuggestions.length > 0;\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n }\n this.cdr.markForCheck();\n }\n\n // ============================================\n // VALUE LIST AUTOCOMPLETE (for 'autocomplete' type)\n // ============================================\n\n /** Whether the value list dropdown is visible */\n ShowValueListDropdown = false;\n\n /** Current filter text for the value list */\n private _valueListFilter = '';\n\n /** Filtered possible values based on what the user typed */\n get FilteredPossibleValues(): string[] {\n if (!this._valueListFilter) return this.PossibleValues;\n const filter = this._valueListFilter.toLowerCase();\n return this.PossibleValues.filter(v => v.toLowerCase().includes(filter));\n }\n\n /** Handle typing in the value list autocomplete */\n OnValueListInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._valueListFilter = input.value;\n this.Value = input.value;\n this.updateDropdownPosition(input);\n if (!this._scrollCleanup) this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Show dropdown on focus */\n OnValueListFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Hide dropdown on blur */\n OnValueListBlur(): void {\n setTimeout(() => {\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the value list dropdown */\n OnValueListSelect(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this._valueListFilter = '';\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // CUSTOM SELECT DROPDOWN (replaces native <select>)\n // ============================================\n\n /** Whether the custom select dropdown is visible */\n ShowSelectDropdown = false;\n\n /** Toggle the custom select dropdown */\n OnSelectTriggerClick(event: Event): void {\n event.preventDefault();\n if (this.ShowSelectDropdown) {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n } else {\n const el = event.currentTarget as HTMLElement;\n this.updateDropdownPosition(el);\n this.startScrollListener();\n this.ShowSelectDropdown = true;\n }\n this.cdr.markForCheck();\n }\n\n /** Close the select dropdown on blur */\n OnSelectTriggerBlur(): void {\n setTimeout(() => {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an option from the custom select dropdown */\n OnSelectOptionClick(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // GENERAL PROPERTIES\n // ============================================\n\n /** Whether the field's varchar(max) - long text that gets markdown rendering */\n get IsLongText(): boolean {\n return this.FieldInfo?.Length === -1;\n }\n\n /** Format a value for display */\n FormatValue(): string {\n const val = this.Value;\n if (val === null || val === undefined) return '';\n if (val instanceof Date) {\n return val.toLocaleString();\n }\n return String(val);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['FormContext'] || changes['EditMode'] || changes['Record']) {\n // Reset FK state when record changes\n if (changes['Record']) {\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n this._fkNameLoading = false;\n // Reset validation state for new record\n this._touched = false;\n this._fieldErrors = [];\n }\n // Reset validation state when exiting edit mode\n if (changes['EditMode'] && !this.EditMode) {\n this._touched = false;\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n }\n\n ngOnDestroy(): void {\n if (this._fkSearchTimeout) {\n clearTimeout(this._fkSearchTimeout);\n }\n this.stopScrollListener();\n }\n\n // ---- Navigation Handlers ----\n\n /**\n * Handle click on a record FK link in read-only mode.\n */\n OnRecordLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.FieldInfo || !this.Record) return;\n const relatedEntityName = this.FieldInfo.RelatedEntity;\n if (!relatedEntityName) return;\n\n const fkValue = this.Value;\n if (!fkValue) return;\n\n // Build a CompositeKey for the FK target record using the related entity's PK field\n const relatedFieldName = this.FieldInfo.RelatedEntityFieldName || 'ID';\n const targetKey = new CompositeKey([new KeyValuePair(relatedFieldName, fkValue)]);\n\n this.Navigate.emit({\n Kind: 'record',\n EntityName: relatedEntityName,\n PrimaryKey: targetKey,\n OpenInNewTab: event.ctrlKey || event.metaKey\n });\n }\n\n /**\n * Handle click on an email link in read-only mode.\n */\n OnEmailLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const email = this.FormatValue();\n if (!email) return;\n this.Navigate.emit({\n Kind: 'email',\n EmailAddress: email\n });\n }\n\n /**\n * Handle click on a URL link in read-only mode.\n */\n OnUrlLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const url = this.FormatValue();\n if (!url) return;\n this.Navigate.emit({\n Kind: 'external-link',\n Url: url,\n OpenInNewTab: true\n });\n }\n\n /**\n * Handle value change from a native input.\n */\n OnInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value;\n }\n\n /**\n * Handle value change from a number input.\n */\n OnNumberChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const num = input.valueAsNumber;\n this.Value = isNaN(num) ? null : num;\n }\n\n /**\n * Handle value change from a date input.\n */\n OnDateChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value ? new Date(input.value) : null;\n }\n\n /**\n * Handle value change from a checkbox.\n */\n OnCheckboxChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.checked;\n }\n\n /**\n * Get date value formatted for HTML date input.\n */\n get DateInputValue(): string {\n const val = this.Value;\n if (!val) return '';\n const date = val instanceof Date ? val : new Date(String(val));\n if (isNaN(date.getTime())) return '';\n return date.toISOString().split('T')[0];\n }\n}\n","@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"form-field.component.js","sourceRoot":"","sources":["../../../src/lib/field/form-field.component.ts","../../../src/lib/field/form-field.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { BaseEntity, EntityFieldInfo, CompositeKey, KeyValuePair, RunView } from '@memberjunction/core';\nimport { ValidationErrorInfo, HighlightSearchMatches } from '@memberjunction/global';\nimport { FormContext } from '../types/form-types';\nimport { FormNavigationEvent } from '../types/navigation-events';\n\n/**\n * Represents a suggestion item for FK autocomplete search results.\n */\nexport interface FKSuggestion {\n PrimaryKeyValue: unknown;\n DisplayName: string;\n}\n\n/**\n * Modern form field component that renders entity fields in both read-only and edit modes.\n *\n * **Read mode**: Clean text display with optional hyperlinks (email, URL, record).\n * **Edit mode**: Native HTML inputs with custom-built select and autocomplete components.\n *\n * Uses:\n * - Native `<input>` for text, number, date\n * - Custom styled dropdown for value list selections\n * - Custom autocomplete with floating dropdown for foreign key search\n * - Custom-styled `<input type=\"checkbox\">` for booleans\n *\n * All navigation (clicking FK links, email links, URL links) is emitted as events.\n *\n * @example\n * ```html\n * <mj-form-field\n * [Record]=\"record\"\n * [EditMode]=\"editMode\"\n * FieldName=\"CustomerName\"\n * Type=\"textbox\"\n * [FormContext]=\"formContext\"\n * (Navigate)=\"onNavigate($event)\"\n * (ValueChange)=\"onValueChange($event)\">\n * </mj-form-field>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-form-field',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './form-field.component.html',\n styleUrls: ['./form-field.component.css']\n})\nexport class MjFormFieldComponent extends BaseAngularComponent implements OnChanges, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n /** The entity record containing this field */\n @Input() Record!: BaseEntity;\n\n /** Whether the form is in edit mode */\n @Input() EditMode = false;\n\n /** The field code name (must match a field on the entity) */\n @Input() FieldName = '';\n\n /**\n * The control type to render in edit mode.\n * Determines which input component is used.\n *\n * Also accepts deprecated Kendo-style type names for backward compatibility:\n * - `'dropdownlist'` → `'select'`\n * - `'numerictextbox'` → `'number'`\n */\n @Input()\n set Type(value: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' | 'dropdownlist' | 'numerictextbox') {\n // Normalize deprecated Kendo type names to modern equivalents\n switch (value) {\n case 'dropdownlist': this._type = 'select'; break;\n case 'numerictextbox': this._type = 'number'; break;\n default: this._type = value; break;\n }\n }\n get Type(): 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' {\n return this._type;\n }\n private _type: 'textbox' | 'textarea' | 'number' | 'datepicker' | 'checkbox' | 'select' | 'autocomplete' | 'code' = 'textbox';\n\n /**\n * Link type for read-only rendering.\n * - 'Email': renders as mailto link\n * - 'URL': renders as external hyperlink\n * - 'Record': renders as FK link to related entity record\n * - 'None': renders as plain text\n */\n @Input() LinkType: 'Email' | 'URL' | 'Record' | 'None' = 'None';\n\n /** Whether to show the field label */\n @Input() ShowLabel = true;\n\n /** Form-level context (search filter, showEmptyFields) */\n @Input() FormContext?: FormContext;\n\n // ---- Deprecated camelCase aliases (backward compat) ----\n\n /** @deprecated Use [Record] instead */\n @Input('record') set _deprecatedRecord(value: BaseEntity) { this.Record = value; }\n\n /** @deprecated Use [FormContext] instead */\n @Input('formContext') set _deprecatedFormContext(value: FormContext | undefined) { this.FormContext = value; }\n\n /** Whether to hide this field when empty in read-only mode. Default: true */\n @Input() HideWhenEmptyInReadOnlyMode = true;\n\n /** Override display name (defaults to entity field metadata DisplayName) */\n @Input() DisplayNameOverride = '';\n\n /** Override possible values for select/autocomplete */\n @Input() PossibleValuesOverride: string[] | null = null;\n\n /** Emitted when the field value changes */\n @Output() ValueChange = new EventEmitter<{ FieldName: string; OldValue: unknown; NewValue: unknown }>();\n\n /** Emitted when a navigation action is triggered (FK link click, email click, etc.) */\n @Output() Navigate = new EventEmitter<FormNavigationEvent>();\n\n // ---- Computed Properties ----\n\n /** Get EntityFieldInfo metadata for this field */\n get FieldInfo(): EntityFieldInfo | undefined {\n return this.Record?.EntityInfo?.Fields?.find(f => f.Name === this.FieldName);\n }\n\n /** Display name from metadata or override */\n get DisplayName(): string {\n if (this.DisplayNameOverride) return this.DisplayNameOverride;\n\n // Friendly labels for standard MJ timestamp fields\n if (this.FieldName === '__mj_CreatedAt') return 'Created';\n if (this.FieldName === '__mj_UpdatedAt') return 'Updated';\n\n // For FK fields that have a mapped name field, use the name field's\n // friendly label (e.g., show \"Parent\" instead of \"Parent ID\")\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const nameField = this.Record?.EntityInfo?.Fields?.find(f => f.Name === nameFieldMap);\n if (nameField) {\n return nameField.DisplayNameOrName;\n }\n }\n\n return this.FieldInfo?.DisplayNameOrName ?? this.FieldName;\n }\n\n /** Display name with search highlighting applied. Output is bound to `[innerHTML]`. */\n get HighlightedDisplayName(): string {\n return HighlightSearchMatches(this.DisplayName, this.FormContext?.sectionFilter ?? '', 'mj-forms-search-highlight');\n }\n\n /** Current field value */\n get Value(): unknown {\n return this.Record?.Get(this.FieldName);\n }\n\n /** Set field value, mark touched, run validation, and emit change event */\n set Value(newValue: unknown) {\n if (!this.Record) return;\n const oldValue = this.Record.Get(this.FieldName);\n this.Record.Set(this.FieldName, newValue);\n this._touched = true;\n this.runFieldValidation();\n this.ValueChange.emit({ FieldName: this.FieldName, OldValue: oldValue, NewValue: newValue });\n }\n\n /** Whether this field is read-only based on entity metadata */\n get IsFieldReadOnly(): boolean {\n if (!this.FieldInfo) return false;\n return this.FieldInfo.ReadOnly;\n }\n\n /** Whether this field has been modified (dirty). Only shown for saved records (not new). */\n get IsDirty(): boolean {\n if (!this.Record || !this.Record.IsSaved) return false;\n const field = this.Record.Fields?.find(f => f.Name === this.FieldName);\n return field?.Dirty ?? false;\n }\n\n /** Whether this field is required (not nullable) */\n get IsRequired(): boolean {\n return this.FieldInfo?.AllowsNull === false;\n }\n\n /** Whether this is a required field that is currently empty (for validation styling) */\n get IsRequiredEmpty(): boolean {\n // Defer to the validation system when it has active errors for this field\n if (this.ShowErrors) return false;\n if (!this.IsRequired || !this.EditMode) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n // ---- INLINE VALIDATION ----\n\n /** Whether the user has interacted with (changed) this field */\n private _touched = false;\n\n /** Locally computed validation errors for this field */\n private _fieldErrors: ValidationErrorInfo[] = [];\n\n /** Validation errors for this field from the best available source */\n get FieldErrors(): ValidationErrorInfo[] {\n // If touched, use fresh local validation (covers real-time feedback)\n if (this._touched) {\n return this._fieldErrors;\n }\n // Otherwise use form-level errors from save failure (covers untouched fields)\n const contextErrors = this.FormContext?.validationErrors;\n if (contextErrors && contextErrors.length > 0) {\n return contextErrors.filter(e => e.Source === this.FieldName);\n }\n return [];\n }\n\n /** Whether to show validation messages (touched OR form-level showValidation) */\n get ShowValidation(): boolean {\n if (!this.EditMode || this.IsFieldReadOnly) return false;\n return this._touched || (this.FormContext?.showValidation === true);\n }\n\n /** Whether this field has active error-level validation failures to display */\n get ShowErrors(): boolean {\n return this.ShowValidation && this.FieldErrors.some(e => e.Type === 'Failure');\n }\n\n /** Whether this field has active warning-level validation issues to display */\n get ShowWarnings(): boolean {\n return this.ShowValidation && !this.ShowErrors && this.FieldErrors.some(e => e.Type === 'Warning');\n }\n\n /** Error messages to render in the template */\n get DisplayErrors(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Failure');\n }\n\n /** Warning messages to render in the template */\n get DisplayWarnings(): ValidationErrorInfo[] {\n if (!this.ShowValidation) return [];\n return this.FieldErrors.filter(e => e.Type === 'Warning');\n }\n\n /**\n * Runs validation for this field using the full Record.Validate() method.\n * This captures both built-in field checks and custom Validate() overrides\n * (including cross-field rules). Results are filtered to this field only.\n */\n private runFieldValidation(): void {\n if (!this.Record || !this.EditMode) {\n this._fieldErrors = [];\n return;\n }\n try {\n const result = this.Record.Validate();\n this._fieldErrors = result.Errors.filter(e => e.Source === this.FieldName);\n } catch {\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n\n /** Whether this field should be hidden (empty in read-only mode) */\n get ShouldHideField(): boolean {\n if (this.EditMode) return false;\n if (!this.HideWhenEmptyInReadOnlyMode) return false;\n if (this.FormContext?.showEmptyFields) return false;\n const val = this.Value;\n return val === null || val === undefined || val === '';\n }\n\n /** Possible values for select/autocomplete from entity metadata or override */\n get PossibleValues(): string[] {\n if (this.PossibleValuesOverride) return this.PossibleValuesOverride;\n const values = this.FieldInfo?.EntityFieldValues;\n if (values && values.length > 0) {\n return values.map(v => v.Value);\n }\n return [];\n }\n\n /** Whether this field has a related entity (foreign key) */\n get HasRelatedEntity(): boolean {\n const re = this.FieldInfo?.RelatedEntity;\n return re != null && re.length > 0;\n }\n\n /**\n * For FK fields, returns the human-readable name to display instead of the raw ID.\n *\n * Resolution order:\n * 1. If `RelatedEntityNameFieldMap` exists, read the name from the joined field on the record (sync).\n * 2. Otherwise, fall back to an async `GetEntityRecordName` lookup (result cached in `_resolvedFKName`).\n */\n get FKDisplayName(): string | null {\n if (!this.Record || !this.HasRelatedEntity) return null;\n\n // If the FK value itself is null/empty, there's nothing to display\n // (the joined name field may still hold a stale cached value from the view)\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return null;\n\n // Fast path: name field is joined into our record's view\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n const val = this.Record.Get(nameFieldMap);\n if (val != null && val !== '') return String(val);\n }\n\n // Async fallback: resolved via GetEntityRecordName\n if (this._resolvedFKName !== undefined) {\n return this._resolvedFKName;\n }\n\n // Kick off async resolution if not already in flight\n this.resolveFKNameAsync();\n return null; // will render once resolved\n }\n\n /**\n * Whether this FK field should display the related entity name\n * with a hyperlink instead of the raw ID value.\n */\n get IsFKWithNameField(): boolean {\n return this.HasRelatedEntity && this.FKDisplayName != null;\n }\n\n // ---- Async FK name resolution ----\n\n /** Cached result from GetEntityRecordName. undefined = not yet resolved. */\n private _resolvedFKName: string | null | undefined = undefined;\n\n /** Tracks which FK value we resolved so we can invalidate on record change */\n private _resolvedFKValue: unknown = undefined;\n\n /** Whether an async lookup is in flight */\n private _fkNameLoading = false;\n\n /**\n * Asynchronously resolves the display name for an FK field that lacks\n * a RelatedEntityNameFieldMap by calling Metadata.GetEntityRecordName.\n */\n private resolveFKNameAsync(): void {\n if (this._fkNameLoading) return;\n\n const fkValue = this.Value;\n if (fkValue == null || fkValue === '') return;\n\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity || !fieldInfo?.RelatedEntityFieldName) return;\n\n this._fkNameLoading = true;\n this._resolvedFKValue = fkValue;\n\n const pk = new CompositeKey([{\n FieldName: fieldInfo.RelatedEntityFieldName,\n Value: fkValue\n }]);\n\n const md = this.ProviderToUse;\n md.GetEntityRecordName(fieldInfo.RelatedEntity, pk)\n .then(name => {\n this._resolvedFKName = name || null;\n this._fkNameLoading = false;\n this.cdr.markForCheck();\n })\n .catch(() => {\n this._resolvedFKName = null;\n this._fkNameLoading = false;\n });\n }\n\n // ============================================\n // DROPDOWN POSITIONING (shared by FK, value list, select)\n // ============================================\n\n /** Calculated position for fixed-position dropdowns */\n DropdownTop = 0;\n DropdownLeft = 0;\n DropdownWidth = 0;\n OpenAbove = false;\n\n /** Cleanup function for scroll/resize listeners */\n private _scrollCleanup: (() => void) | null = null;\n\n /** Inline style for the fixed-position dropdown */\n get DropdownPositionStyle(): Record<string, string> {\n if (this.OpenAbove) {\n return {\n 'position': 'fixed',\n 'bottom': (window.innerHeight - this.DropdownTop) + 'px',\n 'top': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n return {\n 'position': 'fixed',\n 'top': this.DropdownTop + 'px',\n 'bottom': 'auto',\n 'left': this.DropdownLeft + 'px',\n 'width': this.DropdownWidth + 'px',\n 'z-index': '10000'\n };\n }\n\n /** Calculate dropdown position relative to viewport from anchor element */\n private updateDropdownPosition(anchorEl: HTMLElement): void {\n const rect = anchorEl.getBoundingClientRect();\n const dropdownMaxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n if (spaceBelow < dropdownMaxHeight && spaceAbove > spaceBelow) {\n this.OpenAbove = true;\n this.DropdownTop = rect.top - gap;\n } else {\n this.OpenAbove = false;\n this.DropdownTop = rect.bottom + gap;\n }\n this.DropdownLeft = rect.left;\n this.DropdownWidth = rect.width;\n }\n\n /** Start listening for scroll/resize to close dropdowns */\n private startScrollListener(): void {\n this.stopScrollListener();\n\n const onScroll = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n const onResize = () => {\n this.closeAllDropdowns();\n this.cdr.markForCheck();\n };\n\n document.addEventListener('scroll', onScroll, true); // capture phase catches all scrollable ancestors\n window.addEventListener('resize', onResize);\n\n this._scrollCleanup = () => {\n document.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onResize);\n };\n }\n\n /** Remove scroll/resize listeners */\n private stopScrollListener(): void {\n if (this._scrollCleanup) {\n this._scrollCleanup();\n this._scrollCleanup = null;\n }\n }\n\n /** Close all dropdown types */\n private closeAllDropdowns(): void {\n this.ShowFKDropdown = false;\n this.ShowValueListDropdown = false;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n }\n\n // ============================================\n // FK AUTOCOMPLETE (custom implementation)\n // ============================================\n\n /** Suggestions returned from the FK entity search */\n FKSuggestions: FKSuggestion[] = [];\n\n /** Whether the current FK value is a confirmed match (user selected from dropdown) */\n FKIsMatched = false;\n\n /** Whether the FK dropdown is visible */\n ShowFKDropdown = false;\n\n /** Text the user is currently typing in the FK search input. null = use display name. */\n private _fkInputText: string | null = null;\n\n /** Debounce timer for FK search */\n private _fkSearchTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Last known FK input element for position recalculation */\n private _lastFKInputEl: HTMLElement | null = null;\n\n /** The display text shown in the FK search input */\n get FKSearchText(): string {\n if (this._fkInputText !== null) return this._fkInputText;\n return this.FKDisplayName || '';\n }\n\n /** Handle typing in the FK search input */\n OnFKInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._fkInputText = input.value;\n this._lastFKInputEl = input;\n this.FKIsMatched = false;\n\n // Debounce search\n if (this._fkSearchTimeout) clearTimeout(this._fkSearchTimeout);\n this._fkSearchTimeout = setTimeout(() => {\n if (this._fkInputText && this._fkInputText.length >= 1) {\n this.searchRelatedEntity(this._fkInputText);\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n }, 300);\n }\n\n /** Show dropdown on focus if suggestions exist */\n OnFKFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this._lastFKInputEl = input;\n if (this.FKSuggestions.length > 0) {\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowFKDropdown = true;\n this.cdr.markForCheck();\n }\n }\n\n /** Hide dropdown on blur, revert to matched name if user didn't select */\n OnFKBlur(): void {\n // Small delay so mousedown on dropdown items fires first\n setTimeout(() => {\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n // If user was typing but didn't select, revert to display name\n if (!this.FKIsMatched && this._fkInputText !== null) {\n this._fkInputText = null;\n }\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the FK dropdown */\n OnFKSelectItem(suggestion: FKSuggestion, event: MouseEvent): void {\n event.preventDefault();\n this._fkInputText = suggestion.DisplayName;\n this.Value = suggestion.PrimaryKeyValue;\n this.FKIsMatched = true;\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n\n // Update virtual name field for visual consistency after save\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, suggestion.DisplayName);\n }\n this.cdr.markForCheck();\n }\n\n /** Clear FK value via the X button */\n OnFKClearClick(event: MouseEvent): void {\n event.preventDefault();\n this.Value = null;\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n\n const nameFieldMap = this.FieldInfo?.RelatedEntityNameFieldMap;\n if (nameFieldMap) {\n this.Record.Set(nameFieldMap, '');\n }\n this.cdr.markForCheck();\n }\n\n /**\n * Perform a RunView search on the related entity's name field.\n * Falls back to searching by primary key when no NameField exists (single-field PKs only).\n */\n private async searchRelatedEntity(query: string): Promise<void> {\n const fieldInfo = this.FieldInfo;\n if (!fieldInfo?.RelatedEntity) return;\n\n const md = this.ProviderToUse;\n const relatedEntity = md.Entities.find(e => e.Name === fieldInfo.RelatedEntity);\n if (!relatedEntity) return;\n\n const nameField = relatedEntity.NameField;\n const pkFields = relatedEntity.PrimaryKeys;\n\n // If no NameField, fall back to PK — but only for single-field PKs\n if (!nameField) {\n if (!pkFields || pkFields.length !== 1) return;\n }\n\n const nameFieldName = nameField ? nameField.Name : pkFields[0].Name;\n const pkFieldName = fieldInfo.RelatedEntityFieldName || 'ID';\n\n // Build Fields array, avoiding duplicates when nameField IS the PK\n const fields = nameFieldName === pkFieldName\n ? [pkFieldName]\n : [pkFieldName, nameFieldName];\n\n const escapedQuery = query.replace(/'/g, \"''\");\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<Record<string, unknown>>({\n EntityName: fieldInfo.RelatedEntity,\n ExtraFilter: `[${nameFieldName}] LIKE '%${escapedQuery}%'`,\n MaxRows: 20,\n ResultType: 'simple',\n Fields: fields\n });\n\n if (result.Success) {\n this.FKSuggestions = result.Results.map(r => ({\n PrimaryKeyValue: r[pkFieldName],\n DisplayName: String(r[nameFieldName] || '')\n }));\n if (this.FKSuggestions.length > 0 && this._lastFKInputEl) {\n this.updateDropdownPosition(this._lastFKInputEl);\n this.startScrollListener();\n }\n this.ShowFKDropdown = this.FKSuggestions.length > 0;\n } else {\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this.stopScrollListener();\n }\n this.cdr.markForCheck();\n }\n\n // ============================================\n // VALUE LIST AUTOCOMPLETE (for 'autocomplete' type)\n // ============================================\n\n /** Whether the value list dropdown is visible */\n ShowValueListDropdown = false;\n\n /** Current filter text for the value list */\n private _valueListFilter = '';\n\n /** Filtered possible values based on what the user typed */\n get FilteredPossibleValues(): string[] {\n if (!this._valueListFilter) return this.PossibleValues;\n const filter = this._valueListFilter.toLowerCase();\n return this.PossibleValues.filter(v => v.toLowerCase().includes(filter));\n }\n\n /** Handle typing in the value list autocomplete */\n OnValueListInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n this._valueListFilter = input.value;\n this.Value = input.value;\n this.updateDropdownPosition(input);\n if (!this._scrollCleanup) this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Show dropdown on focus */\n OnValueListFocus(event: FocusEvent): void {\n const input = event.target as HTMLElement;\n this.updateDropdownPosition(input);\n this.startScrollListener();\n this.ShowValueListDropdown = true;\n this.cdr.markForCheck();\n }\n\n /** Hide dropdown on blur */\n OnValueListBlur(): void {\n setTimeout(() => {\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an item from the value list dropdown */\n OnValueListSelect(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this._valueListFilter = '';\n this.ShowValueListDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // CUSTOM SELECT DROPDOWN (replaces native <select>)\n // ============================================\n\n /** Whether the custom select dropdown is visible */\n ShowSelectDropdown = false;\n\n /** Toggle the custom select dropdown */\n OnSelectTriggerClick(event: Event): void {\n event.preventDefault();\n if (this.ShowSelectDropdown) {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n } else {\n const el = event.currentTarget as HTMLElement;\n this.updateDropdownPosition(el);\n this.startScrollListener();\n this.ShowSelectDropdown = true;\n }\n this.cdr.markForCheck();\n }\n\n /** Close the select dropdown on blur */\n OnSelectTriggerBlur(): void {\n setTimeout(() => {\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }, 200);\n }\n\n /** Select an option from the custom select dropdown */\n OnSelectOptionClick(value: string, event: MouseEvent): void {\n event.preventDefault();\n this.Value = value;\n this.ShowSelectDropdown = false;\n this.stopScrollListener();\n this.cdr.markForCheck();\n }\n\n // ============================================\n // GENERAL PROPERTIES\n // ============================================\n\n /** Whether the field's varchar(max) - long text that gets markdown rendering */\n get IsLongText(): boolean {\n return this.FieldInfo?.Length === -1;\n }\n\n /** Format a value for display */\n FormatValue(): string {\n const val = this.Value;\n if (val === null || val === undefined) return '';\n if (val instanceof Date) {\n return val.toLocaleString();\n }\n return String(val);\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['FormContext'] || changes['EditMode'] || changes['Record']) {\n // Reset FK state when record changes\n if (changes['Record']) {\n this._fkInputText = null;\n this.FKIsMatched = false;\n this.FKSuggestions = [];\n this.ShowFKDropdown = false;\n this._resolvedFKName = undefined;\n this._resolvedFKValue = undefined;\n this._fkNameLoading = false;\n // Reset validation state for new record\n this._touched = false;\n this._fieldErrors = [];\n }\n // Reset validation state when exiting edit mode\n if (changes['EditMode'] && !this.EditMode) {\n this._touched = false;\n this._fieldErrors = [];\n }\n this.cdr.markForCheck();\n }\n }\n\n ngOnDestroy(): void {\n if (this._fkSearchTimeout) {\n clearTimeout(this._fkSearchTimeout);\n }\n this.stopScrollListener();\n }\n\n // ---- Navigation Handlers ----\n\n /**\n * Handle click on a record FK link in read-only mode.\n */\n OnRecordLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.FieldInfo || !this.Record) return;\n const relatedEntityName = this.FieldInfo.RelatedEntity;\n if (!relatedEntityName) return;\n\n const fkValue = this.Value;\n if (!fkValue) return;\n\n // Build a CompositeKey for the FK target record using the related entity's PK field\n const relatedFieldName = this.FieldInfo.RelatedEntityFieldName || 'ID';\n const targetKey = new CompositeKey([new KeyValuePair(relatedFieldName, fkValue)]);\n\n this.Navigate.emit({\n Kind: 'record',\n EntityName: relatedEntityName,\n PrimaryKey: targetKey,\n OpenInNewTab: event.ctrlKey || event.metaKey\n });\n }\n\n /**\n * Handle click on an email link in read-only mode.\n */\n OnEmailLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const email = this.FormatValue();\n if (!email) return;\n this.Navigate.emit({\n Kind: 'email',\n EmailAddress: email\n });\n }\n\n /**\n * Handle click on a URL link in read-only mode.\n */\n OnUrlLinkClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const url = this.FormatValue();\n if (!url) return;\n this.Navigate.emit({\n Kind: 'external-link',\n Url: url,\n OpenInNewTab: true\n });\n }\n\n /**\n * Handle value change from a native input.\n */\n OnInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value;\n }\n\n /**\n * Handle value change from a number input.\n */\n OnNumberChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const num = input.valueAsNumber;\n this.Value = isNaN(num) ? null : num;\n }\n\n /**\n * Handle value change from a date input.\n */\n OnDateChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.value ? new Date(input.value) : null;\n }\n\n /**\n * Handle value change from a checkbox.\n */\n OnCheckboxChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.Value = input.checked;\n }\n\n /**\n * Get date value formatted for HTML date input.\n */\n get DateInputValue(): string {\n const val = this.Value;\n if (!val) return '';\n const date = val instanceof Date ? val : new Date(String(val));\n if (isNaN(date.getTime())) return '';\n return date.toISOString().split('T')[0];\n }\n}\n","@if (Record && (Record.IsSaved || !IsFieldReadOnly)) {\n <!-- READ-ONLY MODE -->\n @if ((!EditMode || IsFieldReadOnly) && !ShouldHideField) {\n <div class=\"mj-forms-field\" [class.mj-forms-field--readonly]=\"EditMode && IsFieldReadOnly\" [class.mj-forms-field--dirty]=\"IsDirty\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- FK fields with a mapped name field: show the name as a hyperlink -->\n @if (IsFKWithNameField) {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link mj-forms-field-link--fk\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FKDisplayName }}\n </a>\n </span>\n }\n @else {\n @switch (LinkType) {\n @case ('Email') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnEmailLinkClick($event)\" title=\"Send email\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-envelope mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('URL') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnUrlLinkClick($event)\" title=\"Open link\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @case ('Record') {\n <span class=\"mj-forms-field-value\">\n <a class=\"mj-forms-field-link\" (click)=\"OnRecordLinkClick($event)\" title=\"View related record\">\n {{ FormatValue() }}\n <i class=\"fa-solid fa-arrow-up-right-from-square mj-forms-field-link-icon\"></i>\n </a>\n </span>\n }\n @default {\n @if (Type === 'checkbox') {\n <span class=\"mj-forms-field-value\">\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\" [checked]=\"!!Value\" disabled>\n </div>\n </span>\n }\n @else if (IsLongText) {\n <span class=\"mj-forms-field-value mj-forms-field-value--long\">{{ FormatValue() }}</span>\n }\n @else {\n <span class=\"mj-forms-field-value\">{{ FormatValue() }}</span>\n }\n }\n }\n }\n </div>\n </div>\n }\n\n <!-- EDIT MODE -->\n @if (EditMode && !IsFieldReadOnly) {\n <div class=\"mj-forms-field mj-forms-field--editing\" [class.mj-forms-field--dirty]=\"IsDirty\" [class.mj-forms-field--required-empty]=\"IsRequiredEmpty\" [class.mj-forms-field--has-error]=\"ShowErrors\" [class.mj-forms-field--has-warning]=\"ShowWarnings\">\n @if (ShowLabel) {\n <label class=\"mj-forms-field-label\" [innerHTML]=\"HighlightedDisplayName\"></label>\n }\n <div class=\"mj-forms-field-control\">\n <!-- Foreign Key fields get custom search autocomplete -->\n @if (HasRelatedEntity) {\n <div class=\"mj-fk-search\" [class.mj-fk-search--matched]=\"FKIsMatched\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FKSearchText\"\n (input)=\"OnFKInput($event)\"\n (focus)=\"OnFKFocus($event)\"\n (blur)=\"OnFKBlur()\"\n placeholder=\"Search...\">\n @if (FKSearchText) {\n <button class=\"mj-fk-clear\" (mousedown)=\"OnFKClearClick($event)\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n }\n @if (ShowFKDropdown && FKSuggestions.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (suggestion of FKSuggestions; track suggestion.PrimaryKeyValue) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnFKSelectItem(suggestion, $event)\">\n {{ suggestion.DisplayName }}\n </div>\n }\n </div>\n }\n </div>\n }\n @else {\n @switch (Type) {\n @case ('textbox') {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-forms-field-input mj-forms-field-input--textarea\"\n [value]=\"FormatValue()\"\n (input)=\"OnInputChange($event)\"></textarea>\n }\n @case ('number') {\n <input type=\"number\"\n class=\"mj-forms-field-input mj-forms-field-input--number\"\n [value]=\"Value\"\n (change)=\"OnNumberChange($event)\">\n }\n @case ('datepicker') {\n <input type=\"date\"\n class=\"mj-forms-field-input mj-forms-field-input--date\"\n [value]=\"DateInputValue\"\n (change)=\"OnDateChange($event)\">\n }\n @case ('checkbox') {\n <div class=\"mj-forms-field-checkbox\">\n <input type=\"checkbox\"\n [checked]=\"!!Value\"\n (change)=\"OnCheckboxChange($event)\">\n </div>\n }\n @case ('select') {\n <div class=\"mj-custom-select-trigger\"\n tabindex=\"0\"\n (click)=\"OnSelectTriggerClick($event)\"\n (blur)=\"OnSelectTriggerBlur()\">\n <span class=\"mj-custom-select-value\" [class.mj-custom-select-value--placeholder]=\"!FormatValue()\">\n {{ FormatValue() || '-- Select --' }}\n </span>\n <i class=\"fa-solid fa-chevron-down mj-custom-select-chevron\" [class.mj-custom-select-chevron--open]=\"ShowSelectDropdown\"></i>\n </div>\n @if (ShowSelectDropdown && PossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of PossibleValues; track option) {\n <div class=\"mj-fk-option\" [class.mj-fk-option--selected]=\"FormatValue() === option\" (mousedown)=\"OnSelectOptionClick(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n }\n @case ('autocomplete') {\n <div class=\"mj-fk-search\">\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (input)=\"OnValueListInput($event)\"\n (focus)=\"OnValueListFocus($event)\"\n (blur)=\"OnValueListBlur()\"\n placeholder=\"Type to search...\">\n <i class=\"fa-solid fa-magnifying-glass mj-fk-search-icon\"></i>\n @if (ShowValueListDropdown && FilteredPossibleValues.length > 0) {\n <div class=\"mj-fk-dropdown\" [ngStyle]=\"DropdownPositionStyle\" [class.mj-fk-dropdown--above]=\"OpenAbove\">\n @for (option of FilteredPossibleValues; track option) {\n <div class=\"mj-fk-option\" (mousedown)=\"OnValueListSelect(option, $event)\">\n {{ option }}\n </div>\n }\n </div>\n }\n </div>\n }\n @default {\n <input type=\"text\"\n class=\"mj-forms-field-input\"\n [value]=\"FormatValue()\"\n (change)=\"OnInputChange($event)\">\n }\n }\n }\n </div>\n <!-- Inline validation messages -->\n @if (DisplayErrors.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--error\">\n @for (error of DisplayErrors; track error.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ error.Message }}</span>\n </div>\n }\n </div>\n }\n @if (DisplayWarnings.length > 0) {\n <div class=\"mj-forms-field-validation mj-forms-field-validation--warning\">\n @for (warning of DisplayWarnings; track warning.Message) {\n <div class=\"mj-forms-field-validation-item\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ warning.Message }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapsible-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/panel/collapsible-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACqB,YAAY,EAEtC,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAC3D,SAAS,EAE3B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;;
|
|
1
|
+
{"version":3,"file":"collapsible-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/panel/collapsible-panel.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { Subject } from 'rxjs';
|
|
|
3
3
|
import { takeUntil } from 'rxjs/operators';
|
|
4
4
|
import { MjFormFieldComponent } from '../field/form-field.component';
|
|
5
5
|
import { CompositeKey } from '@memberjunction/core';
|
|
6
|
+
import { EscapeHTML, HighlightSearchMatches } from '@memberjunction/global';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
const _c0 = ["panelContent"];
|
|
8
9
|
const _c1 = ["*"];
|
|
@@ -354,14 +355,11 @@ export class MjCollapsiblePanelComponent {
|
|
|
354
355
|
const sectionMatches = this.SectionName.toLowerCase().includes(searchTerm);
|
|
355
356
|
const fieldsMatch = this.FieldNames.includes(searchTerm);
|
|
356
357
|
this.IsVisible = sectionMatches || fieldsMatch;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
else {
|
|
363
|
-
this.DisplayName = this.SectionName;
|
|
364
|
-
}
|
|
358
|
+
// DisplayName is bound to `[innerHTML]` in the template — must always be HTML-safe.
|
|
359
|
+
this.DisplayName =
|
|
360
|
+
this.IsVisible && sectionMatches
|
|
361
|
+
? HighlightSearchMatches(this.SectionName, searchTerm, 'mj-forms-search-highlight')
|
|
362
|
+
: EscapeHTML(this.SectionName);
|
|
365
363
|
this.cdr.markForCheck();
|
|
366
364
|
}
|
|
367
365
|
static ɵfac = function MjCollapsiblePanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MjCollapsiblePanelComponent)(); };
|
|
@@ -488,5 +486,5 @@ export class MjCollapsiblePanelComponent {
|
|
|
488
486
|
type: HostListener,
|
|
489
487
|
args: ['drop', ['$event']]
|
|
490
488
|
}] }); })();
|
|
491
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjCollapsiblePanelComponent, { className: "MjCollapsiblePanelComponent", filePath: "src/lib/panel/collapsible-panel.component.ts", lineNumber:
|
|
489
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjCollapsiblePanelComponent, { className: "MjCollapsiblePanelComponent", filePath: "src/lib/panel/collapsible-panel.component.ts", lineNumber: 54 }); })();
|
|
492
490
|
//# 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 { FormNavigationEvent } from '../types/navigation-events';\nimport { MjFormFieldComponent } from '../field/form-field.component';\nimport { CompositeKey } from '@memberjunction/core';\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 // ---- 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\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 /** Whether the panel is expanded (delegates to form state) */\n get Expanded(): boolean {\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 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 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 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 if (this.IsVisible && sectionMatches) {\n const escaped = searchTerm.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(escaped, 'gi');\n this.DisplayName = this.SectionName.replace(regex, '<mark class=\"mj-forms-search-highlight\">$&</mark>');\n } else {\n this.DisplayName = this.SectionName;\n }\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\" role=\"button\" tabindex=\"0\" (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 -->\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\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 { 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 // ---- 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\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 /** Whether the panel is expanded (delegates to form state) */\n get Expanded(): boolean {\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 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 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 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\" role=\"button\" tabindex=\"0\" (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 -->\n <div class=\"mj-forms-panel-chevron\">\n <i [class]=\"Expanded ? 'fa fa-chevron-up' : 'fa fa-chevron-down'\"></i>\n </div>\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-base-forms",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.34.0",
|
|
4
4
|
"description": "MemberJunction: Generic Angular form components for rendering and editing entity records. Provides configurable toolbar, modern form fields (PrimeNG unstyled), collapsible panels with IS-A inheritance support, and event-driven navigation. Zero Explorer dependencies - usable in any Angular application.",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -36,15 +36,15 @@
|
|
|
36
36
|
"primeng": "21.1.1"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@memberjunction/core": "5.
|
|
40
|
-
"@memberjunction/core-entities": "5.
|
|
41
|
-
"@memberjunction/global": "5.
|
|
42
|
-
"@memberjunction/ng-base-types": "5.
|
|
43
|
-
"@memberjunction/ng-list-management": "5.
|
|
44
|
-
"@memberjunction/ng-notifications": "5.
|
|
45
|
-
"@memberjunction/ng-record-changes": "5.
|
|
46
|
-
"@memberjunction/ng-record-tags": "5.
|
|
47
|
-
"@memberjunction/ng-entity-viewer": "5.
|
|
39
|
+
"@memberjunction/core": "5.34.0",
|
|
40
|
+
"@memberjunction/core-entities": "5.34.0",
|
|
41
|
+
"@memberjunction/global": "5.34.0",
|
|
42
|
+
"@memberjunction/ng-base-types": "5.34.0",
|
|
43
|
+
"@memberjunction/ng-list-management": "5.34.0",
|
|
44
|
+
"@memberjunction/ng-notifications": "5.34.0",
|
|
45
|
+
"@memberjunction/ng-record-changes": "5.34.0",
|
|
46
|
+
"@memberjunction/ng-record-tags": "5.34.0",
|
|
47
|
+
"@memberjunction/ng-entity-viewer": "5.34.0",
|
|
48
48
|
"rxjs": "^7.8.2",
|
|
49
49
|
"tslib": "^2.8.1"
|
|
50
50
|
},
|