@memberjunction/ng-dashboard-viewer 5.39.0 → 5.40.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.
@@ -2,8 +2,7 @@ import { ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';
2
2
  import { BaseDashboardPart } from './base-dashboard-part';
3
3
  import { EntityInfo } from '@memberjunction/core';
4
4
  import { MJUserViewEntityExtended } from '@memberjunction/core-entities';
5
- import { EntityViewMode, RecordSelectedEvent, RecordOpenedEvent } from '@memberjunction/ng-entity-viewer';
6
- import { MapRenderMode } from '@memberjunction/ng-map-view';
5
+ import { RecordSelectedEvent, RecordOpenedEvent, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';
7
6
  import * as i0 from "@angular/core";
8
7
  /**
9
8
  * Runtime renderer for View dashboard parts.
@@ -13,14 +12,19 @@ export declare class ViewPartComponent extends BaseDashboardPart implements Afte
13
12
  hasView: boolean;
14
13
  viewEntity: MJUserViewEntityExtended | null;
15
14
  entityInfo: EntityInfo | null;
16
- viewMode: EntityViewMode;
17
- mapRenderMode: MapRenderMode;
18
- selectionMode: 'single' | 'multiple';
19
15
  constructor(cdr: ChangeDetectorRef);
20
16
  ngAfterViewInit(): void;
21
17
  loadContent(): Promise<void>;
22
18
  onRecordSelected(event: RecordSelectedEvent): void;
23
19
  onRecordOpened(event: RecordOpenedEvent): void;
20
+ /**
21
+ * Handle a plug-in renderer's request (bubbled up via the inner entity-viewer) to open a
22
+ * *related* record on a (possibly different) entity — e.g. a grid foreign-key drill-through.
23
+ * Requests navigation through the dashboard-part routing contract.
24
+ *
25
+ * @param nav the related-record navigation payload: the target entity name and the record's key.
26
+ */
27
+ onOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void;
24
28
  protected cleanup(): void;
25
29
  static ɵfac: i0.ɵɵFactoryDeclaration<ViewPartComponent, never>;
26
30
  static ɵcmp: i0.ɵɵComponentDeclaration<ViewPartComponent, "mj-view-part", never, {}, {}, never, never, false, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"view-part.component.d.ts","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1G,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;;AAE5D;;;GAGG;AACH,qBAoGa,iBAAkB,SAAQ,iBAAkB,YAAW,aAAa,EAAE,SAAS;IACjF,OAAO,UAAS;IAChB,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAQ;IACnD,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IACrC,QAAQ,EAAE,cAAc,CAAU;IAClC,aAAa,EAAE,aAAa,CAAW;IACvC,aAAa,EAAE,QAAQ,GAAG,UAAU,CAAY;gBAE3C,GAAG,EAAE,iBAAiB;IAIlC,eAAe,IAAI,IAAI;IAMV,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAgElC,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IASlD,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;cAmBlC,OAAO,IAAI,IAAI;yCA9GzB,iBAAiB;2CAAjB,iBAAiB;CAmH7B"}
1
+ {"version":3,"file":"view-part.component.d.ts","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;;AAEvH;;;GAGG;AACH,qBAiGa,iBAAkB,SAAQ,iBAAkB,YAAW,aAAa,EAAE,SAAS;IACjF,OAAO,UAAS;IAChB,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAQ;IACnD,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;gBAEhC,GAAG,EAAE,iBAAiB;IAIlC,eAAe,IAAI,IAAI;IAMV,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DlC,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IASlD,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAmBrD;;;;;;OAMG;IACI,4BAA4B,CAAC,GAAG,EAAE,2BAA2B,GAAG,IAAI;cAWxD,OAAO,IAAI,IAAI;yCAxHzB,iBAAiB;2CAAjB,iBAAiB;CA6H7B"}
@@ -39,14 +39,11 @@ function ViewPartComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
39
39
  function ViewPartComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
40
40
  const _r2 = i0.ɵɵgetCurrentView();
41
41
  i0.ɵɵelementStart(0, "mj-entity-viewer", 8);
42
- i0.ɵɵtwoWayListener("viewModeChange", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_viewModeChange_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.viewMode, $event) || (ctx_r0.viewMode = $event); return i0.ɵɵresetView($event); });
43
- i0.ɵɵlistener("recordSelected", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_recordSelected_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRecordSelected($event)); })("recordOpened", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_recordOpened_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRecordOpened($event)); });
42
+ i0.ɵɵlistener("RecordSelected", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_RecordSelected_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRecordSelected($event)); })("RecordOpened", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_RecordOpened_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onRecordOpened($event)); })("OpenRelatedRecordRequested", function ViewPartComponent_Conditional_4_Template_mj_entity_viewer_OpenRelatedRecordRequested_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onOpenRelatedRecordRequested($event)); });
44
43
  i0.ɵɵelementEnd();
