@memberjunction/ng-search 5.50.0 → 6.1.0-edge.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/LICENSE +7 -0
- package/dist/lib/search-scope-child-grid.component.d.ts +2 -1
- package/dist/lib/search-scope-child-grid.component.d.ts.map +1 -1
- package/dist/lib/search-scope-child-grid.component.js +11 -8
- package/dist/lib/search-scope-child-grid.component.js.map +1 -1
- package/package.json +17 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 MemberJunction
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
*/
|
|
43
43
|
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
44
44
|
import { BaseEntity } from '@memberjunction/core';
|
|
45
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
45
46
|
import * as i0 from "@angular/core";
|
|
46
47
|
/** Supported inline-edit types for a scope-child grid column. */
|
|
47
48
|
export type SearchScopeChildGridColumnType = 'text' | 'number' | 'checkbox' | 'code' | 'textarea' | 'lookup' | 'select';
|
|
@@ -80,7 +81,7 @@ interface GridRow {
|
|
|
80
81
|
/** True while an inline save is in flight. */
|
|
81
82
|
Saving: boolean;
|
|
82
83
|
}
|
|
83
|
-
export declare class SearchScopeChildGridComponent implements OnDestroy {
|
|
84
|
+
export declare class SearchScopeChildGridComponent extends BaseAngularComponent implements OnDestroy {
|
|
84
85
|
private cdr;
|
|
85
86
|
private _parentID;
|
|
86
87
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-scope-child-grid.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-scope-child-grid.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAGH,YAAY,EAEZ,SAAS,EAGZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAA+B,MAAM,sBAAsB,CAAC
|
|
1
|
+
{"version":3,"file":"search-scope-child-grid.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-scope-child-grid.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
* @module @memberjunction/ng-search
|
|
42
42
|
*/
|
|
43
43
|
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
44
|
-
import { LogError,
|
|
44
|
+
import { LogError, RunView } from '@memberjunction/core';
|
|
45
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
45
46
|
import { UUIDsEqual } from '@memberjunction/global';
|
|
46
47
|
import * as i0 from "@angular/core";
|
|
47
48
|
import * as i1 from "@angular/forms";
|
|
@@ -254,7 +255,7 @@ function SearchScopeChildGridComponent_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
254
255
|
i0.ɵɵadvance(2);
|
|
255
256
|
i0.ɵɵconditional(!ctx_r0.Disabled ? 9 : -1);
|
|
256
257
|
} }
|
|
257
|
-
export class SearchScopeChildGridComponent {
|
|
258
|
+
export class SearchScopeChildGridComponent extends BaseAngularComponent {
|
|
258
259
|
cdr = inject(ChangeDetectorRef);
|
|
259
260
|
// ─── Inputs ───────────────────────────────────────────────────────────────
|
|
260
261
|
_parentID = null;
|
|
@@ -317,7 +318,7 @@ export class SearchScopeChildGridComponent {
|
|
|
317
318
|
this.IsLoading = true;
|
|
318
319
|
this.LoadError = null;
|
|
319
320
|
try {
|
|
320
|
-
const rv =
|
|
321
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
321
322
|
const result = await rv.RunView({
|
|
322
323
|
EntityName: this.ChildEntityName,
|
|
323
324
|
ExtraFilter: `${this.ParentFieldName} = '${this._parentID.replace(/'/g, "''")}'`,
|
|
@@ -355,7 +356,9 @@ export class SearchScopeChildGridComponent {
|
|
|
355
356
|
if (this.Disabled || !this._parentID || !this.ChildEntityName)
|
|
356
357
|
return;
|
|
357
358
|
try {
|
|
358
|
-
|
|
359
|
+
// This class extends BaseAngularComponent, so it has accepted a `Provider` input all
|
|
360
|
+
// along — the note claiming otherwise was stale.
|
|
361
|
+
const md = this.ProviderToUse;
|
|
359
362
|
const entity = await md.GetEntityObject(this.ChildEntityName);
|
|
360
363
|
entity.Set(this.ParentFieldName, this._parentID);
|
|
361
364
|
this.applyColumnDefaults(entity);
|
|
@@ -451,7 +454,7 @@ export class SearchScopeChildGridComponent {
|
|
|
451
454
|
this.refreshLookupLabels();
|
|
452
455
|
return;
|
|
453
456
|
}
|
|
454
|
-
const rv =
|
|
457
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
455
458
|
const queries = toLoad.map(c => ({
|
|
456
459
|
EntityName: c.LookupEntityName,
|
|
457
460
|
ExtraFilter: c.LookupFilter || '',
|
|
@@ -534,8 +537,8 @@ export class SearchScopeChildGridComponent {
|
|
|
534
537
|
`array to match the entity's typed properties.`);
|
|
535
538
|
}
|
|
536
539
|
}
|
|
537
|
-
static ɵfac = function SearchScopeChildGridComponent_Factory(__ngFactoryType__) { return
|
|
538
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchScopeChildGridComponent, selectors: [["mj-search-scope-child-grid"]], inputs: { ParentID: "ParentID", ChildEntityName: "ChildEntityName", ParentFieldName: "ParentFieldName", Columns: "Columns", AddButtonLabel: "AddButtonLabel", EmptyMessage: "EmptyMessage", OrderBy: "OrderBy", Disabled: "Disabled" }, outputs: { RowsChanged: "RowsChanged", RowAdded: "RowAdded", RowRemoved: "RowRemoved" }, standalone: false, decls: 4, vars: 3, consts: [[1, "scope-grid"], [1, "scope-grid-loading"], [1, "scope-grid-error"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], [1, "scope-grid-table"], [3, "width"], ["aria-hidden", "true", 1, "scope-grid-actions-col"], [1, "scope-grid-footer"], [1, "scope-grid-empty"], [3, "saving"], [1, "scope-grid-actions-col"], ["type", "button", "title", "Remove row", 1, "scope-grid-icon-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], ["type", "checkbox", 1, "mj-checkbox", 3, "checked", "disabled"], ["type", "number", 1, "mj-input", "scope-grid-input", 3, "value", "placeholder", "disabled"], ["rows", "2", 1, "mj-textarea", "scope-grid-textarea", 3, "value", "placeholder", "disabled"], ["rows", "2", "spellcheck", "false", 1, "mj-textarea", "scope-grid-code", 3, "value", "placeholder", "disabled"], [1, "mj-input", "scope-grid-select", 3, "value", "disabled"], ["type", "text", 1, "mj-input", "scope-grid-input", 3, "value", "placeholder", "disabled"], ["type", "checkbox", 1, "mj-checkbox", 3, "change", "checked", "disabled"], ["type", "number", 1, "mj-input", "scope-grid-input", 3, "change", "value", "placeholder", "disabled"], ["rows", "2", 1, "mj-textarea", "scope-grid-textarea", 3, "change", "value", "placeholder", "disabled"], ["rows", "2", "spellcheck", "false", 1, "mj-textarea", "scope-grid-code", 3, "change", "value", "placeholder", "disabled"], [1, "mj-input", "scope-grid-select", 3, "change", "value", "disabled"], ["value", ""], [3, "value"], ["type", "text", 1, "mj-input", "scope-grid-input", 3, "change", "value", "placeholder", "disabled"], ["type", "button", 1, "scope-grid-add-btn", 3, "click"]], template: function SearchScopeChildGridComponent_Template(rf, ctx) { if (rf & 1) {
|
|
540
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵSearchScopeChildGridComponent_BaseFactory; return function SearchScopeChildGridComponent_Factory(__ngFactoryType__) { return (ɵSearchScopeChildGridComponent_BaseFactory || (ɵSearchScopeChildGridComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SearchScopeChildGridComponent)))(__ngFactoryType__ || SearchScopeChildGridComponent); }; })();
|
|
541
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchScopeChildGridComponent, selectors: [["mj-search-scope-child-grid"]], inputs: { ParentID: "ParentID", ChildEntityName: "ChildEntityName", ParentFieldName: "ParentFieldName", Columns: "Columns", AddButtonLabel: "AddButtonLabel", EmptyMessage: "EmptyMessage", OrderBy: "OrderBy", Disabled: "Disabled" }, outputs: { RowsChanged: "RowsChanged", RowAdded: "RowAdded", RowRemoved: "RowRemoved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 3, consts: [[1, "scope-grid"], [1, "scope-grid-loading"], [1, "scope-grid-error"], ["aria-hidden", "true", 1, "fa-solid", "fa-triangle-exclamation"], [1, "scope-grid-table"], [3, "width"], ["aria-hidden", "true", 1, "scope-grid-actions-col"], [1, "scope-grid-footer"], [1, "scope-grid-empty"], [3, "saving"], [1, "scope-grid-actions-col"], ["type", "button", "title", "Remove row", 1, "scope-grid-icon-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], ["type", "checkbox", 1, "mj-checkbox", 3, "checked", "disabled"], ["type", "number", 1, "mj-input", "scope-grid-input", 3, "value", "placeholder", "disabled"], ["rows", "2", 1, "mj-textarea", "scope-grid-textarea", 3, "value", "placeholder", "disabled"], ["rows", "2", "spellcheck", "false", 1, "mj-textarea", "scope-grid-code", 3, "value", "placeholder", "disabled"], [1, "mj-input", "scope-grid-select", 3, "value", "disabled"], ["type", "text", 1, "mj-input", "scope-grid-input", 3, "value", "placeholder", "disabled"], ["type", "checkbox", 1, "mj-checkbox", 3, "change", "checked", "disabled"], ["type", "number", 1, "mj-input", "scope-grid-input", 3, "change", "value", "placeholder", "disabled"], ["rows", "2", 1, "mj-textarea", "scope-grid-textarea", 3, "change", "value", "placeholder", "disabled"], ["rows", "2", "spellcheck", "false", 1, "mj-textarea", "scope-grid-code", 3, "change", "value", "placeholder", "disabled"], [1, "mj-input", "scope-grid-select", 3, "change", "value", "disabled"], ["value", ""], [3, "value"], ["type", "text", 1, "mj-input", "scope-grid-input", 3, "change", "value", "placeholder", "disabled"], ["type", "button", 1, "scope-grid-add-btn", 3, "click"]], template: function SearchScopeChildGridComponent_Template(rf, ctx) { if (rf & 1) {
|
|
539
542
|
i0.ɵɵelementStart(0, "div", 0);
|
|
540
543
|
i0.ɵɵconditionalCreate(1, SearchScopeChildGridComponent_Conditional_1_Template, 2, 0, "div", 1)(2, SearchScopeChildGridComponent_Conditional_2_Template, 3, 1, "div", 2)(3, SearchScopeChildGridComponent_Conditional_3_Template, 10, 2);
|
|
541
544
|
i0.ɵɵelementEnd();
|
|
@@ -571,5 +574,5 @@ export class SearchScopeChildGridComponent {
|
|
|
571
574
|
}], RowRemoved: [{
|
|
572
575
|
type: Output
|
|
573
576
|
}] }); })();
|
|
574
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SearchScopeChildGridComponent, { className: "SearchScopeChildGridComponent", filePath: "src/lib/search-scope-child-grid.component.ts", lineNumber:
|
|
577
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SearchScopeChildGridComponent, { className: "SearchScopeChildGridComponent", filePath: "src/lib/search-scope-child-grid.component.ts", lineNumber: 107 }); })();
|
|
575
578
|
//# sourceMappingURL=search-scope-child-grid.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-scope-child-grid.component.js","sourceRoot":"","sources":["../../src/lib/search-scope-child-grid.component.ts","../../src/lib/search-scope-child-grid.component.html"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EACH,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,KAAK,EAEL,MAAM,EACN,MAAM,EACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAc,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;;;;ICnD5C,8BAAgC;IAAA,6BAAe;IAAA,iBAAM;;;IAErD,8BAA8B;IAC1B,uBAAmE;IACnE,YACJ;IAAA,iBAAM;;;IADF,eACJ;IADI,iDACJ;;;IAMgB,0BAAsC;IAAA,YAAe;IAAA,iBAAK;;;IAAtD,6CAAiC;IAAC,cAAe;IAAf,kCAAe;;;IAQrD,AADJ,0BAAI,YACiE;IAC7D,YACJ;IACJ,AADI,iBAAK,EACJ;;;IAHG,cAAmC;;IACnC,cACJ;IADI,oDACJ;;;;IASoB,iCAKmE;IAA/D,oUAAU,0DAAmD,KAAC;IALlE,iBAKmE;;;;;IAD/D,AADA,+DAAoC,gDACC;;;;IAIzC,iCAMyE;IAArE,oUAAU,gEAAyD,KAAC;IANxE,iBAMyE;;;;;IADrE,AADA,AADA,iEAA4C,yCACP,gDACA;;;;IAIzC,oCAMiE;IAA7D,uUAAU,wDAAiD,KAAC;IAAC,iBAAW;;;;;IADxE,AADA,AADA,iEAA4C,yCACP,gDACA;;;;IAIzC,oCAOiE;IAA7D,uUAAU,wDAAiD,KAAC;IAAC,iBAAW;;;;;IADxE,AADA,AADA,iEAA4C,yCACP,gDACA;;;IAWjC,kCAAyB;IAAA,YAAe;IAAA,iBAAS;;;IAAzC,kCAAgB;IAAC,cAAe;IAAf,mCAAe;;;;IAPhD,kCAIiE;IAA7D,sUAAU,wDAAiD,KAAC;IAC5D,kCAAiB;IAAA,oCAAU;IAAA,iBAAS;IACpC,mJAEC;IACL,iBAAS;;;;;IANL,AADA,iEAA4C,gDACP;IAGrC,eAEC;IAFD,cAAA,+BAAqB,CAEpB;;;IAUG,kCAAkC;IAAA,YAAe;IAAA,iBAAS;;;IAAlD,qCAAyB;IAAC,cAAe;IAAf,mCAAe;;;;IANzD,kCAIiE;IAA7D,sUAAU,wDAAiD,KAAC;IAC5D,mJAEC;IACL,iBAAS;;;;;IALL,AADA,iEAA4C,gDACP;IAErC,cAEC;IAFD,6BAEC;;;;IAIL,iCAMiE;IAA7D,qUAAU,wDAAiD,KAAC;IANhE,iBAMiE;;;;;IAD7D,AADA,AADA,iEAA4C,yCACP,gDACA;;;IAnErD,0BAAsC;IA6D9B,AAXA,AAZA,AAVA,AATA,AATA,AARA,mIAAoB,6GAQF,gHASE,gHASJ,8GAUE,8GAYA,6GAWR;IAUlB,iBAAK;;;;IAvED,6CAAiC;IACjC,cAqEC;IArED,8CAAA,UAAU,oBAAV,QAAQ,oBAAR,UAAU,oBAAV,MAAM,oBAAN,QAAQ,oBAAR,QAAQ,SAqEP;;;;IAxEb,0BAAgC;IAC5B,iIAyEC;IAEG,AADJ,8BAAmC,iBAMF;IAAzB,+OAAS,wBAAc,KAAC;IACxB,wBAAoD;IAGhE,AADI,AADI,iBAAS,EACR,EACJ;;;;IArFD,uCAA2B;IAC3B,cAyEC;IAzED,6BAyEC;IAMO,eAAmC;IAAnC,2DAAmC;;;IAjFnD,2HAuFC;;;IAvFD,0BAuFC;;;;IAOL,AADJ,8BAA+B,iBACyC;IAAnB,iNAAS,eAAQ,KAAC;IAC/D,YACJ;IACJ,AADI,iBAAS,EACP;;;IAFE,eACJ;IADI,sDACJ;;;IA/GA,AADJ,AADJ,gCAAgC,YACrB,SACC;IACA,6GAEC;IACD,wBAA2D;IAEnE,AADI,iBAAK,EACD;IACR,6BAAO;IAOD,AANF,yGAAyB,6EAMhB;IA2FjB,AADI,iBAAQ,EACJ;IAER,6GAAiB;;;IA1GL,eAEC;IAFD,6BAEC;IAKL,eA+FC;IA/FD,kDA+FC;IAIT,eAMC;IAND,2CAMC;;ADnBT,MAAM,OAAO,6BAA6B;IAC9B,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExC,6EAA6E;IAErE,SAAS,GAAkB,IAAI,CAAC;IACxC;;;;OAIG;IACH,IACI,QAAQ,CAAC,KAAoB;QAC7B,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS;YAAE,OAAO;QACrC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;IACL,CAAC;IACD,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,6EAA6E;IACpE,eAAe,GAAW,EAAE,CAAC;IAEtC,qEAAqE;IAC5D,eAAe,GAAW,eAAe,CAAC;IAEnD,oDAAoD;IAC3C,OAAO,GAAiC,EAAE,CAAC;IAEpD,iDAAiD;IACxC,cAAc,GAAW,WAAW,CAAC;IAE9C,oDAAoD;IAC3C,YAAY,GAAW,cAAc,CAAC;IAE/C,2DAA2D;IAClD,OAAO,GAAW,EAAE,CAAC;IAE9B,4CAA4C;IACnC,QAAQ,GAAY,KAAK,CAAC;IAEnC,6EAA6E;IAE7E,+DAA+D;IACrD,WAAW,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEjD,oCAAoC;IAC1B,QAAQ,GAAG,IAAI,YAAY,EAAc,CAAC;IAEpD,sCAAsC;IAC5B,UAAU,GAAG,IAAI,YAAY,EAAc,CAAC;IAEtD,6EAA6E;IAEtE,IAAI,GAAc,EAAE,CAAC;IACrB,SAAS,GAAY,KAAK,CAAC;IAC3B,SAAS,GAAkB,IAAI,CAAC;IAEvC,mDAAmD;IAC3C,WAAW,GAAG,IAAI,GAAG,EAAgD,CAAC;IAEvE,WAAW;QACd,mEAAmE;IACvE,CAAC;IAED,4EAA4E;IAE5E,uCAAuC;IAChC,KAAK,CAAC,QAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACpE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YACf,OAAO;QACX,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAa;gBACxC,UAAU,EAAE,IAAI,CAAC,eAAe;gBAChC,WAAW,EAAE,GAAG,IAAI,CAAC,eAAe,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG;gBAChF,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB;gBAC7C,UAAU,EAAE,eAAe;aAC9B,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,IAAI,qBAAqB,CAAC;gBAC9D,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;gBAClC,4DAA4D;gBAC5D,8DAA8D;gBAC9D,2DAA2D;gBAC3D,kCAAkC;gBAClC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,CAAC;gBACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACrD,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,yDAAyD;IAClD,KAAK,CAAC,MAAM;QACf,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QACtE,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC,CAAC,uIAAuI;YAClK,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAAa,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1E,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACjD,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,8CAA8C,IAAI,CAAC,eAAe,UACvE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACnD,EAAE,CAAC,CAAC;QACR,CAAC;IACL,CAAC;IAED,yDAAyD;IAClD,KAAK,CAAC,OAAO,CAAC,GAAY;QAC7B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAChC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACN,QAAQ,CAAC,yCAAyC,IAAI,CAAC,eAAe,KAClE,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,IAAI,eAChD,EAAE,CAAC,CAAC;gBACJ,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YACxB,8EAA8E;YAC9E,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QAChB,CAAC;gBAAS,CAAC;YACP,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,wEAAwE;IACjE,KAAK,CAAC,SAAS,CAAC,GAAY;QAC/B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACrC,IAAI,CAAC,EAAE,EAAE,CAAC;oBACN,QAAQ,CAAC,2CAA2C,IAAI,CAAC,eAAe,KACpE,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,IAAI,eAChD,EAAE,CAAC,CAAC;oBACJ,OAAO;gBACX,CAAC;YACL,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzG,CAAC;IACL,CAAC;IAED,2DAA2D;IACpD,YAAY,CAAC,GAAY,EAAE,MAAkC;QAChE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,YAAY,CACrB,GAAY,EACZ,MAAkC,EAClC,KAAc;QAEd,IAAI,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ;YAAE,OAAO;QAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxD,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACpG,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1D,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;QACxD,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,kDAAkD;IAC3C,cAAc,CAAC,GAAY,EAAE,MAAkC;QAClE,OAAO,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;IAED,uDAAuD;IAChD,gBAAgB,CACnB,MAAkC;QAElC,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAC/D,CAAC;IAED,4EAA4E;IAE5E;;;OAGG;IACK,KAAK,CAAC,cAAc;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAiB,CAAC,CAAC,CAAC;QACrF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO;QACX,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,UAAU,EAAE,CAAC,CAAC,gBAAiB;YAC/B,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE;YACjC,OAAO,EAAE,GAAG,CAAC,CAAC,kBAAkB,IAAI,MAAM,MAAM;YAChD,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC;YAC9C,UAAU,EAAE,QAAiB;SAChC,CAAC,CAAC,CAAC;QAEJ,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;oBACf,QAAQ,CAAC,gDAAgD,GAAG,CAAC,gBAAgB,KAAK,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;oBACtG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAiB,EAAE,EAAE,CAAC,CAAC;oBAChD,OAAO;gBACX,CAAC;gBACD,MAAM,YAAY,GAAG,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC;gBACtD,MAAM,OAAO,GAAI,GAAG,CAAC,OAA0C,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACtE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACnB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;iBAC5C,CAAC,CAAC,CAAC;gBACJ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAiB,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,gDAAgD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjH,CAAC;QAED,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAEO,mBAAmB;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,gBAAgB;oBAAE,SAAS;gBAC7D,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,OAAO,EAAE,KAAK,QAAQ;oBAAE,SAAS;gBACrC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;gBACjE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBACtD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;YACrD,CAAC;QACL,CAAC;IACL,CAAC;IAEO,OAAO,CAAC,MAAkB;QAC9B,OAAO;YACH,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,EAAE;YAChB,MAAM,EAAE,KAAK;SAChB,CAAC;IACN,CAAC;IAED,sEAAsE;IAC9D,mBAAmB,CAAC,MAAkB;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC5D,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;;;;;;;;OAUG;IACK,iBAAiB,CAAC,MAAkB;QACxC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO;aACvB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,QAAQ,CACJ,gEAAgE;gBAChE,wBAAwB,IAAI,CAAC,eAAe,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBACxE,iEAAiE;gBACjE,+CAA+C,CAClD,CAAC;QACN,CAAC;IACL,CAAC;uHAxTQ,6BAA6B;6DAA7B,6BAA6B;YCzG1C,8BAAoD;YAQ9C,AALA,AAFF,+FAAiB,yEAEO,gEAKf;YAsHb,iBAAM;;YA9HkB,wCAA2B;YAC/C,cA4HC;YA5HD,2DA4HC;;;iFDpBQ,6BAA6B;cANzC,SAAS;6BACM,KAAK,YACP,4BAA4B;;kBAerC,KAAK;;kBAeL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAKL,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kFAvDE,6BAA6B","sourcesContent":["/**\n * @fileoverview Generic Search Scope Child Grid\n *\n * A parameter-driven grid for editing the child-collection tabs of a Search Scope:\n * - Providers (`MJ: Search Scope Providers`)\n * - External Indexes (`MJ: Search Scope External Indexes`)\n * - Entities (`MJ: Search Scope Entities`)\n * - Storage Accounts (`MJ: Search Scope Storage Accounts`)\n *\n * Also reused on the AI Agent form for assigning scopes to an agent (the\n * `MJ: AI Agent Search Scopes` join table). The `ParentID` + `ParentFieldName`\n * inputs keep it generic — parent can be a SearchScope OR an AI Agent.\n *\n * One component, many configurations. The parent passes:\n * - `ParentID` — the parent record ID (SearchScope ID, AI Agent ID, etc.)\n * - `ChildEntityName` — the MJ entity name of the child table\n * - `ParentFieldName` — the FK column on the child that references the parent\n * - `Columns` — declarative column spec (type, label, optional lookup source)\n *\n * This is a **Generic component** (see `packages/Angular/Generic/CLAUDE.md`):\n * - No Router / ActivatedRoute imports\n * - All state flows through @Input/@Output\n * - Parent owns persistence coordination if needed — rows are saved in-place on edit\n *\n * ## Runtime-generic by design (re P6.2 in plans/search-scopes-rag-plus/RAG_plan.md)\n *\n * The plan asked whether this grid should adopt the strongly-typed entity API\n * (`record.Field` accessors) instead of `BaseEntity.Get/Set`. It cannot:\n * the component is parameterized by `ChildEntityName` and `Columns[].Field`,\n * both runtime strings, so the entity class is unknown at compile time.\n * Picking a concrete type would force one consumer per child-entity flavor\n * (SearchScopeProvider, SearchScopeEntity, SearchScopeExternalIndex,\n * SearchScopeStorageAccount, AIAgentSearchScope, plus future ones), defeating\n * the point of the abstraction.\n *\n * Mitigation: a runtime sanity check (`Entity.GetFieldByName`) confirms each\n * column's `Field` name exists on the loaded entity before any Get/Set is\n * issued. This catches typos / schema drift at first render rather than\n * silently writing to a non-existent property. See `assertFieldsExist()`.\n *\n * @module @memberjunction/ng-search\n */\n\nimport {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input,\n OnDestroy,\n Output,\n inject\n} from '@angular/core';\nimport { BaseEntity, LogError, Metadata, RunView } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/** Supported inline-edit types for a scope-child grid column. */\nexport type SearchScopeChildGridColumnType =\n | 'text'\n | 'number'\n | 'checkbox'\n | 'code' // Monospace textarea (Nunjucks filters, SQL, JSON)\n | 'textarea'\n | 'lookup' // Dropdown populated from a related entity\n | 'select'; // Dropdown populated from a fixed option list\n\n/** Declarative spec for a single grid column. */\nexport interface SearchScopeChildGridColumn {\n /** BaseEntity field name (e.g. 'SearchProviderID'). */\n Field: string;\n /** Column header label. */\n Label: string;\n /** Editor type. */\n Type: SearchScopeChildGridColumnType;\n /** Placeholder text for empty cells. */\n Placeholder?: string;\n /** For 'lookup': entity name whose rows populate the dropdown. */\n LookupEntityName?: string;\n /** For 'lookup': which field of the lookup entity is displayed. Defaults to 'Name'. */\n LookupDisplayField?: string;\n /** For 'lookup': optional ExtraFilter to constrain lookup rows. */\n LookupFilter?: string;\n /** For 'select': fixed option list. */\n Options?: Array<{ Label: string; Value: string | number | boolean }>;\n /** CSS width (e.g. '140px'). */\n Width?: string;\n /** True to make the cell read-only. */\n ReadOnly?: boolean;\n}\n\n/** Row as rendered in the grid. Wraps a BaseEntity with a transient \"dirty\" flag. */\ninterface GridRow {\n /** The underlying BaseEntity record. */\n Entity: BaseEntity;\n /** Cached display value for lookup columns, keyed by field name. */\n LookupLabels: Record<string, string>;\n /** True while an inline save is in flight. */\n Saving: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-scope-child-grid',\n templateUrl: './search-scope-child-grid.component.html',\n styleUrls: ['./search-scope-child-grid.component.css']\n})\nexport class SearchScopeChildGridComponent implements OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n // ─── Inputs ───────────────────────────────────────────────────────────────\n\n private _parentID: string | null = null;\n /**\n * The parent record ID to filter / attach rows to. For a `MJ: Search Scopes` parent\n * this is the scope ID; for an `MJ: AI Agents` parent (assigning scopes to an agent)\n * this is the agent ID. Paired with `ParentFieldName` which names the FK column.\n */\n @Input()\n set ParentID(value: string | null) {\n if (value === this._parentID) return;\n this._parentID = value;\n if (value) {\n void this.LoadRows();\n } else {\n this.Rows = [];\n }\n }\n get ParentID(): string | null {\n return this._parentID;\n }\n\n /** MJ entity name of the child table (e.g. `MJ: Search Scope Providers`). */\n @Input() ChildEntityName: string = '';\n\n /** FK column on the child that references the parent SearchScope. */\n @Input() ParentFieldName: string = 'SearchScopeID';\n\n /** Column config — drives rendering of each row. */\n @Input() Columns: SearchScopeChildGridColumn[] = [];\n\n /** Button label for the \"add new row\" action. */\n @Input() AddButtonLabel: string = '+ Add row';\n\n /** Empty-state copy when the grid has zero rows. */\n @Input() EmptyMessage: string = 'No rows yet.';\n\n /** Optional OrderBy clause applied to the initial load. */\n @Input() OrderBy: string = '';\n\n /** Disable all editing (read-only mode). */\n @Input() Disabled: boolean = false;\n\n // ─── Outputs ──────────────────────────────────────────────────────────────\n\n /** Emitted whenever a row is successfully added or removed. */\n @Output() RowsChanged = new EventEmitter<void>();\n\n /** Emitted after a row is added. */\n @Output() RowAdded = new EventEmitter<BaseEntity>();\n\n /** Emitted after a row is removed. */\n @Output() RowRemoved = new EventEmitter<BaseEntity>();\n\n // ─── State ────────────────────────────────────────────────────────────────\n\n public Rows: GridRow[] = [];\n public IsLoading: boolean = false;\n public LoadError: string | null = null;\n\n /** Cached lookup options by lookup entity name. */\n private lookupCache = new Map<string, Array<{ ID: string; Label: string }>>();\n\n public ngOnDestroy(): void {\n // No subscriptions to clean up yet; kept for future compatibility.\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n /** Reload the grid from the server. */\n public async LoadRows(): Promise<void> {\n if (!this._parentID || !this.ChildEntityName || !this.ParentFieldName) {\n this.Rows = [];\n return;\n }\n this.IsLoading = true;\n this.LoadError = null;\n try {\n const rv = new RunView();\n const result = await rv.RunView<BaseEntity>({\n EntityName: this.ChildEntityName,\n ExtraFilter: `${this.ParentFieldName} = '${this._parentID.replace(/'/g, \"''\")}'`,\n OrderBy: this.OrderBy || '__mj_CreatedAt ASC',\n ResultType: 'entity_object'\n });\n if (!result.Success) {\n this.LoadError = result.ErrorMessage ?? 'Failed to load rows';\n this.Rows = [];\n } else {\n const rows = result.Results || [];\n // Runtime sanity check: every column's Field must be a real\n // property on the loaded entity. Catches schema drift between\n // a parent form's Columns spec and the actual entity shape\n // before the first Get/Set fires.\n if (rows.length > 0) {\n this.assertFieldsExist(rows[0]);\n }\n this.Rows = rows.map(entity => this.makeRow(entity));\n await this.hydrateLookups();\n }\n } catch (err) {\n this.LoadError = err instanceof Error ? err.message : String(err);\n this.Rows = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Add a new empty row attached to the current scope. */\n public async AddRow(): Promise<void> {\n if (this.Disabled || !this._parentID || !this.ChildEntityName) return;\n try {\n const md = new Metadata(); // global-provider-ok: child grid does not yet accept a Provider input — multi-provider threading is the team's separate Phase 6 effort\n const entity = await md.GetEntityObject<BaseEntity>(this.ChildEntityName);\n entity.Set(this.ParentFieldName, this._parentID);\n this.applyColumnDefaults(entity);\n this.Rows = [...this.Rows, this.makeRow(entity)];\n this.cdr.detectChanges();\n } catch (err) {\n LogError(`SearchScopeChildGrid: failed to create new ${this.ChildEntityName} row — ${\n err instanceof Error ? err.message : String(err)\n }`);\n }\n }\n\n /** Persist changes to a row. Returns true on success. */\n public async SaveRow(row: GridRow): Promise<boolean> {\n if (this.Disabled) return false;\n row.Saving = true;\n try {\n const ok = await row.Entity.Save();\n if (!ok) {\n LogError(`SearchScopeChildGrid: save failed for ${this.ChildEntityName}: ${\n row.Entity.LatestResult?.CompleteMessage ?? 'unknown error'\n }`);\n return false;\n }\n this.RowsChanged.emit();\n // If this was a brand-new row, emit the Added event on first successful save.\n if (!row.Entity.IsSaved) return true;\n this.RowAdded.emit(row.Entity);\n return true;\n } finally {\n row.Saving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Remove a row (deletes from DB if saved, drops from state if new). */\n public async RemoveRow(row: GridRow): Promise<void> {\n if (this.Disabled) return;\n try {\n if (row.Entity.IsSaved) {\n const ok = await row.Entity.Delete();\n if (!ok) {\n LogError(`SearchScopeChildGrid: delete failed for ${this.ChildEntityName}: ${\n row.Entity.LatestResult?.CompleteMessage ?? 'unknown error'\n }`);\n return;\n }\n }\n this.Rows = this.Rows.filter(r => r !== row);\n this.RowRemoved.emit(row.Entity);\n this.RowsChanged.emit();\n this.cdr.detectChanges();\n } catch (err) {\n LogError(`SearchScopeChildGrid: remove error — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /** Read a cell value from a row (used by the template). */\n public GetCellValue(row: GridRow, column: SearchScopeChildGridColumn): unknown {\n return row.Entity.Get(column.Field);\n }\n\n /**\n * Write a cell value back to the row and persist. Lookup columns store the ID but\n * we also refresh the cached display label so the UI stays in sync without a reload.\n */\n public async SetCellValue(\n row: GridRow,\n column: SearchScopeChildGridColumn,\n value: unknown\n ): Promise<void> {\n if (this.Disabled || column.ReadOnly) return;\n row.Entity.Set(column.Field, value);\n if (column.Type === 'lookup' && typeof value === 'string') {\n const options = column.LookupEntityName ? this.lookupCache.get(column.LookupEntityName) : undefined;\n const match = options?.find(o => UUIDsEqual(o.ID, value));\n row.LookupLabels[column.Field] = match?.Label ?? '';\n }\n await this.SaveRow(row);\n }\n\n /** Return the display label for a lookup cell. */\n public GetLookupLabel(row: GridRow, column: SearchScopeChildGridColumn): string {\n return row.LookupLabels[column.Field] ?? '';\n }\n\n /** Return the dropdown options for a lookup column. */\n public GetLookupOptions(\n column: SearchScopeChildGridColumn\n ): Array<{ ID: string; Label: string }> {\n if (!column.LookupEntityName) return [];\n return this.lookupCache.get(column.LookupEntityName) ?? [];\n }\n\n // ─── Internals ───────────────────────────────────────────────────────────\n\n /**\n * Load the set of lookup-option arrays referenced by `Columns` so dropdowns render\n * without triggering additional RunView calls per row.\n */\n private async hydrateLookups(): Promise<void> {\n const lookupColumns = this.Columns.filter(c => c.Type === 'lookup' && c.LookupEntityName);\n const toLoad = lookupColumns.filter(c => !this.lookupCache.has(c.LookupEntityName!));\n if (toLoad.length === 0) {\n this.refreshLookupLabels();\n return;\n }\n\n const rv = new RunView();\n const queries = toLoad.map(c => ({\n EntityName: c.LookupEntityName!,\n ExtraFilter: c.LookupFilter || '',\n OrderBy: `${c.LookupDisplayField ?? 'Name'} ASC`,\n Fields: ['ID', c.LookupDisplayField ?? 'Name'],\n ResultType: 'simple' as const,\n }));\n\n try {\n const results = await rv.RunViews(queries);\n toLoad.forEach((col, idx) => {\n const res = results[idx];\n if (!res.Success) {\n LogError(`SearchScopeChildGrid: lookup load failed for ${col.LookupEntityName}: ${res.ErrorMessage}`);\n this.lookupCache.set(col.LookupEntityName!, []);\n return;\n }\n const displayField = col.LookupDisplayField ?? 'Name';\n const options = (res.Results as Array<Record<string, unknown>>).map(r => ({\n ID: String(r['ID']),\n Label: String(r[displayField] ?? r['ID']),\n }));\n this.lookupCache.set(col.LookupEntityName!, options);\n });\n } catch (err) {\n LogError(`SearchScopeChildGrid: hydrateLookups error — ${err instanceof Error ? err.message : String(err)}`);\n }\n\n this.refreshLookupLabels();\n }\n\n private refreshLookupLabels(): void {\n for (const row of this.Rows) {\n for (const col of this.Columns) {\n if (col.Type !== 'lookup' || !col.LookupEntityName) continue;\n const id = row.Entity.Get(col.Field);\n if (typeof id !== 'string') continue;\n const options = this.lookupCache.get(col.LookupEntityName) ?? [];\n const match = options.find(o => UUIDsEqual(o.ID, id));\n row.LookupLabels[col.Field] = match?.Label ?? '';\n }\n }\n }\n\n private makeRow(entity: BaseEntity): GridRow {\n return {\n Entity: entity,\n LookupLabels: {},\n Saving: false,\n };\n }\n\n /** Apply `DefaultValue` from column specs when creating a new row. */\n private applyColumnDefaults(entity: BaseEntity): void {\n for (const col of this.Columns) {\n if (col.Type === 'checkbox' && entity.Get(col.Field) === null) {\n entity.Set(col.Field, true);\n }\n }\n }\n\n /**\n * Sanity-check that every column's `Field` exists on the loaded entity.\n * The component is runtime-generic by design, but each consumer's `Columns`\n * spec must match the actual entity shape; otherwise `entity.Get(col.Field)`\n * silently returns null and `entity.Set(col.Field, ...)` silently no-ops,\n * masking schema drift. Logging here surfaces the mismatch at first render.\n *\n * `entity.Fields` is the canonical metadata-driven list of fields the\n * BaseEntity subclass exposes. Comparing the column spec's `Field` against\n * that list catches typos and stale Columns arrays in custom forms.\n */\n private assertFieldsExist(sample: BaseEntity): void {\n const knownFields = new Set(sample.Fields.map(f => f.Name.toLowerCase()));\n const unknown = this.Columns\n .filter(c => !c.ReadOnly)\n .map(c => c.Field)\n .filter(f => !knownFields.has(f.toLowerCase()));\n if (unknown.length > 0) {\n LogError(\n `SearchScopeChildGridComponent: Columns spec references fields ` +\n `not found on entity '${this.ChildEntityName}': ${unknown.join(', ')}. ` +\n `This indicates schema drift — update the parent form's Columns ` +\n `array to match the entity's typed properties.`,\n );\n }\n }\n}\n","<div class=\"scope-grid\" [class.disabled]=\"Disabled\">\n @if (IsLoading) {\n <div class=\"scope-grid-loading\">Loading…</div>\n } @else if (LoadError) {\n <div class=\"scope-grid-error\">\n <i class=\"fa-solid fa-triangle-exclamation\" aria-hidden=\"true\"></i>\n {{ LoadError }}\n </div>\n } @else {\n <table class=\"scope-grid-table\">\n <thead>\n <tr>\n @for (col of Columns; track col.Field) {\n <th [style.width]=\"col.Width || null\">{{ col.Label }}</th>\n }\n <th class=\"scope-grid-actions-col\" aria-hidden=\"true\"></th>\n </tr>\n </thead>\n <tbody>\n @if (Rows.length === 0) {\n <tr>\n <td [attr.colspan]=\"Columns.length + 1\" class=\"scope-grid-empty\">\n {{ EmptyMessage }}\n </td>\n </tr>\n } @else {\n @for (row of Rows; track row.Entity) {\n <tr [class.saving]=\"row.Saving\">\n @for (col of Columns; track col.Field) {\n <td [style.width]=\"col.Width || null\">\n @switch (col.Type) {\n @case ('checkbox') {\n <input\n type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"!!GetCellValue(row, col)\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).checked)\">\n }\n @case ('number') {\n <input\n type=\"number\"\n class=\"mj-input scope-grid-input\"\n [value]=\"$any(GetCellValue(row, col)) ?? ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).valueAsNumber)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-textarea scope-grid-textarea\"\n rows=\"2\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\"></textarea>\n }\n @case ('code') {\n <textarea\n class=\"mj-textarea scope-grid-code\"\n rows=\"2\"\n spellcheck=\"false\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\"></textarea>\n }\n @case ('lookup') {\n <select\n class=\"mj-input scope-grid-select\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n <option value=\"\">— select —</option>\n @for (opt of GetLookupOptions(col); track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Label }}</option>\n }\n </select>\n }\n @case ('select') {\n <select\n class=\"mj-input scope-grid-select\"\n [value]=\"$any(GetCellValue(row, col)) ?? ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n @for (opt of col.Options; track opt.Value) {\n <option [value]=\"$any(opt.Value)\">{{ opt.Label }}</option>\n }\n </select>\n }\n @default {\n <input\n type=\"text\"\n class=\"mj-input scope-grid-input\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n }\n }\n </td>\n }\n <td class=\"scope-grid-actions-col\">\n <button\n type=\"button\"\n class=\"scope-grid-icon-btn\"\n title=\"Remove row\"\n [disabled]=\"Disabled || row.Saving\"\n (click)=\"RemoveRow(row)\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n\n @if (!Disabled) {\n <div class=\"scope-grid-footer\">\n <button type=\"button\" class=\"scope-grid-add-btn\" (click)=\"AddRow()\">\n {{ AddButtonLabel }}\n </button>\n </div>\n }\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"search-scope-child-grid.component.js","sourceRoot":"","sources":["../../src/lib/search-scope-child-grid.component.ts","../../src/lib/search-scope-child-grid.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Generic Search Scope Child Grid\n *\n * A parameter-driven grid for editing the child-collection tabs of a Search Scope:\n * - Providers (`MJ: Search Scope Providers`)\n * - External Indexes (`MJ: Search Scope External Indexes`)\n * - Entities (`MJ: Search Scope Entities`)\n * - Storage Accounts (`MJ: Search Scope Storage Accounts`)\n *\n * Also reused on the AI Agent form for assigning scopes to an agent (the\n * `MJ: AI Agent Search Scopes` join table). The `ParentID` + `ParentFieldName`\n * inputs keep it generic — parent can be a SearchScope OR an AI Agent.\n *\n * One component, many configurations. The parent passes:\n * - `ParentID` — the parent record ID (SearchScope ID, AI Agent ID, etc.)\n * - `ChildEntityName` — the MJ entity name of the child table\n * - `ParentFieldName` — the FK column on the child that references the parent\n * - `Columns` — declarative column spec (type, label, optional lookup source)\n *\n * This is a **Generic component** (see `packages/Angular/Generic/CLAUDE.md`):\n * - No Router / ActivatedRoute imports\n * - All state flows through @Input/@Output\n * - Parent owns persistence coordination if needed — rows are saved in-place on edit\n *\n * ## Runtime-generic by design (re P6.2 in plans/search-scopes-rag-plus/RAG_plan.md)\n *\n * The plan asked whether this grid should adopt the strongly-typed entity API\n * (`record.Field` accessors) instead of `BaseEntity.Get/Set`. It cannot:\n * the component is parameterized by `ChildEntityName` and `Columns[].Field`,\n * both runtime strings, so the entity class is unknown at compile time.\n * Picking a concrete type would force one consumer per child-entity flavor\n * (SearchScopeProvider, SearchScopeEntity, SearchScopeExternalIndex,\n * SearchScopeStorageAccount, AIAgentSearchScope, plus future ones), defeating\n * the point of the abstraction.\n *\n * Mitigation: a runtime sanity check (`Entity.GetFieldByName`) confirms each\n * column's `Field` name exists on the loaded entity before any Get/Set is\n * issued. This catches typos / schema drift at first render rather than\n * silently writing to a non-existent property. See `assertFieldsExist()`.\n *\n * @module @memberjunction/ng-search\n */\n\nimport {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n Input,\n OnDestroy,\n Output,\n inject\n} from '@angular/core';\nimport { BaseEntity, LogError, Metadata, RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/** Supported inline-edit types for a scope-child grid column. */\nexport type SearchScopeChildGridColumnType =\n | 'text'\n | 'number'\n | 'checkbox'\n | 'code' // Monospace textarea (Nunjucks filters, SQL, JSON)\n | 'textarea'\n | 'lookup' // Dropdown populated from a related entity\n | 'select'; // Dropdown populated from a fixed option list\n\n/** Declarative spec for a single grid column. */\nexport interface SearchScopeChildGridColumn {\n /** BaseEntity field name (e.g. 'SearchProviderID'). */\n Field: string;\n /** Column header label. */\n Label: string;\n /** Editor type. */\n Type: SearchScopeChildGridColumnType;\n /** Placeholder text for empty cells. */\n Placeholder?: string;\n /** For 'lookup': entity name whose rows populate the dropdown. */\n LookupEntityName?: string;\n /** For 'lookup': which field of the lookup entity is displayed. Defaults to 'Name'. */\n LookupDisplayField?: string;\n /** For 'lookup': optional ExtraFilter to constrain lookup rows. */\n LookupFilter?: string;\n /** For 'select': fixed option list. */\n Options?: Array<{ Label: string; Value: string | number | boolean }>;\n /** CSS width (e.g. '140px'). */\n Width?: string;\n /** True to make the cell read-only. */\n ReadOnly?: boolean;\n}\n\n/** Row as rendered in the grid. Wraps a BaseEntity with a transient \"dirty\" flag. */\ninterface GridRow {\n /** The underlying BaseEntity record. */\n Entity: BaseEntity;\n /** Cached display value for lookup columns, keyed by field name. */\n LookupLabels: Record<string, string>;\n /** True while an inline save is in flight. */\n Saving: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-scope-child-grid',\n templateUrl: './search-scope-child-grid.component.html',\n styleUrls: ['./search-scope-child-grid.component.css']\n})\nexport class SearchScopeChildGridComponent extends BaseAngularComponent implements OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n // ─── Inputs ───────────────────────────────────────────────────────────────\n\n private _parentID: string | null = null;\n /**\n * The parent record ID to filter / attach rows to. For a `MJ: Search Scopes` parent\n * this is the scope ID; for an `MJ: AI Agents` parent (assigning scopes to an agent)\n * this is the agent ID. Paired with `ParentFieldName` which names the FK column.\n */\n @Input()\n set ParentID(value: string | null) {\n if (value === this._parentID) return;\n this._parentID = value;\n if (value) {\n void this.LoadRows();\n } else {\n this.Rows = [];\n }\n }\n get ParentID(): string | null {\n return this._parentID;\n }\n\n /** MJ entity name of the child table (e.g. `MJ: Search Scope Providers`). */\n @Input() ChildEntityName: string = '';\n\n /** FK column on the child that references the parent SearchScope. */\n @Input() ParentFieldName: string = 'SearchScopeID';\n\n /** Column config — drives rendering of each row. */\n @Input() Columns: SearchScopeChildGridColumn[] = [];\n\n /** Button label for the \"add new row\" action. */\n @Input() AddButtonLabel: string = '+ Add row';\n\n /** Empty-state copy when the grid has zero rows. */\n @Input() EmptyMessage: string = 'No rows yet.';\n\n /** Optional OrderBy clause applied to the initial load. */\n @Input() OrderBy: string = '';\n\n /** Disable all editing (read-only mode). */\n @Input() Disabled: boolean = false;\n\n // ─── Outputs ──────────────────────────────────────────────────────────────\n\n /** Emitted whenever a row is successfully added or removed. */\n @Output() RowsChanged = new EventEmitter<void>();\n\n /** Emitted after a row is added. */\n @Output() RowAdded = new EventEmitter<BaseEntity>();\n\n /** Emitted after a row is removed. */\n @Output() RowRemoved = new EventEmitter<BaseEntity>();\n\n // ─── State ────────────────────────────────────────────────────────────────\n\n public Rows: GridRow[] = [];\n public IsLoading: boolean = false;\n public LoadError: string | null = null;\n\n /** Cached lookup options by lookup entity name. */\n private lookupCache = new Map<string, Array<{ ID: string; Label: string }>>();\n\n public ngOnDestroy(): void {\n // No subscriptions to clean up yet; kept for future compatibility.\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n /** Reload the grid from the server. */\n public async LoadRows(): Promise<void> {\n if (!this._parentID || !this.ChildEntityName || !this.ParentFieldName) {\n this.Rows = [];\n return;\n }\n this.IsLoading = true;\n this.LoadError = null;\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<BaseEntity>({\n EntityName: this.ChildEntityName,\n ExtraFilter: `${this.ParentFieldName} = '${this._parentID.replace(/'/g, \"''\")}'`,\n OrderBy: this.OrderBy || '__mj_CreatedAt ASC',\n ResultType: 'entity_object'\n });\n if (!result.Success) {\n this.LoadError = result.ErrorMessage ?? 'Failed to load rows';\n this.Rows = [];\n } else {\n const rows = result.Results || [];\n // Runtime sanity check: every column's Field must be a real\n // property on the loaded entity. Catches schema drift between\n // a parent form's Columns spec and the actual entity shape\n // before the first Get/Set fires.\n if (rows.length > 0) {\n this.assertFieldsExist(rows[0]);\n }\n this.Rows = rows.map(entity => this.makeRow(entity));\n await this.hydrateLookups();\n }\n } catch (err) {\n this.LoadError = err instanceof Error ? err.message : String(err);\n this.Rows = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Add a new empty row attached to the current scope. */\n public async AddRow(): Promise<void> {\n if (this.Disabled || !this._parentID || !this.ChildEntityName) return;\n try {\n // This class extends BaseAngularComponent, so it has accepted a `Provider` input all\n // along — the note claiming otherwise was stale.\n const md = this.ProviderToUse;\n const entity = await md.GetEntityObject<BaseEntity>(this.ChildEntityName);\n entity.Set(this.ParentFieldName, this._parentID);\n this.applyColumnDefaults(entity);\n this.Rows = [...this.Rows, this.makeRow(entity)];\n this.cdr.detectChanges();\n } catch (err) {\n LogError(`SearchScopeChildGrid: failed to create new ${this.ChildEntityName} row — ${\n err instanceof Error ? err.message : String(err)\n }`);\n }\n }\n\n /** Persist changes to a row. Returns true on success. */\n public async SaveRow(row: GridRow): Promise<boolean> {\n if (this.Disabled) return false;\n row.Saving = true;\n try {\n const ok = await row.Entity.Save();\n if (!ok) {\n LogError(`SearchScopeChildGrid: save failed for ${this.ChildEntityName}: ${\n row.Entity.LatestResult?.CompleteMessage ?? 'unknown error'\n }`);\n return false;\n }\n this.RowsChanged.emit();\n // If this was a brand-new row, emit the Added event on first successful save.\n if (!row.Entity.IsSaved) return true;\n this.RowAdded.emit(row.Entity);\n return true;\n } finally {\n row.Saving = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Remove a row (deletes from DB if saved, drops from state if new). */\n public async RemoveRow(row: GridRow): Promise<void> {\n if (this.Disabled) return;\n try {\n if (row.Entity.IsSaved) {\n const ok = await row.Entity.Delete();\n if (!ok) {\n LogError(`SearchScopeChildGrid: delete failed for ${this.ChildEntityName}: ${\n row.Entity.LatestResult?.CompleteMessage ?? 'unknown error'\n }`);\n return;\n }\n }\n this.Rows = this.Rows.filter(r => r !== row);\n this.RowRemoved.emit(row.Entity);\n this.RowsChanged.emit();\n this.cdr.detectChanges();\n } catch (err) {\n LogError(`SearchScopeChildGrid: remove error — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /** Read a cell value from a row (used by the template). */\n public GetCellValue(row: GridRow, column: SearchScopeChildGridColumn): unknown {\n return row.Entity.Get(column.Field);\n }\n\n /**\n * Write a cell value back to the row and persist. Lookup columns store the ID but\n * we also refresh the cached display label so the UI stays in sync without a reload.\n */\n public async SetCellValue(\n row: GridRow,\n column: SearchScopeChildGridColumn,\n value: unknown\n ): Promise<void> {\n if (this.Disabled || column.ReadOnly) return;\n row.Entity.Set(column.Field, value);\n if (column.Type === 'lookup' && typeof value === 'string') {\n const options = column.LookupEntityName ? this.lookupCache.get(column.LookupEntityName) : undefined;\n const match = options?.find(o => UUIDsEqual(o.ID, value));\n row.LookupLabels[column.Field] = match?.Label ?? '';\n }\n await this.SaveRow(row);\n }\n\n /** Return the display label for a lookup cell. */\n public GetLookupLabel(row: GridRow, column: SearchScopeChildGridColumn): string {\n return row.LookupLabels[column.Field] ?? '';\n }\n\n /** Return the dropdown options for a lookup column. */\n public GetLookupOptions(\n column: SearchScopeChildGridColumn\n ): Array<{ ID: string; Label: string }> {\n if (!column.LookupEntityName) return [];\n return this.lookupCache.get(column.LookupEntityName) ?? [];\n }\n\n // ─── Internals ───────────────────────────────────────────────────────────\n\n /**\n * Load the set of lookup-option arrays referenced by `Columns` so dropdowns render\n * without triggering additional RunView calls per row.\n */\n private async hydrateLookups(): Promise<void> {\n const lookupColumns = this.Columns.filter(c => c.Type === 'lookup' && c.LookupEntityName);\n const toLoad = lookupColumns.filter(c => !this.lookupCache.has(c.LookupEntityName!));\n if (toLoad.length === 0) {\n this.refreshLookupLabels();\n return;\n }\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const queries = toLoad.map(c => ({\n EntityName: c.LookupEntityName!,\n ExtraFilter: c.LookupFilter || '',\n OrderBy: `${c.LookupDisplayField ?? 'Name'} ASC`,\n Fields: ['ID', c.LookupDisplayField ?? 'Name'],\n ResultType: 'simple' as const,\n }));\n\n try {\n const results = await rv.RunViews(queries);\n toLoad.forEach((col, idx) => {\n const res = results[idx];\n if (!res.Success) {\n LogError(`SearchScopeChildGrid: lookup load failed for ${col.LookupEntityName}: ${res.ErrorMessage}`);\n this.lookupCache.set(col.LookupEntityName!, []);\n return;\n }\n const displayField = col.LookupDisplayField ?? 'Name';\n const options = (res.Results as Array<Record<string, unknown>>).map(r => ({\n ID: String(r['ID']),\n Label: String(r[displayField] ?? r['ID']),\n }));\n this.lookupCache.set(col.LookupEntityName!, options);\n });\n } catch (err) {\n LogError(`SearchScopeChildGrid: hydrateLookups error — ${err instanceof Error ? err.message : String(err)}`);\n }\n\n this.refreshLookupLabels();\n }\n\n private refreshLookupLabels(): void {\n for (const row of this.Rows) {\n for (const col of this.Columns) {\n if (col.Type !== 'lookup' || !col.LookupEntityName) continue;\n const id = row.Entity.Get(col.Field);\n if (typeof id !== 'string') continue;\n const options = this.lookupCache.get(col.LookupEntityName) ?? [];\n const match = options.find(o => UUIDsEqual(o.ID, id));\n row.LookupLabels[col.Field] = match?.Label ?? '';\n }\n }\n }\n\n private makeRow(entity: BaseEntity): GridRow {\n return {\n Entity: entity,\n LookupLabels: {},\n Saving: false,\n };\n }\n\n /** Apply `DefaultValue` from column specs when creating a new row. */\n private applyColumnDefaults(entity: BaseEntity): void {\n for (const col of this.Columns) {\n if (col.Type === 'checkbox' && entity.Get(col.Field) === null) {\n entity.Set(col.Field, true);\n }\n }\n }\n\n /**\n * Sanity-check that every column's `Field` exists on the loaded entity.\n * The component is runtime-generic by design, but each consumer's `Columns`\n * spec must match the actual entity shape; otherwise `entity.Get(col.Field)`\n * silently returns null and `entity.Set(col.Field, ...)` silently no-ops,\n * masking schema drift. Logging here surfaces the mismatch at first render.\n *\n * `entity.Fields` is the canonical metadata-driven list of fields the\n * BaseEntity subclass exposes. Comparing the column spec's `Field` against\n * that list catches typos and stale Columns arrays in custom forms.\n */\n private assertFieldsExist(sample: BaseEntity): void {\n const knownFields = new Set(sample.Fields.map(f => f.Name.toLowerCase()));\n const unknown = this.Columns\n .filter(c => !c.ReadOnly)\n .map(c => c.Field)\n .filter(f => !knownFields.has(f.toLowerCase()));\n if (unknown.length > 0) {\n LogError(\n `SearchScopeChildGridComponent: Columns spec references fields ` +\n `not found on entity '${this.ChildEntityName}': ${unknown.join(', ')}. ` +\n `This indicates schema drift — update the parent form's Columns ` +\n `array to match the entity's typed properties.`,\n );\n }\n }\n}\n","<div class=\"scope-grid\" [class.disabled]=\"Disabled\">\n @if (IsLoading) {\n <div class=\"scope-grid-loading\">Loading…</div>\n } @else if (LoadError) {\n <div class=\"scope-grid-error\">\n <i class=\"fa-solid fa-triangle-exclamation\" aria-hidden=\"true\"></i>\n {{ LoadError }}\n </div>\n } @else {\n <table class=\"scope-grid-table\">\n <thead>\n <tr>\n @for (col of Columns; track col.Field) {\n <th [style.width]=\"col.Width || null\">{{ col.Label }}</th>\n }\n <th class=\"scope-grid-actions-col\" aria-hidden=\"true\"></th>\n </tr>\n </thead>\n <tbody>\n @if (Rows.length === 0) {\n <tr>\n <td [attr.colspan]=\"Columns.length + 1\" class=\"scope-grid-empty\">\n {{ EmptyMessage }}\n </td>\n </tr>\n } @else {\n @for (row of Rows; track row.Entity) {\n <tr [class.saving]=\"row.Saving\">\n @for (col of Columns; track col.Field) {\n <td [style.width]=\"col.Width || null\">\n @switch (col.Type) {\n @case ('checkbox') {\n <input\n type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"!!GetCellValue(row, col)\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).checked)\">\n }\n @case ('number') {\n <input\n type=\"number\"\n class=\"mj-input scope-grid-input\"\n [value]=\"$any(GetCellValue(row, col)) ?? ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).valueAsNumber)\">\n }\n @case ('textarea') {\n <textarea\n class=\"mj-textarea scope-grid-textarea\"\n rows=\"2\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\"></textarea>\n }\n @case ('code') {\n <textarea\n class=\"mj-textarea scope-grid-code\"\n rows=\"2\"\n spellcheck=\"false\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\"></textarea>\n }\n @case ('lookup') {\n <select\n class=\"mj-input scope-grid-select\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n <option value=\"\">— select —</option>\n @for (opt of GetLookupOptions(col); track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Label }}</option>\n }\n </select>\n }\n @case ('select') {\n <select\n class=\"mj-input scope-grid-select\"\n [value]=\"$any(GetCellValue(row, col)) ?? ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n @for (opt of col.Options; track opt.Value) {\n <option [value]=\"$any(opt.Value)\">{{ opt.Label }}</option>\n }\n </select>\n }\n @default {\n <input\n type=\"text\"\n class=\"mj-input scope-grid-input\"\n [value]=\"$any(GetCellValue(row, col)) || ''\"\n [placeholder]=\"col.Placeholder || ''\"\n [disabled]=\"Disabled || col.ReadOnly\"\n (change)=\"SetCellValue(row, col, $any($event.target).value)\">\n }\n }\n </td>\n }\n <td class=\"scope-grid-actions-col\">\n <button\n type=\"button\"\n class=\"scope-grid-icon-btn\"\n title=\"Remove row\"\n [disabled]=\"Disabled || row.Saving\"\n (click)=\"RemoveRow(row)\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n\n @if (!Disabled) {\n <div class=\"scope-grid-footer\">\n <button type=\"button\" class=\"scope-grid-add-btn\" (click)=\"AddRow()\">\n {{ AddButtonLabel }}\n </button>\n </div>\n }\n }\n</div>\n"]}
|
package/package.json
CHANGED
|
@@ -1,40 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-search",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0-edge.0",
|
|
4
4
|
"description": "MemberJunction: Reusable search overlay and results components - command palette / Spotlight style search",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"/dist"
|
|
9
9
|
],
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "vitest run",
|
|
12
|
-
"build": "ngc",
|
|
13
|
-
"test:watch": "vitest"
|
|
14
|
-
},
|
|
15
10
|
"keywords": [],
|
|
16
11
|
"author": "MemberJunction.com",
|
|
17
12
|
"license": "ISC",
|
|
18
13
|
"devDependencies": {
|
|
19
14
|
"@angular/compiler": "21.1.3",
|
|
20
15
|
"@angular/compiler-cli": "21.1.3",
|
|
21
|
-
"@memberjunction/ng-test-utils": "
|
|
16
|
+
"@memberjunction/ng-test-utils": "6.1.0-edge.0",
|
|
22
17
|
"vitest": "^4.0.18"
|
|
23
18
|
},
|
|
24
19
|
"peerDependencies": {
|
|
25
20
|
"@angular/common": "21.1.3",
|
|
26
21
|
"@angular/core": "21.1.3",
|
|
27
|
-
"@angular/router": "21.1.3",
|
|
28
22
|
"@angular/forms": "21.1.3"
|
|
29
23
|
},
|
|
30
24
|
"dependencies": {
|
|
31
|
-
"@memberjunction/ng-ui-components": "
|
|
32
|
-
"@memberjunction/core": "
|
|
33
|
-
"@memberjunction/ng-base-types": "
|
|
34
|
-
"@memberjunction/global": "
|
|
35
|
-
"@memberjunction/graphql-dataprovider": "
|
|
36
|
-
"@memberjunction/core-entities": "
|
|
37
|
-
"@memberjunction/ng-shared-generic": "
|
|
25
|
+
"@memberjunction/ng-ui-components": "6.1.0-edge.0",
|
|
26
|
+
"@memberjunction/core": "6.1.0-edge.0",
|
|
27
|
+
"@memberjunction/ng-base-types": "6.1.0-edge.0",
|
|
28
|
+
"@memberjunction/global": "6.1.0-edge.0",
|
|
29
|
+
"@memberjunction/graphql-dataprovider": "6.1.0-edge.0",
|
|
30
|
+
"@memberjunction/core-entities": "6.1.0-edge.0",
|
|
31
|
+
"@memberjunction/ng-shared-generic": "6.1.0-edge.0",
|
|
38
32
|
"rxjs": "^7.8.2",
|
|
39
33
|
"tslib": "^2.8.1"
|
|
40
34
|
},
|
|
@@ -42,5 +36,12 @@
|
|
|
42
36
|
"repository": {
|
|
43
37
|
"type": "git",
|
|
44
38
|
"url": "https://github.com/MemberJunction/MJ"
|
|
39
|
+
},
|
|
40
|
+
"mjUILayer": "widgets",
|
|
41
|
+
"scripts": {
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:types": "tsc --noEmit -p tsconfig.spec.json",
|
|
44
|
+
"build": "ngc",
|
|
45
|
+
"test:watch": "vitest"
|
|
45
46
|
}
|
|
46
|
-
}
|
|
47
|
+
}
|