@memberjunction/ng-explorer-core 5.5.0 → 5.6.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.
@@ -1,13 +1,48 @@
1
- import { EventEmitter } from '@angular/core';
2
- import { RunViewParams } from '@memberjunction/core';
1
+ import { EventEmitter, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { EntityInfo } from '@memberjunction/core';
3
+ import { NavigationService } from '@memberjunction/ng-shared';
4
+ import { DataLoadedEvent, RecordOpenedEvent, EntityViewerConfig, EntityViewMode, GridToolbarConfig } from '@memberjunction/ng-entity-viewer';
3
5
  import * as i0 from "@angular/core";
4
- export declare class SingleSearchResultComponent {
6
+ type SearchState = 'loading' | 'no-results' | 'single-result' | 'viewer';
7
+ export declare class SingleSearchResultComponent implements OnChanges {
8
+ private navigationService;
9
+ private cdr;
5
10
  entity: string;
6
11
  searchInput: string;
7
- loadComplete: EventEmitter<any>;
8
- loadStarted: EventEmitter<any>;
9
- get params(): RunViewParams;
12
+ loadComplete: EventEmitter<boolean>;
13
+ loadStarted: EventEmitter<boolean>;
14
+ SearchState: SearchState;
15
+ ResultCount: number;
16
+ EntityInfo: EntityInfo | null;
17
+ CurrentViewMode: EntityViewMode;
18
+ /** Whether the current entity has date fields (enables timeline view toggle) */
19
+ get HasDateFields(): boolean;
20
+ /** Resolved icon class for the entity, matching Data Explorer's format */
21
+ get EntityIcon(): string;
22
+ /** Configuration for the entity-viewer — matches the Data Explorer's setup */
23
+ ViewerConfig: Partial<EntityViewerConfig>;
24
+ /** Grid toolbar config — minimal action bar (no search, no column chooser) */
25
+ GridToolbarConfig: Partial<GridToolbarConfig>;
26
+ constructor(navigationService: NavigationService, cdr: ChangeDetectorRef);
27
+ ngOnChanges(changes: SimpleChanges): void;
28
+ /**
29
+ * Runs a lightweight pre-query (MaxRows: 2, PK fields only) to determine result count,
30
+ * then routes to the appropriate state: no-results, single-result auto-nav, or viewer.
31
+ */
32
+ private ExecuteSearch;
33
+ private findEntityInfo;
34
+ private runPreQuery;
35
+ private setNoResults;
36
+ private navigateToSingleResult;
37
+ SetViewMode(mode: EntityViewMode): void;
38
+ OnViewModeChanged(mode: EntityViewMode): void;
39
+ OnCreateNewRecord(): void;
40
+ OnDataLoaded(event: DataLoadedEvent): void;
41
+ OnRecordOpened(event: RecordOpenedEvent): void;
42
+ /** Format entity icon to ensure proper Font Awesome class format */
43
+ private formatEntityIcon;
10
44
  static ɵfac: i0.ɵɵFactoryDeclaration<SingleSearchResultComponent, never>;
11
45
  static ɵcmp: i0.ɵɵComponentDeclaration<SingleSearchResultComponent, "mj-single-search-result", never, { "entity": { "alias": "entity"; "required": false; }; "searchInput": { "alias": "searchInput"; "required": false; }; }, { "loadComplete": "loadComplete"; "loadStarted": "loadStarted"; }, never, never, false, never>;
12
46
  }
47
+ export {};
13
48
  //# sourceMappingURL=single-search-result.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"single-search-result.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;;AAErD,qBAMa,2BAA2B;IACtB,MAAM,EAAE,MAAM,CAAM;IACpB,WAAW,EAAE,MAAM,CAAM;IACxB,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,CAA2B;IAC1D,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,CAA2B;IAE1E,IAAW,MAAM,IAAI,aAAa,CAOjC;yCAbU,2BAA2B;2CAA3B,2BAA2B;CAgBvC"}
1
+ {"version":3,"file":"single-search-result.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAyB,UAAU,EAA+B,MAAM,sBAAsB,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;;AAE7I,KAAK,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEzE,qBAMa,2BAA4B,YAAW,SAAS;IAiDzD,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,GAAG;IAjDG,MAAM,EAAE,MAAM,CAAM;IACpB,WAAW,EAAE,MAAM,CAAM;IACxB,YAAY,wBAA+B;IAC3C,WAAW,wBAA+B;IAEpD,WAAW,EAAE,WAAW,CAAa;IACrC,WAAW,SAAK;IAChB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IACrC,eAAe,EAAE,cAAc,CAAU;IAEhD,gFAAgF;IAChF,IAAW,aAAa,IAAI,OAAO,CAGlC;IAED,0EAA0E;IAC1E,IAAW,UAAU,IAAI,MAAM,CAK9B;IAED,8EAA8E;IACvE,YAAY,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAQ9C;IAEF,8EAA8E;IACvE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CASlD;gBAGQ,iBAAiB,EAAE,iBAAiB,EACpC,GAAG,EAAE,iBAAiB;IAGhC,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMzC;;;OAGG;YACW,aAAa;IAgC3B,OAAO,CAAC,cAAc;YAOR,WAAW;IAazB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,sBAAsB;IAavB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKvC,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAK7C,iBAAiB,IAAI,IAAI;IAQzB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAM1C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIrD,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;yCApKb,2BAA2B;2CAA3B,2BAA2B;CAkLvC"}
@@ -1,29 +1,307 @@
1
1
  import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { RunView, CompositeKey, EntityFieldTSType, Metadata } from '@memberjunction/core';
2
3
  import * as i0 from "@angular/core";
4
+ import * as i1 from "@memberjunction/ng-shared";
5
+ import * as i2 from "@memberjunction/ng-shared-generic";
6
+ import * as i3 from "@memberjunction/ng-entity-viewer";
7
+ import * as i4 from "@angular/common";
8
+ function SingleSearchResultComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
9
+ i0.ɵɵelementStart(0, "span", 5);
10
+ i0.ɵɵtext(1);
11
+ i0.ɵɵelementEnd();
12
+ } if (rf & 2) {
13
+ const ctx_r0 = i0.ɵɵnextContext();
14
+ i0.ɵɵadvance();
15
+ i0.ɵɵtextInterpolate1("Searching for \"", ctx_r0.searchInput, "\"...");
16
+ } }
17
+ function SingleSearchResultComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
18
+ i0.ɵɵelementStart(0, "span", 5);
19
+ i0.ɵɵtext(1);
20
+ i0.ɵɵelementEnd();
21
+ } if (rf & 2) {
22
+ const ctx_r0 = i0.ɵɵnextContext();
23
+ i0.ɵɵadvance();
24
+ i0.ɵɵtextInterpolate1("No results for \"", ctx_r0.searchInput, "\"");
25
+ } }
26
+ function SingleSearchResultComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
27
+ i0.ɵɵelementStart(0, "span", 5);
28
+ i0.ɵɵtext(1);
29
+ i0.ɵɵpipe(2, "number");
30
+ i0.ɵɵelementEnd();
31
+ } if (rf & 2) {
32
+ const ctx_r0 = i0.ɵɵnextContext();
33
+ i0.ɵɵadvance();
34
+ i0.ɵɵtextInterpolate3("", i0.ɵɵpipeBind1(2, 3, ctx_r0.ResultCount), " ", ctx_r0.ResultCount === 1 ? "result" : "results", " for \"", ctx_r0.searchInput, "\"");
35
+ } }
36
+ function SingleSearchResultComponent_Conditional_9_Conditional_8_Template(rf, ctx) { if (rf & 1) {
37
+ const _r3 = i0.ɵɵgetCurrentView();
38
+ i0.ɵɵelementStart(0, "button", 19);
39
+ i0.ɵɵlistener("click", function SingleSearchResultComponent_Conditional_9_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.SetViewMode("timeline")); });
40
+ i0.ɵɵelement(1, "i", 20);
41
+ i0.ɵɵelementEnd();
42
+ } if (rf & 2) {
43
+ const ctx_r0 = i0.ɵɵnextContext(2);
44
+ i0.ɵɵclassProp("active", ctx_r0.CurrentViewMode === "timeline");
45
+ } }
46
+ function SingleSearchResultComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
47
+ const _r2 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵelementStart(0, "div", 6)(1, "button", 11);
49
+ i0.ɵɵlistener("click", function SingleSearchResultComponent_Conditional_9_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnCreateNewRecord()); });
50
+ i0.ɵɵelement(2, "i", 12);
51
+ i0.ɵɵelementEnd();
52
+ i0.ɵɵelementStart(3, "div", 13)(4, "button", 14);
53
+ i0.ɵɵlistener("click", function SingleSearchResultComponent_Conditional_9_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.SetViewMode("grid")); });
54
+ i0.ɵɵelement(5, "i", 15);
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵelementStart(6, "button", 16);
57
+ i0.ɵɵlistener("click", function SingleSearchResultComponent_Conditional_9_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.SetViewMode("cards")); });
58
+ i0.ɵɵelement(7, "i", 17);
59
+ i0.ɵɵelementEnd();
60
+ i0.ɵɵconditionalCreate(8, SingleSearchResultComponent_Conditional_9_Conditional_8_Template, 2, 2, "button", 18);
61
+ i0.ɵɵelementEnd()();
62
+ } if (rf & 2) {
63
+ const ctx_r0 = i0.ɵɵnextContext();
64
+ i0.ɵɵadvance(4);
65
+ i0.ɵɵclassProp("active", ctx_r0.CurrentViewMode === "grid");
66
+ i0.ɵɵadvance(2);
67
+ i0.ɵɵclassProp("active", ctx_r0.CurrentViewMode === "cards");
68
+ i0.ɵɵadvance(2);
69
+ i0.ɵɵconditional(ctx_r0.HasDateFields ? 8 : -1);
70
+ } }
71
+ function SingleSearchResultComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
72
+ i0.ɵɵelementStart(0, "div", 7);
73
+ i0.ɵɵelement(1, "mj-loading", 21);
74
+ i0.ɵɵelementEnd();
75
+ } }
76
+ function SingleSearchResultComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
77
+ i0.ɵɵelementStart(0, "div", 8);
78
+ i0.ɵɵelement(1, "i", 22);
79
+ i0.ɵɵelementStart(2, "p");
80
+ i0.ɵɵtext(3, "No results found for \"");
81
+ i0.ɵɵelementStart(4, "strong");
82
+ i0.ɵɵtext(5);
83
+ i0.ɵɵelementEnd();
84
+ i0.ɵɵtext(6);
85
+ i0.ɵɵelementEnd();
86
+ i0.ɵɵelementStart(7, "p", 23);
87
+ i0.ɵɵtext(8, "Try a different search term or entity");
88
+ i0.ɵɵelementEnd()();
89
+ } if (rf & 2) {
90
+ const ctx_r0 = i0.ɵɵnextContext();
91
+ i0.ɵɵadvance(5);
92
+ i0.ɵɵtextInterpolate(ctx_r0.searchInput);
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵtextInterpolate1("\" in ", ctx_r0.entity);
95
+ } }
96
+ function SingleSearchResultComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
97
+ i0.ɵɵelementStart(0, "div", 9);
98
+ i0.ɵɵelement(1, "i", 24);
99
+ i0.ɵɵelementStart(2, "p");
100
+ i0.ɵɵtext(3, "Found 1 result \u2014 opening record...");
101
+ i0.ɵɵelementEnd()();
102
+ } }
103
+ function SingleSearchResultComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
104
+ const _r4 = i0.ɵɵgetCurrentView();
105
+ i0.ɵɵelementStart(0, "div", 10)(1, "mj-entity-viewer", 25);
106
+ i0.ɵɵlistener("viewModeChange", function SingleSearchResultComponent_Conditional_13_Template_mj_entity_viewer_viewModeChange_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnViewModeChanged($event)); })("dataLoaded", function SingleSearchResultComponent_Conditional_13_Template_mj_entity_viewer_dataLoaded_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnDataLoaded($event)); })("recordOpened", function SingleSearchResultComponent_Conditional_13_Template_mj_entity_viewer_recordOpened_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnRecordOpened($event)); })("addRequested", function SingleSearchResultComponent_Conditional_13_Template_mj_entity_viewer_addRequested_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnCreateNewRecord()); });
107
+ i0.ɵɵelementEnd()();
108
+ } if (rf & 2) {
109
+ const ctx_r0 = i0.ɵɵnextContext();
110
+ i0.ɵɵadvance();
111
+ i0.ɵɵproperty("entity", ctx_r0.EntityInfo)("viewMode", ctx_r0.CurrentViewMode)("filterText", ctx_r0.searchInput)("config", ctx_r0.ViewerConfig)("showGridToolbar", true)("gridToolbarConfig", ctx_r0.GridToolbarConfig);
112
+ } }
3
113
  export class SingleSearchResultComponent {
114
+ navigationService;
115
+ cdr;
4
116
  entity = '';
5
117
  searchInput = '';
6
118
  loadComplete = new EventEmitter();
7
119
  loadStarted = new EventEmitter();
8
- get params() {
9
- const p = {
120
+ SearchState = 'loading';
121
+ ResultCount = 0;
122
+ EntityInfo = null;
123
+ CurrentViewMode = 'grid';
124
+ /** Whether the current entity has date fields (enables timeline view toggle) */
125
+ get HasDateFields() {
126
+ if (!this.EntityInfo)
127
+ return false;
128
+ return this.EntityInfo.Fields.some(f => f.TSType === EntityFieldTSType.Date);
129
+ }
130
+ /** Resolved icon class for the entity, matching Data Explorer's format */
131
+ get EntityIcon() {
132
+ if (this.EntityInfo?.Icon) {
133
+ return this.formatEntityIcon(this.EntityInfo.Icon);
134
+ }
135
+ return 'fa-solid fa-table';
136
+ }
137
+ /** Configuration for the entity-viewer — matches the Data Explorer's setup */
138
+ ViewerConfig = {
139
+ showFilter: false,
140
+ showViewModeToggle: false,
141
+ showRecordCount: false,
142
+ showPagination: true,
143
+ serverSideFiltering: true,
144
+ serverSideSorting: true,
145
+ height: '100%'
146
+ };
147
+ /** Grid toolbar config — minimal action bar (no search, no column chooser) */
148
+ GridToolbarConfig = {
149
+ showSearch: false,
150
+ showRefresh: true,
151
+ showAdd: true,
152
+ showExport: true,
153
+ showDelete: false,
154
+ showColumnChooser: false,
155
+ showRowCount: false,
156
+ showSelectionCount: false
157
+ };
158
+ constructor(navigationService, cdr) {
159
+ this.navigationService = navigationService;
160
+ this.cdr = cdr;
161
+ }
162
+ ngOnChanges(changes) {
163
+ if ((changes['entity'] || changes['searchInput']) && this.entity && this.searchInput) {
164
+ this.ExecuteSearch();
165
+ }
166
+ }
167
+ /**
168
+ * Runs a lightweight pre-query (MaxRows: 2, PK fields only) to determine result count,
169
+ * then routes to the appropriate state: no-results, single-result auto-nav, or viewer.
170
+ */
171
+ async ExecuteSearch() {
172
+ this.SearchState = 'loading';
173
+ this.ResultCount = 0;
174
+ this.CurrentViewMode = 'grid';
175
+ this.loadStarted.emit(true);
176
+ // Resolve EntityInfo early so the header can show icon + display name during loading
177
+ const entityInfo = this.findEntityInfo();
178
+ this.EntityInfo = entityInfo ?? null;
179
+ this.cdr.detectChanges();
180
+ if (!entityInfo) {
181
+ this.setNoResults();
182
+ return;
183
+ }
184
+ const result = await this.runPreQuery(entityInfo);
185
+ if (!result.Success || result.Results.length === 0) {
186
+ this.setNoResults();
187
+ return;
188
+ }
189
+ if (result.Results.length === 1) {
190
+ this.navigateToSingleResult(entityInfo, result.Results[0]);
191
+ return;
192
+ }
193
+ // 2+ results — show the entity-viewer
194
+ this.SearchState = 'viewer';
195
+ this.cdr.detectChanges();
196
+ }
197
+ findEntityInfo() {
198
+ const md = new Metadata();
199
+ return md.Entities.find(e => e.Name.trim().toLowerCase() === this.entity.trim().toLowerCase());
200
+ }
201
+ async runPreQuery(entityInfo) {
202
+ const rv = new RunView();
203
+ const pkFields = entityInfo.PrimaryKeys.map(pk => pk.Name);
204
+ return rv.RunView({
10
205
  EntityName: this.entity,
11
- ExtraFilter: "ID IS NOT NULL", // temporary hack as ExtraFilter is required for dynamic views
206
+ ExtraFilter: 'ID IS NOT NULL',
12
207
  UserSearchString: this.searchInput,
13
- };
14
- return p;
208
+ Fields: pkFields,
209
+ ResultType: 'simple',
210
+ MaxRows: 2,
211
+ });
212
+ }
213
+ setNoResults() {
214
+ this.SearchState = 'no-results';
215
+ this.ResultCount = 0;
216
+ this.loadComplete.emit(true);
217
+ this.cdr.detectChanges();
218
+ }
219
+ navigateToSingleResult(entityInfo, record) {
220
+ this.SearchState = 'single-result';
221
+ this.ResultCount = 1;
222
+ this.cdr.detectChanges();
223
+ const compositeKey = new CompositeKey();
224
+ compositeKey.LoadFromEntityInfoAndRecord(entityInfo, record);
225
+ this.navigationService.OpenEntityRecord(entityInfo.Name, compositeKey);
226
+ this.loadComplete.emit(true);
227
+ }
228
+ // ── Header action handlers ──
229
+ SetViewMode(mode) {
230
+ this.CurrentViewMode = mode;
231
+ this.cdr.detectChanges();
15
232
  }
16
- static ɵfac = function SingleSearchResultComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SingleSearchResultComponent)(); };
17
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleSearchResultComponent, selectors: [["mj-single-search-result"]], inputs: { entity: "entity", searchInput: "searchInput" }, outputs: { loadComplete: "loadComplete", loadStarted: "loadStarted" }, standalone: false, decls: 2, vars: 0, template: function SingleSearchResultComponent_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "div");
19
- i0.ɵɵtext(1, " Needs to be implemented!\n");
233
+ OnViewModeChanged(mode) {
234
+ this.CurrentViewMode = mode;
235
+ this.cdr.detectChanges();
236
+ }
237
+ OnCreateNewRecord() {
238
+ if (this.EntityInfo) {
239
+ this.navigationService.OpenNewEntityRecord(this.EntityInfo.Name);
240
+ }
241
+ }
242
+ // ── Entity-viewer event handlers ──
243
+ OnDataLoaded(event) {
244
+ this.ResultCount = event.totalRowCount;
245
+ this.loadComplete.emit(true);
246
+ this.cdr.detectChanges();
247
+ }
248
+ OnRecordOpened(event) {
249
+ this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);
250
+ }
251
+ /** Format entity icon to ensure proper Font Awesome class format */
252
+ formatEntityIcon(icon) {
253
+ if (!icon) {
254
+ return 'fa-solid fa-table';
255
+ }
256
+ if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||
257
+ icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||
258
+ icon.startsWith('fa ')) {
259
+ return icon;
260
+ }
261
+ if (icon.startsWith('fa-')) {
262
+ return `fa-solid ${icon}`;
263
+ }
264
+ return `fa-solid fa-${icon}`;
265
+ }
266
+ static ɵfac = function SingleSearchResultComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SingleSearchResultComponent)(i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
267
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleSearchResultComponent, selectors: [["mj-single-search-result"]], inputs: { entity: "entity", searchInput: "searchInput" }, outputs: { loadComplete: "loadComplete", loadStarted: "loadStarted" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 14, vars: 9, consts: [[1, "search-result-container"], [1, "content-header"], [1, "header-left"], [1, "entity-icon"], [1, "entity-title"], [1, "record-count"], [1, "header-right"], [1, "loading-container"], [1, "empty-state"], [1, "single-result-state"], [1, "viewer-container"], ["title", "New Record", 1, "header-action-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "view-mode-toggle"], ["title", "Grid View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["title", "Cards View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-grip"], ["title", "Timeline View", 1, "toggle-btn", 3, "active"], ["title", "Timeline View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-timeline"], ["text", "Searching..."], [1, "fa-solid", "fa-magnifying-glass", "empty-icon"], [1, "empty-hint"], [1, "fa-solid", "fa-arrow-right", "redirect-icon"], [3, "viewModeChange", "dataLoaded", "recordOpened", "addRequested", "entity", "viewMode", "filterText", "config", "showGridToolbar", "gridToolbarConfig"]], template: function SingleSearchResultComponent_Template(rf, ctx) { if (rf & 1) {
268
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
269
+ i0.ɵɵelement(3, "i", 3);
270
+ i0.ɵɵelementStart(4, "h2", 4);
271
+ i0.ɵɵtext(5);
272
+ i0.ɵɵelementEnd();
273
+ i0.ɵɵconditionalCreate(6, SingleSearchResultComponent_Conditional_6_Template, 2, 1, "span", 5)(7, SingleSearchResultComponent_Conditional_7_Template, 2, 1, "span", 5)(8, SingleSearchResultComponent_Conditional_8_Template, 3, 5, "span", 5);
274
+ i0.ɵɵelementEnd();
275
+ i0.ɵɵconditionalCreate(9, SingleSearchResultComponent_Conditional_9_Template, 9, 5, "div", 6);
276
+ i0.ɵɵelementEnd();
277
+ i0.ɵɵconditionalCreate(10, SingleSearchResultComponent_Conditional_10_Template, 2, 0, "div", 7);
278
+ i0.ɵɵconditionalCreate(11, SingleSearchResultComponent_Conditional_11_Template, 9, 2, "div", 8);
279
+ i0.ɵɵconditionalCreate(12, SingleSearchResultComponent_Conditional_12_Template, 4, 0, "div", 9);
280
+ i0.ɵɵconditionalCreate(13, SingleSearchResultComponent_Conditional_13_Template, 2, 6, "div", 10);
20
281
  i0.ɵɵelementEnd();
21
- } }, encapsulation: 2 });
282
+ } if (rf & 2) {
283
+ i0.ɵɵadvance(3);
284
+ i0.ɵɵclassMap(ctx.EntityIcon);
285
+ i0.ɵɵadvance(2);
286
+ i0.ɵɵtextInterpolate((ctx.EntityInfo == null ? null : ctx.EntityInfo.DisplayNameOrName) || ctx.entity);
287
+ i0.ɵɵadvance();
288
+ i0.ɵɵconditional(ctx.SearchState === "loading" ? 6 : ctx.SearchState === "no-results" ? 7 : ctx.ResultCount > 0 ? 8 : -1);
289
+ i0.ɵɵadvance(3);
290
+ i0.ɵɵconditional(ctx.SearchState === "viewer" && ctx.EntityInfo ? 9 : -1);
291
+ i0.ɵɵadvance();
292
+ i0.ɵɵconditional(ctx.SearchState === "loading" ? 10 : -1);
293
+ i0.ɵɵadvance();
294
+ i0.ɵɵconditional(ctx.SearchState === "no-results" ? 11 : -1);
295
+ i0.ɵɵadvance();
296
+ i0.ɵɵconditional(ctx.SearchState === "single-result" ? 12 : -1);
297
+ i0.ɵɵadvance();
298
+ i0.ɵɵconditional(ctx.SearchState === "viewer" && ctx.EntityInfo ? 13 : -1);
299
+ } }, dependencies: [i2.LoadingComponent, i3.EntityViewerComponent, i4.DecimalPipe], styles: [".search-result-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n\n\n\n.content-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #1976d2;\n}\n\n.entity-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.record-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n font-weight: 500;\n}\n\n\n\n\n\n\n.header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n\n\n.header-action-btn[_ngcontent-%COMP%] {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.header-action-btn[_ngcontent-%COMP%]:hover {\n border-color: #1976d2;\n color: #1976d2;\n background: #f5f9ff;\n}\n.header-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.toggle-btn[_ngcontent-%COMP%]:hover {\n color: #333;\n}\n.toggle-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 48px 0;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 0;\n color: #666;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: #ccc;\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 4px 0;\n font-size: 15px;\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n color: #999;\n font-size: 13px !important;\n}\n\n\n\n\n\n\n.single-result-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 0;\n color: #666;\n}\n\n.redirect-icon[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #4a90d9;\n margin-bottom: 16px;\n}\n\n.single-result-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 15px;\n margin: 4px 0;\n}\n\n\n\n\n\n\n.viewer-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}"] });
22
300
  }