45
44
  } if (rf & 2) {
46
45
  const ctx_r0 = i0.ɵɵnextContext();
47
- i0.ɵɵproperty("entity", ctx_r0.entityInfo)("viewEntity", ctx_r0.viewEntity);
48
- i0.ɵɵtwoWayProperty("viewMode", ctx_r0.viewMode);
49
- i0.ɵɵproperty("mapRenderMode", ctx_r0.mapRenderMode)("gridSelectionMode", ctx_r0.selectionMode)("showGridToolbar", false);
46
+ i0.ɵɵproperty("Entity", ctx_r0.entityInfo)("ViewEntity", ctx_r0.viewEntity);
50
47
  } }
51
48
  /**
52
49
  * Runtime renderer for View dashboard parts.
@@ -56,9 +53,6 @@ let ViewPartComponent = class ViewPartComponent extends BaseDashboardPart {
56
53
  hasView = false;
57
54
  viewEntity = null;
58
55
  entityInfo = null;
59
- viewMode = 'grid';
60
- mapRenderMode = 'point';
61
- selectionMode = 'single';
62
56
  constructor(cdr) {
63
57
  super(cdr);
64
58
  }
@@ -79,10 +73,6 @@ let ViewPartComponent = class ViewPartComponent extends BaseDashboardPart {
79
73
  this.setLoading(true);
80
74
  try {
81
75
  const p = this.ProviderToUse;
82
- // Set view mode from config
83
- this.viewMode = config?.['displayMode'] || 'grid';
84
- this.mapRenderMode = config?.['mapRenderMode'] || 'point';
85
- this.selectionMode = config?.['selectionMode'] === 'multiple' ? 'multiple' : 'single';
86
76
  if (viewId) {
87
77
  // Load saved view by ID
88
78
  const viewEntity = await p.GetEntityObject('MJ: User Views', p.CurrentUser);
@@ -143,18 +133,30 @@ let ViewPartComponent = class ViewPartComponent extends BaseDashboardPart {
143
133
  this.RequestOpenEntityRecord(event.entity.Name, event.compositeKey.ToURLSegment(), 'view', false);
144
134
  }
145
135
  }
136
+ /**
137
+ * Handle a plug-in renderer's request (bubbled up via the inner entity-viewer) to open a
138
+ * *related* record on a (possibly different) entity — e.g. a grid foreign-key drill-through.
139
+ * Requests navigation through the dashboard-part routing contract.
140
+ *
141
+ * @param nav the related-record navigation payload: the target entity name and the record's key.
142
+ */
143
+ onOpenRelatedRecordRequested(nav) {
144
+ if (nav?.entityName && nav.recordKey != null) {
145
+ this.RequestOpenEntityRecord(nav.entityName, String(nav.recordKey), 'view', false);
146
+ }
147
+ }
146
148
  cleanup() {
147
149
  // EntityViewer handles its own cleanup
148
150
  this.viewEntity = null;
149
151
  this.entityInfo = null;
150
152
  }
151
153
  static ɵfac = function ViewPartComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ViewPartComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
152
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewPartComponent, selectors: [["mj-view-part"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [[1, "view-part"], [1, "loading-state"], [1, "error-state"], [1, "empty-state"], [3, "entity", "viewEntity", "viewMode", "mapRenderMode", "gridSelectionMode", "showGridToolbar"], ["text", "Loading view..."], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-table"], [3, "viewModeChange", "recordSelected", "recordOpened", "entity", "viewEntity", "viewMode", "mapRenderMode", "gridSelectionMode", "showGridToolbar"]], template: function ViewPartComponent_Template(rf, ctx) { if (rf & 1) {
154
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewPartComponent, selectors: [["mj-view-part"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [[1, "view-part"], [1, "loading-state"], [1, "error-state"], [1, "empty-state"], [3, "Entity", "ViewEntity"], ["text", "Loading view..."], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-table"], [3, "RecordSelected", "RecordOpened", "OpenRelatedRecordRequested", "Entity", "ViewEntity"]], template: function ViewPartComponent_Template(rf, ctx) { if (rf & 1) {
153
155
  i0.ɵɵelementStart(0, "div", 0);
154
156
  i0.ɵɵconditionalCreate(1, ViewPartComponent_Conditional_1_Template, 2, 0, "div", 1);
155
157
  i0.ɵɵconditionalCreate(2, ViewPartComponent_Conditional_2_Template, 4, 1, "div", 2);
156
158
  i0.ɵɵconditionalCreate(3, ViewPartComponent_Conditional_3_Template, 6, 0, "div", 3);
157
- i0.ɵɵconditionalCreate(4, ViewPartComponent_Conditional_4_Template, 1, 6, "mj-entity-viewer", 4);
159
+ i0.ɵɵconditionalCreate(4, ViewPartComponent_Conditional_4_Template, 1, 2, "mj-entity-viewer", 4);
158
160
  i0.ɵɵelementEnd();
159
161
  } if (rf & 2) {
160
162
  i0.ɵɵclassProp("loading", ctx.IsLoading)("error", ctx.ErrorMessage);
@@ -203,18 +205,15 @@ export { ViewPartComponent };
203
205
  <!-- Entity Viewer -->
204
206
  @if (!IsLoading && !ErrorMessage && hasView && entityInfo) {
205
207
  <mj-entity-viewer
206
- [entity]="entityInfo"
207
- [viewEntity]="viewEntity"
208
- [(viewMode)]="viewMode"
209
- [mapRenderMode]="mapRenderMode"
210
- [gridSelectionMode]="selectionMode"
211
- [showGridToolbar]="false"
212
- (recordSelected)="onRecordSelected($event)"
213
- (recordOpened)="onRecordOpened($event)">
208
+ [Entity]="entityInfo"
209
+ [ViewEntity]="viewEntity"
210
+ (RecordSelected)="onRecordSelected($event)"
211
+ (RecordOpened)="onRecordOpened($event)"
212
+ (OpenRelatedRecordRequested)="onOpenRelatedRecordRequested($event)">
214
213
  </mj-entity-viewer>
215
214
  }
216
215
  </div>
217
216
  `, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .view-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state,\n .error-state,\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .error-state i,\n .empty-state i {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n }\n\n .error-state i {\n color: var(--mj-status-error);\n }\n\n .empty-state h4 {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n }\n\n .empty-state p {\n margin: 0;\n font-size: 13px;\n }\n\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n "] }]
218
217
  }], () => [{ type: i0.ChangeDetectorRef }], null); })();
219
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ViewPartComponent, { className: "ViewPartComponent", filePath: "src/lib/parts/view-part.component.ts", lineNumber: 114 }); })();
218
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ViewPartComponent, { className: "ViewPartComponent", filePath: "src/lib/parts/view-part.component.ts", lineNumber: 110 }); })();
220
219
  //# sourceMappingURL=view-part.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"view-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { EntityInfo } from '@memberjunction/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { EntityViewMode, RecordSelectedEvent, RecordOpenedEvent } from '@memberjunction/ng-entity-viewer';\nimport { MapRenderMode } from '@memberjunction/ng-map-view';\n\n/**\n * Runtime renderer for View dashboard parts.\n * Displays entity data using mj-entity-viewer with grid, cards, or timeline layout.\n */\n@RegisterClass(BaseDashboardPart, 'ViewPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-view-part',\n template: `\n <div class=\"view-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading view...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n \n <!-- No view configured -->\n @if (!IsLoading && !ErrorMessage && !hasView) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-table\"></i>\n <h4>No View Selected</h4>\n <p>Click the configure button to select a view for this part.</p>\n </div>\n }\n \n <!-- Entity Viewer -->\n @if (!IsLoading && !ErrorMessage && hasView && entityInfo) {\n <mj-entity-viewer\n [entity]=\"entityInfo\"\n [viewEntity]=\"viewEntity\"\n [(viewMode)]=\"viewMode\"\n [mapRenderMode]=\"mapRenderMode\"\n [gridSelectionMode]=\"selectionMode\"\n [showGridToolbar]=\"false\"\n (recordSelected)=\"onRecordSelected($event)\"\n (recordOpened)=\"onRecordOpened($event)\">\n </mj-entity-viewer>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .view-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state,\n .error-state,\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .error-state i,\n .empty-state i {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n }\n\n .error-state i {\n color: var(--mj-status-error);\n }\n\n .empty-state h4 {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n }\n\n .empty-state p {\n margin: 0;\n font-size: 13px;\n }\n\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ViewPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n public hasView = false;\n public viewEntity: MJUserViewEntityExtended | null = null;\n public entityInfo: EntityInfo | null = null;\n public viewMode: EntityViewMode = 'grid';\n public mapRenderMode: MapRenderMode = 'point';\n public selectionMode: 'single' | 'multiple' = 'single';\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const viewId = config?.['viewId'] as string | undefined;\n const entityName = config?.['entityName'] as string | undefined;\n\n if (!viewId && !entityName) {\n this.hasView = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n const p = this.ProviderToUse;\n\n // Set view mode from config\n this.viewMode = (config?.['displayMode'] as EntityViewMode) || 'grid';\n this.mapRenderMode = (config?.['mapRenderMode'] as MapRenderMode) || 'point';\n this.selectionMode = config?.['selectionMode'] === 'multiple' ? 'multiple' : 'single';\n\n if (viewId) {\n // Load saved view by ID\n const viewEntity = await p.GetEntityObject<MJUserViewEntityExtended>('MJ: User Views', p.CurrentUser);\n const loaded = await viewEntity.Load(viewId);\n this.viewEntity = viewEntity; // IMPORTANT - only set this.viewEntity AFTER we have it loaded in the above\n\n if (!loaded) {\n throw new Error('View not found');\n }\n\n // Get entity info from the view - prefer ViewEntityInfo if available (set by MJUserViewEntityExtended.Load)\n // Fall back to looking up by Entity name (virtual field) or EntityID\n if (viewEntity.ViewEntityInfo) {\n this.entityInfo = viewEntity.ViewEntityInfo;\n } else if (viewEntity.Entity) {\n this.entityInfo = p.EntityByName(viewEntity!.Entity) || null;\n } else if (viewEntity.EntityID) {\n // Last resort: look up by EntityID\n this.entityInfo = p.Entities.find(e => UUIDsEqual(e.ID, viewEntity!.EntityID)) || null;\n }\n\n if (!this.entityInfo) {\n throw new Error(`Could not determine entity for view \"${this.viewEntity.Name}\" (ID: ${viewId})`);\n }\n } else if (entityName) {\n // Create dynamic view for entity (no saved view)\n this.entityInfo = p.EntityByName(entityName) || null;\n\n if (!this.entityInfo) {\n throw new Error(`Entity \"${entityName}\" not found`);\n }\n\n // No viewEntity means the entity-viewer will show all records\n this.viewEntity = null;\n }\n\n this.hasView = true;\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load view');\n }\n }\n\n public onRecordSelected(event: RecordSelectedEvent): void {\n // Emit data change event with selected record\n this.emitDataChanged({\n type: 'record-selected',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n }\n\n public onRecordOpened(event: RecordOpenedEvent): void {\n // Emit data change event for record open (for any listeners that need it)\n this.emitDataChanged({\n type: 'record-opened',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n\n // Request navigation to open the record\n if (event.entity && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entity.Name,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n protected override cleanup(): void {\n // EntityViewer handles its own cleanup\n this.viewEntity = null;\n this.entityInfo = null;\n }\n}\n"]}
1
+ {"version":3,"file":"view-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { EntityInfo } from '@memberjunction/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { RecordSelectedEvent, RecordOpenedEvent, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';\n\n/**\n * Runtime renderer for View dashboard parts.\n * Displays entity data using mj-entity-viewer with grid, cards, or timeline layout.\n */\n@RegisterClass(BaseDashboardPart, 'ViewPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-view-part',\n template: `\n <div class=\"view-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading view...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n \n <!-- No view configured -->\n @if (!IsLoading && !ErrorMessage && !hasView) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-table\"></i>\n <h4>No View Selected</h4>\n <p>Click the configure button to select a view for this part.</p>\n </div>\n }\n \n <!-- Entity Viewer -->\n @if (!IsLoading && !ErrorMessage && hasView && entityInfo) {\n <mj-entity-viewer\n [Entity]=\"entityInfo\"\n [ViewEntity]=\"viewEntity\"\n (RecordSelected)=\"onRecordSelected($event)\"\n (RecordOpened)=\"onRecordOpened($event)\"\n (OpenRelatedRecordRequested)=\"onOpenRelatedRecordRequested($event)\">\n </mj-entity-viewer>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .view-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state,\n .error-state,\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .error-state i,\n .empty-state i {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n }\n\n .error-state i {\n color: var(--mj-status-error);\n }\n\n .empty-state h4 {\n margin: 0 0 8px 0;\n color: var(--mj-text-primary);\n }\n\n .empty-state p {\n margin: 0;\n font-size: 13px;\n }\n\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ViewPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n public hasView = false;\n public viewEntity: MJUserViewEntityExtended | null = null;\n public entityInfo: EntityInfo | null = null;\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const viewId = config?.['viewId'] as string | undefined;\n const entityName = config?.['entityName'] as string | undefined;\n\n if (!viewId && !entityName) {\n this.hasView = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n const p = this.ProviderToUse;\n\n if (viewId) {\n // Load saved view by ID\n const viewEntity = await p.GetEntityObject<MJUserViewEntityExtended>('MJ: User Views', p.CurrentUser);\n const loaded = await viewEntity.Load(viewId);\n this.viewEntity = viewEntity; // IMPORTANT - only set this.viewEntity AFTER we have it loaded in the above\n\n if (!loaded) {\n throw new Error('View not found');\n }\n\n // Get entity info from the view - prefer ViewEntityInfo if available (set by MJUserViewEntityExtended.Load)\n // Fall back to looking up by Entity name (virtual field) or EntityID\n if (viewEntity.ViewEntityInfo) {\n this.entityInfo = viewEntity.ViewEntityInfo;\n } else if (viewEntity.Entity) {\n this.entityInfo = p.EntityByName(viewEntity!.Entity) || null;\n } else if (viewEntity.EntityID) {\n // Last resort: look up by EntityID\n this.entityInfo = p.Entities.find(e => UUIDsEqual(e.ID, viewEntity!.EntityID)) || null;\n }\n\n if (!this.entityInfo) {\n throw new Error(`Could not determine entity for view \"${this.viewEntity.Name}\" (ID: ${viewId})`);\n }\n } else if (entityName) {\n // Create dynamic view for entity (no saved view)\n this.entityInfo = p.EntityByName(entityName) || null;\n\n if (!this.entityInfo) {\n throw new Error(`Entity \"${entityName}\" not found`);\n }\n\n // No viewEntity means the entity-viewer will show all records\n this.viewEntity = null;\n }\n\n this.hasView = true;\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load view');\n }\n }\n\n public onRecordSelected(event: RecordSelectedEvent): void {\n // Emit data change event with selected record\n this.emitDataChanged({\n type: 'record-selected',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n }\n\n public onRecordOpened(event: RecordOpenedEvent): void {\n // Emit data change event for record open (for any listeners that need it)\n this.emitDataChanged({\n type: 'record-opened',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n\n // Request navigation to open the record\n if (event.entity && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entity.Name,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n /**\n * Handle a plug-in renderer's request (bubbled up via the inner entity-viewer) to open a\n * *related* record on a (possibly different) entity — e.g. a grid foreign-key drill-through.\n * Requests navigation through the dashboard-part routing contract.\n *\n * @param nav the related-record navigation payload: the target entity name and the record's key.\n */\n public onOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void {\n if (nav?.entityName && nav.recordKey != null) {\n this.RequestOpenEntityRecord(\n nav.entityName,\n String(nav.recordKey),\n 'view',\n false\n );\n }\n }\n\n protected override cleanup(): void {\n // EntityViewer handles its own cleanup\n this.viewEntity = null;\n this.entityInfo = null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-dashboard-viewer",
3
- "version": "5.39.0",
3
+ "version": "5.40.0",
4
4
  "description": "MemberJunction: Angular components for metadata-driven dashboards with Golden Layout panels, supporting views, queries, artifacts, and custom content",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -37,16 +37,16 @@
37
37
  "golden-layout": "^2.6.0"
38
38
  },
39
39
  "dependencies": {
40
- "@memberjunction/core": "5.39.0",
41
- "@memberjunction/core-entities": "5.39.0",
42
- "@memberjunction/global": "5.39.0",
43
- "@memberjunction/ng-artifacts": "5.39.0",
44
- "@memberjunction/ng-base-types": "5.39.0",
45
- "@memberjunction/ng-entity-viewer": "5.39.0",
46
- "@memberjunction/ng-map-view": "5.39.0",
47
- "@memberjunction/ng-query-viewer": "5.39.0",
48
- "@memberjunction/ng-shared-generic": "5.39.0",
49
- "@memberjunction/ng-trees": "5.39.0",
40
+ "@memberjunction/core": "5.40.0",
41
+ "@memberjunction/core-entities": "5.40.0",
42
+ "@memberjunction/global": "5.40.0",
43
+ "@memberjunction/ng-artifacts": "5.40.0",
44
+ "@memberjunction/ng-base-types": "5.40.0",
45
+ "@memberjunction/ng-entity-viewer": "5.40.0",
46
+ "@memberjunction/ng-map-view": "5.40.0",
47
+ "@memberjunction/ng-query-viewer": "5.40.0",
48
+ "@memberjunction/ng-shared-generic": "5.40.0",
49
+ "@memberjunction/ng-trees": "5.40.0",
50
50
  "rxjs": "^7.8.2",
51
51
  "tslib": "^2.8.1"
52
52
  },