23
301
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleSearchResultComponent, [{
24
302
  type: Component,
25
- args: [{ standalone: false, selector: 'mj-single-search-result', template: "<div>\n Needs to be implemented!\n</div>" }]
26
- }], null, { entity: [{
303
+ args: [{ standalone: false, selector: 'mj-single-search-result', template: "<div class=\"search-result-container\">\n <!-- Content Header \u2014 matches Data Explorer layout -->\n <div class=\"content-header\">\n <div class=\"header-left\">\n <i [class]=\"EntityIcon\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ EntityInfo?.DisplayNameOrName || entity }}</h2>\n @if (SearchState === 'loading') {\n <span class=\"record-count\">Searching for \"{{ searchInput }}\"...</span>\n } @else if (SearchState === 'no-results') {\n <span class=\"record-count\">No results for \"{{ searchInput }}\"</span>\n } @else if (ResultCount > 0) {\n <span class=\"record-count\">{{ ResultCount | number }} {{ ResultCount === 1 ? 'result' : 'results' }} for \"{{ searchInput }}\"</span>\n }\n </div>\n\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"header-right\">\n <!-- New Record -->\n <button\n class=\"header-action-btn\"\n (click)=\"OnCreateNewRecord()\"\n title=\"New Record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'grid'\"\n (click)=\"SetViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'cards'\"\n (click)=\"SetViewMode('cards')\"\n title=\"Cards View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n @if (HasDateFields) {\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'timeline'\"\n (click)=\"SetViewMode('timeline')\"\n title=\"Timeline View\">\n <i class=\"fa-solid fa-timeline\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Loading state -->\n @if (SearchState === 'loading') {\n <div class=\"loading-container\">\n <mj-loading text=\"Searching...\"></mj-loading>\n </div>\n }\n\n <!-- No results -->\n @if (SearchState === 'no-results') {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-magnifying-glass empty-icon\"></i>\n <p>No results found for \"<strong>{{ searchInput }}</strong>\" in {{ entity }}</p>\n <p class=\"empty-hint\">Try a different search term or entity</p>\n </div>\n }\n\n <!-- Single result \u2014 auto-navigating to entity form -->\n @if (SearchState === 'single-result') {\n <div class=\"single-result-state\">\n <i class=\"fa-solid fa-arrow-right redirect-icon\"></i>\n <p>Found 1 result &mdash; opening record...</p>\n </div>\n }\n\n <!-- Entity Viewer (2+ results) -->\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"viewer-container\">\n <mj-entity-viewer\n [entity]=\"EntityInfo\"\n [viewMode]=\"CurrentViewMode\"\n [filterText]=\"searchInput\"\n [config]=\"ViewerConfig\"\n [showGridToolbar]=\"true\"\n [gridToolbarConfig]=\"GridToolbarConfig\"\n (viewModeChange)=\"OnViewModeChanged($event)\"\n (dataLoaded)=\"OnDataLoaded($event)\"\n (recordOpened)=\"OnRecordOpened($event)\"\n (addRequested)=\"OnCreateNewRecord()\">\n </mj-entity-viewer>\n </div>\n }\n</div>\n", styles: [".search-result-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* ============================================\n CONTENT HEADER \u2014 matches Data Explorer layout\n ============================================ */\n\n.content-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n.entity-icon {\n font-size: 20px;\n color: #1976d2;\n}\n\n.entity-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.record-count {\n font-size: 13px;\n color: #666;\n font-weight: 500;\n}\n\n/* ============================================\n HEADER RIGHT \u2014 action buttons, view mode toggle\n ============================================ */\n\n.header-right {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n/* Action Button (New Record, Export, etc.) */\n.header-action-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.header-action-btn:hover {\n border-color: #1976d2;\n color: #1976d2;\n background: #f5f9ff;\n}\n.header-action-btn i {\n font-size: 14px;\n}\n\n/* View Mode Toggle */\n.view-mode-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.toggle-btn:hover {\n color: #333;\n}\n.toggle-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* ============================================\n LOADING STATE\n ============================================ */\n\n.loading-container {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 48px 0;\n}\n\n/* ============================================\n EMPTY STATE\n ============================================ */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 0;\n color: #666;\n}\n\n.empty-icon {\n font-size: 48px;\n color: #ccc;\n margin-bottom: 16px;\n}\n\n.empty-state p {\n margin: 4px 0;\n font-size: 15px;\n}\n\n.empty-hint {\n color: #999;\n font-size: 13px !important;\n}\n\n/* ============================================\n SINGLE RESULT \u2014 auto-nav state\n ============================================ */\n\n.single-result-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 0;\n color: #666;\n}\n\n.redirect-icon {\n font-size: 32px;\n color: #4a90d9;\n margin-bottom: 16px;\n}\n\n.single-result-state p {\n font-size: 15px;\n margin: 4px 0;\n}\n\n/* ============================================\n VIEWER CONTAINER\n ============================================ */\n\n.viewer-container {\n flex: 1;\n min-height: 0;\n}\n"] }]
304
+ }], () => [{ type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], { entity: [{
27
305
  type: Input
28
306
  }], searchInput: [{
29
307
  type: Input
@@ -32,5 +310,5 @@ export class SingleSearchResultComponent {
32
310
  }], loadStarted: [{
33
311
  type: Output
34
312
  }] }); })();
35
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SingleSearchResultComponent, { className: "SingleSearchResultComponent", filePath: "src/lib/single-search-result/single-search-result.component.ts", lineNumber: 10 }); })();
313
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SingleSearchResultComponent, { className: "SingleSearchResultComponent", filePath: "src/lib/single-search-result/single-search-result.component.ts", lineNumber: 14 }); })();
36
314
  //# sourceMappingURL=single-search-result.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"single-search-result.component.js","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts","../../../src/lib/single-search-result/single-search-result.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AASvE,MAAM,OAAO,2BAA2B;IACtB,MAAM,GAAW,EAAE,CAAC;IACpB,WAAW,GAAW,EAAE,CAAC;IACxB,YAAY,GAAsB,IAAI,YAAY,EAAO,CAAC;IAC1D,WAAW,GAAsB,IAAI,YAAY,EAAO,CAAC;IAE1E,IAAW,MAAM;QACf,MAAM,CAAC,GAAkB;YACvB,UAAU,EAAE,IAAI,CAAC,MAAM;YACvB,WAAW,EAAE,gBAAgB,EAAE,8DAA8D;YAC7F,gBAAgB,EAAE,IAAI,CAAC,WAAW;SACnC,CAAA;QACD,OAAO,CAAC,CAAC;IACX,CAAC;qHAbU,2BAA2B;6DAA3B,2BAA2B;YCTxC,2BAAK;YACD,2CACJ;YAAA,iBAAM;;;iFDOO,2BAA2B;cANvC,SAAS;6BACI,KAAK,YACP,yBAAyB;;kBAKlC,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kFAJI,2BAA2B","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { RunViewParams } from '@memberjunction/core';\n\n@Component({\n standalone: false,\n selector: 'mj-single-search-result',\n templateUrl: './single-search-result.component.html',\n styleUrls: ['./single-search-result.component.css']\n})\nexport class SingleSearchResultComponent {\n @Input() public entity: string = '';\n @Input() public searchInput: string = '';\n @Output() public loadComplete: EventEmitter<any> = new EventEmitter<any>();\n @Output() public loadStarted: EventEmitter<any> = new EventEmitter<any>();\n\n public get params(): RunViewParams {\n const p: RunViewParams = {\n EntityName: this.entity,\n ExtraFilter: \"ID IS NOT NULL\", // temporary hack as ExtraFilter is required for dynamic views\n UserSearchString: this.searchInput,\n }\n return p;\n }\n \n\n}\n","<div>\n Needs to be implemented!\n</div>"]}
1
+ {"version":3,"file":"single-search-result.component.js","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts","../../../src/lib/single-search-result/single-search-result.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';\nimport { RunView, CompositeKey, EntityInfo, EntityFieldTSType, Metadata } from '@memberjunction/core';\nimport { NavigationService } from '@memberjunction/ng-shared';\nimport { DataLoadedEvent, RecordOpenedEvent, EntityViewerConfig, EntityViewMode, GridToolbarConfig } from '@memberjunction/ng-entity-viewer';\n\ntype SearchState = 'loading' | 'no-results' | 'single-result' | 'viewer';\n\n@Component({\n standalone: false,\n selector: 'mj-single-search-result',\n templateUrl: './single-search-result.component.html',\n styleUrls: ['./single-search-result.component.css']\n})\nexport class SingleSearchResultComponent implements OnChanges {\n @Input() public entity: string = '';\n @Input() public searchInput: string = '';\n @Output() public loadComplete = new EventEmitter<boolean>();\n @Output() public loadStarted = new EventEmitter<boolean>();\n\n public SearchState: SearchState = 'loading';\n public ResultCount = 0;\n public EntityInfo: EntityInfo | null = null;\n public CurrentViewMode: EntityViewMode = 'grid';\n\n /** Whether the current entity has date fields (enables timeline view toggle) */\n public get HasDateFields(): boolean {\n if (!this.EntityInfo) return false;\n return this.EntityInfo.Fields.some(f => f.TSType === EntityFieldTSType.Date);\n }\n\n /** Resolved icon class for the entity, matching Data Explorer's format */\n public get EntityIcon(): string {\n if (this.EntityInfo?.Icon) {\n return this.formatEntityIcon(this.EntityInfo.Icon);\n }\n return 'fa-solid fa-table';\n }\n\n /** Configuration for the entity-viewer — matches the Data Explorer's setup */\n public ViewerConfig: Partial<EntityViewerConfig> = {\n showFilter: false,\n showViewModeToggle: false,\n showRecordCount: false,\n showPagination: true,\n serverSideFiltering: true,\n serverSideSorting: true,\n height: '100%'\n };\n\n /** Grid toolbar config — minimal action bar (no search, no column chooser) */\n public GridToolbarConfig: Partial<GridToolbarConfig> = {\n showSearch: false,\n showRefresh: true,\n showAdd: true,\n showExport: true,\n showDelete: false,\n showColumnChooser: false,\n showRowCount: false,\n showSelectionCount: false\n };\n\n constructor(\n private navigationService: NavigationService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n if ((changes['entity'] || changes['searchInput']) && this.entity && this.searchInput) {\n this.ExecuteSearch();\n }\n }\n\n /**\n * Runs a lightweight pre-query (MaxRows: 2, PK fields only) to determine result count,\n * then routes to the appropriate state: no-results, single-result auto-nav, or viewer.\n */\n private async ExecuteSearch(): Promise<void> {\n this.SearchState = 'loading';\n this.ResultCount = 0;\n this.CurrentViewMode = 'grid';\n this.loadStarted.emit(true);\n\n // Resolve EntityInfo early so the header can show icon + display name during loading\n const entityInfo = this.findEntityInfo();\n this.EntityInfo = entityInfo ?? null;\n this.cdr.detectChanges();\n\n if (!entityInfo) {\n this.setNoResults();\n return;\n }\n\n const result = await this.runPreQuery(entityInfo);\n if (!result.Success || result.Results.length === 0) {\n this.setNoResults();\n return;\n }\n\n if (result.Results.length === 1) {\n this.navigateToSingleResult(entityInfo, result.Results[0]);\n return;\n }\n\n // 2+ results — show the entity-viewer\n this.SearchState = 'viewer';\n this.cdr.detectChanges();\n }\n\n private findEntityInfo(): EntityInfo | undefined {\n const md = new Metadata();\n return md.Entities.find(e =>\n e.Name.trim().toLowerCase() === this.entity.trim().toLowerCase()\n );\n }\n\n private async runPreQuery(entityInfo: EntityInfo) {\n const rv = new RunView();\n const pkFields = entityInfo.PrimaryKeys.map(pk => pk.Name);\n return rv.RunView<Record<string, unknown>>({\n EntityName: this.entity,\n ExtraFilter: 'ID IS NOT NULL',\n UserSearchString: this.searchInput,\n Fields: pkFields,\n ResultType: 'simple',\n MaxRows: 2,\n });\n }\n\n private setNoResults(): void {\n this.SearchState = 'no-results';\n this.ResultCount = 0;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n private navigateToSingleResult(entityInfo: EntityInfo, record: Record<string, unknown>): void {\n this.SearchState = 'single-result';\n this.ResultCount = 1;\n this.cdr.detectChanges();\n\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, record);\n this.navigationService.OpenEntityRecord(entityInfo.Name, compositeKey);\n this.loadComplete.emit(true);\n }\n\n // ── Header action handlers ──\n\n public SetViewMode(mode: EntityViewMode): void {\n this.CurrentViewMode = mode;\n this.cdr.detectChanges();\n }\n\n public OnViewModeChanged(mode: EntityViewMode): void {\n this.CurrentViewMode = mode;\n this.cdr.detectChanges();\n }\n\n public OnCreateNewRecord(): void {\n if (this.EntityInfo) {\n this.navigationService.OpenNewEntityRecord(this.EntityInfo.Name);\n }\n }\n\n // ── Entity-viewer event handlers ──\n\n public OnDataLoaded(event: DataLoadedEvent): void {\n this.ResultCount = event.totalRowCount;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n public OnRecordOpened(event: RecordOpenedEvent): void {\n this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);\n }\n\n /** Format entity icon to ensure proper Font Awesome class format */\n private formatEntityIcon(icon: string): string {\n if (!icon) {\n return 'fa-solid fa-table';\n }\n if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||\n icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||\n icon.startsWith('fa ')) {\n return icon;\n }\n if (icon.startsWith('fa-')) {\n return `fa-solid ${icon}`;\n }\n return `fa-solid fa-${icon}`;\n }\n}\n","<div class=\"search-result-container\">\n <!-- Content Header — matches Data Explorer layout -->\n <div class=\"content-header\">\n <div class=\"header-left\">\n <i [class]=\"EntityIcon\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ EntityInfo?.DisplayNameOrName || entity }}</h2>\n @if (SearchState === 'loading') {\n <span class=\"record-count\">Searching for \"{{ searchInput }}\"...</span>\n } @else if (SearchState === 'no-results') {\n <span class=\"record-count\">No results for \"{{ searchInput }}\"</span>\n } @else if (ResultCount > 0) {\n <span class=\"record-count\">{{ ResultCount | number }} {{ ResultCount === 1 ? 'result' : 'results' }} for \"{{ searchInput }}\"</span>\n }\n </div>\n\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"header-right\">\n <!-- New Record -->\n <button\n class=\"header-action-btn\"\n (click)=\"OnCreateNewRecord()\"\n title=\"New Record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'grid'\"\n (click)=\"SetViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'cards'\"\n (click)=\"SetViewMode('cards')\"\n title=\"Cards View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n @if (HasDateFields) {\n <button\n class=\"toggle-btn\"\n [class.active]=\"CurrentViewMode === 'timeline'\"\n (click)=\"SetViewMode('timeline')\"\n title=\"Timeline View\">\n <i class=\"fa-solid fa-timeline\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Loading state -->\n @if (SearchState === 'loading') {\n <div class=\"loading-container\">\n <mj-loading text=\"Searching...\"></mj-loading>\n </div>\n }\n\n <!-- No results -->\n @if (SearchState === 'no-results') {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-magnifying-glass empty-icon\"></i>\n <p>No results found for \"<strong>{{ searchInput }}</strong>\" in {{ entity }}</p>\n <p class=\"empty-hint\">Try a different search term or entity</p>\n </div>\n }\n\n <!-- Single result — auto-navigating to entity form -->\n @if (SearchState === 'single-result') {\n <div class=\"single-result-state\">\n <i class=\"fa-solid fa-arrow-right redirect-icon\"></i>\n <p>Found 1 result &mdash; opening record...</p>\n </div>\n }\n\n <!-- Entity Viewer (2+ results) -->\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"viewer-container\">\n <mj-entity-viewer\n [entity]=\"EntityInfo\"\n [viewMode]=\"CurrentViewMode\"\n [filterText]=\"searchInput\"\n [config]=\"ViewerConfig\"\n [showGridToolbar]=\"true\"\n [gridToolbarConfig]=\"GridToolbarConfig\"\n (viewModeChange)=\"OnViewModeChanged($event)\"\n (dataLoaded)=\"OnDataLoaded($event)\"\n (recordOpened)=\"OnRecordOpened($event)\"\n (addRequested)=\"OnCreateNewRecord()\">\n </mj-entity-viewer>\n </div>\n }\n</div>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-explorer-core",
3
- "version": "5.5.0",
3
+ "version": "5.6.0",
4
4
  "description": "MemberJunction Explorer: Core Angular Components",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -30,39 +30,39 @@
30
30
  "@angular/cdk": "21.1.3",
31
31
  "@angular/platform-browser": "21.1.3",
32
32
  "@auth0/auth0-angular": "^2.6.0",
33
- "@memberjunction/ai-core-plus": "5.5.0",
34
- "@memberjunction/ai-engine-base": "5.5.0",
35
- "@memberjunction/communication-types": "5.5.0",
36
- "@memberjunction/core": "5.5.0",
37
- "@memberjunction/core-entities": "5.5.0",
38
- "@memberjunction/entity-communications-client": "5.5.0",
39
- "@memberjunction/global": "5.5.0",
40
- "@memberjunction/graphql-dataprovider": "5.5.0",
41
- "@memberjunction/ng-ai-test-harness": "5.5.0",
42
- "@memberjunction/ng-artifacts": "5.5.0",
43
- "@memberjunction/ng-auth-services": "5.5.0",
44
- "@memberjunction/ng-base-application": "5.5.0",
45
- "@memberjunction/ng-base-forms": "5.5.0",
46
- "@memberjunction/ng-container-directives": "5.5.0",
47
- "@memberjunction/ng-conversations": "5.5.0",
48
- "@memberjunction/ng-dashboards": "5.5.0",
49
- "@memberjunction/ng-entity-form-dialog": "5.5.0",
50
- "@memberjunction/ng-entity-permissions": "5.5.0",
51
- "@memberjunction/ng-dashboard-viewer": "5.5.0",
52
- "@memberjunction/ng-entity-viewer": "5.5.0",
53
- "@memberjunction/ng-list-detail-grid": "5.5.0",
54
- "@memberjunction/ng-explorer-settings": "5.5.0",
55
- "@memberjunction/ng-file-storage": "5.5.0",
56
- "@memberjunction/ng-generic-dialog": "5.5.0",
57
- "@memberjunction/ng-notifications": "5.5.0",
58
- "@memberjunction/ng-query-viewer": "5.5.0",
59
- "@memberjunction/ng-record-changes": "5.5.0",
60
- "@memberjunction/ng-record-selector": "5.5.0",
61
- "@memberjunction/ng-resource-permissions": "5.5.0",
62
- "@memberjunction/ng-shared": "5.5.0",
63
- "@memberjunction/ng-shared-generic": "5.5.0",
64
- "@memberjunction/ng-user-avatar": "5.5.0",
65
- "@memberjunction/templates-base-types": "5.5.0",
33
+ "@memberjunction/ai-core-plus": "5.6.0",
34
+ "@memberjunction/ai-engine-base": "5.6.0",
35
+ "@memberjunction/communication-types": "5.6.0",
36
+ "@memberjunction/core": "5.6.0",
37
+ "@memberjunction/core-entities": "5.6.0",
38
+ "@memberjunction/entity-communications-client": "5.6.0",
39
+ "@memberjunction/global": "5.6.0",
40
+ "@memberjunction/graphql-dataprovider": "5.6.0",
41
+ "@memberjunction/ng-ai-test-harness": "5.6.0",
42
+ "@memberjunction/ng-artifacts": "5.6.0",
43
+ "@memberjunction/ng-auth-services": "5.6.0",
44
+ "@memberjunction/ng-base-application": "5.6.0",
45
+ "@memberjunction/ng-base-forms": "5.6.0",
46
+ "@memberjunction/ng-container-directives": "5.6.0",
47
+ "@memberjunction/ng-conversations": "5.6.0",
48
+ "@memberjunction/ng-dashboards": "5.6.0",
49
+ "@memberjunction/ng-entity-form-dialog": "5.6.0",
50
+ "@memberjunction/ng-entity-permissions": "5.6.0",
51
+ "@memberjunction/ng-dashboard-viewer": "5.6.0",
52
+ "@memberjunction/ng-entity-viewer": "5.6.0",
53
+ "@memberjunction/ng-list-detail-grid": "5.6.0",
54
+ "@memberjunction/ng-explorer-settings": "5.6.0",
55
+ "@memberjunction/ng-file-storage": "5.6.0",
56
+ "@memberjunction/ng-generic-dialog": "5.6.0",
57
+ "@memberjunction/ng-notifications": "5.6.0",
58
+ "@memberjunction/ng-query-viewer": "5.6.0",
59
+ "@memberjunction/ng-record-changes": "5.6.0",
60
+ "@memberjunction/ng-record-selector": "5.6.0",
61
+ "@memberjunction/ng-resource-permissions": "5.6.0",
62
+ "@memberjunction/ng-shared": "5.6.0",
63
+ "@memberjunction/ng-shared-generic": "5.6.0",
64
+ "@memberjunction/ng-user-avatar": "5.6.0",
65
+ "@memberjunction/templates-base-types": "5.6.0",
66
66
  "@progress/kendo-angular-buttons": "22.0.1",
67
67
  "@progress/kendo-angular-dateinputs": "22.0.1",
68
68
  "@progress/kendo-angular-dialog": "22.0.1",