@memberjunction/ng-entity-viewer 5.39.0 → 5.40.1

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.
Files changed (79) hide show
  1. package/dist/__tests__/view-types.test.d.ts +2 -0
  2. package/dist/__tests__/view-types.test.d.ts.map +1 -0
  3. package/dist/__tests__/view-types.test.js +102 -0
  4. package/dist/__tests__/view-types.test.js.map +1 -0
  5. package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
  6. package/dist/lib/entity-data-grid/entity-data-grid.component.js +8 -0
  7. package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
  8. package/dist/lib/entity-viewer/entity-viewer.component.d.ts +356 -341
  9. package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
  10. package/dist/lib/entity-viewer/entity-viewer.component.js +993 -1097
  11. package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
  12. package/dist/lib/view-config-panel/view-config-panel.component.d.ts +126 -126
  13. package/dist/lib/view-config-panel/view-config-panel.component.js +635 -635
  14. package/dist/lib/view-config-panel/view-config-panel.component.js.map +1 -1
  15. package/dist/lib/view-selector/view-selector.component.d.ts +226 -0
  16. package/dist/lib/view-selector/view-selector.component.d.ts.map +1 -0
  17. package/dist/lib/view-selector/view-selector.component.js +861 -0
  18. package/dist/lib/view-selector/view-selector.component.js.map +1 -0
  19. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts +114 -0
  20. package/dist/lib/view-type-switcher/view-type-switcher.component.d.ts.map +1 -0
  21. package/dist/lib/view-type-switcher/view-type-switcher.component.js +209 -0
  22. package/dist/lib/view-type-switcher/view-type-switcher.component.js.map +1 -0
  23. package/dist/lib/view-types/descriptors/cards-view-type.d.ts +18 -0
  24. package/dist/lib/view-types/descriptors/cards-view-type.d.ts.map +1 -0
  25. package/dist/lib/view-types/descriptors/cards-view-type.js +31 -0
  26. package/dist/lib/view-types/descriptors/cards-view-type.js.map +1 -0
  27. package/dist/lib/view-types/descriptors/grid-view-type.d.ts +17 -0
  28. package/dist/lib/view-types/descriptors/grid-view-type.d.ts.map +1 -0
  29. package/dist/lib/view-types/descriptors/grid-view-type.js +30 -0
  30. package/dist/lib/view-types/descriptors/grid-view-type.js.map +1 -0
  31. package/dist/lib/view-types/descriptors/map-view-type.d.ts +21 -0
  32. package/dist/lib/view-types/descriptors/map-view-type.d.ts.map +1 -0
  33. package/dist/lib/view-types/descriptors/map-view-type.js +35 -0
  34. package/dist/lib/view-types/descriptors/map-view-type.js.map +1 -0
  35. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts +22 -0
  36. package/dist/lib/view-types/descriptors/timeline-view-type.d.ts.map +1 -0
  37. package/dist/lib/view-types/descriptors/timeline-view-type.js +40 -0
  38. package/dist/lib/view-types/descriptors/timeline-view-type.js.map +1 -0
  39. package/dist/lib/view-types/index.d.ts +20 -0
  40. package/dist/lib/view-types/index.d.ts.map +1 -0
  41. package/dist/lib/view-types/index.js +29 -0
  42. package/dist/lib/view-types/index.js.map +1 -0
  43. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts +93 -0
  44. package/dist/lib/view-types/renderers/cards-view-renderer.component.d.ts.map +1 -0
  45. package/dist/lib/view-types/renderers/cards-view-renderer.component.js +144 -0
  46. package/dist/lib/view-types/renderers/cards-view-renderer.component.js.map +1 -0
  47. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts +273 -0
  48. package/dist/lib/view-types/renderers/grid-view-renderer.component.d.ts.map +1 -0
  49. package/dist/lib/view-types/renderers/grid-view-renderer.component.js +558 -0
  50. package/dist/lib/view-types/renderers/grid-view-renderer.component.js.map +1 -0
  51. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts +135 -0
  52. package/dist/lib/view-types/renderers/map-view-renderer.component.d.ts.map +1 -0
  53. package/dist/lib/view-types/renderers/map-view-renderer.component.js +216 -0
  54. package/dist/lib/view-types/renderers/map-view-renderer.component.js.map +1 -0
  55. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts +176 -0
  56. package/dist/lib/view-types/renderers/timeline-view-renderer.component.d.ts.map +1 -0
  57. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js +535 -0
  58. package/dist/lib/view-types/renderers/timeline-view-renderer.component.js.map +1 -0
  59. package/dist/lib/view-types/view-type.contracts.d.ts +235 -0
  60. package/dist/lib/view-types/view-type.contracts.d.ts.map +1 -0
  61. package/dist/lib/view-types/view-type.contracts.js +51 -0
  62. package/dist/lib/view-types/view-type.contracts.js.map +1 -0
  63. package/dist/lib/view-types/view-type.engine.d.ts +76 -0
  64. package/dist/lib/view-types/view-type.engine.d.ts.map +1 -0
  65. package/dist/lib/view-types/view-type.engine.js +138 -0
  66. package/dist/lib/view-types/view-type.engine.js.map +1 -0
  67. package/dist/lib/view-workspace/view-workspace.component.d.ts +451 -0
  68. package/dist/lib/view-workspace/view-workspace.component.d.ts.map +1 -0
  69. package/dist/lib/view-workspace/view-workspace.component.js +1212 -0
  70. package/dist/lib/view-workspace/view-workspace.component.js.map +1 -0
  71. package/dist/module.d.ts +20 -11
  72. package/dist/module.d.ts.map +1 -1
  73. package/dist/module.js +50 -8
  74. package/dist/module.js.map +1 -1
  75. package/dist/public-api.d.ts +8 -0
  76. package/dist/public-api.d.ts.map +1 -1
  77. package/dist/public-api.js +14 -0
  78. package/dist/public-api.js.map +1 -1
  79. package/package.json +16 -15
@@ -1,14 +1,76 @@
1
- import { EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';
1
+ import { EventEmitter, OnInit, OnDestroy, AfterViewInit, ChangeDetectorRef, ElementRef, NgZone } from '@angular/core';
2
2
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
- import { EntityInfo, EntityFieldInfo, RunViewParams } from '@memberjunction/core';
3
+ import { EntityInfo } from '@memberjunction/core';
4
4
  import { MJUserViewEntityExtended } from '@memberjunction/core-entities';
5
5
  import { PageChangeEvent } from '@memberjunction/ng-pagination';
6
- import { TimelineGroup, TimeSegmentGrouping, TimelineSortOrder, AfterEventClickArgs } from '@memberjunction/ng-timeline';
7
- import { MapDisplayState, MapRenderMode } from '@memberjunction/ng-map-view';
8
- import { EntityViewMode, EntityViewerConfig, RecordSelectedEvent, RecordOpenedEvent, DataLoadedEvent, FilteredCountChangedEvent, CardTemplate, GridColumnDef, SortState, SortChangedEvent, PaginationState, ViewGridState, GridStateChangedEvent, TimelineOrientation, TimelineState } from '../types';
9
- import { AfterRowClickEventArgs, AfterRowDoubleClickEventArgs, AfterSortEventArgs } from '../entity-data-grid/events/grid-events';
10
- import { GridToolbarConfig, GridSelectionMode, ForeignKeyClickEvent } from '../entity-data-grid/models/grid-types';
6
+ import { EntityViewerConfig, RecordSelectedEvent, RecordOpenedEvent, DataLoadedEvent, FilteredCountChangedEvent, SortState, PaginationState, ViewGridState } from '../types';
7
+ import { IViewTypeDescriptor, ViewRelatedRecordNavigation } from '../view-types';
11
8
  import * as i0 from "@angular/core";
9
+ /**
10
+ * A single entry in the view-type switcher, built from the {@link ViewTypeEngine} registry
11
+ * (`MJ: View Types`). Every view type is a dynamic-mounted plug-in implementing `IViewRenderer`;
12
+ * the container has zero knowledge of any specific view type — it mounts the descriptor's
13
+ * `RendererComponent` and feeds it the generic contract.
14
+ */
15
+ export interface ViewModeOption {
16
+ /**
17
+ * Stable key for this option — the descriptor's `Name` (== `MJ: View Types.DriverClass`),
18
+ * e.g. "GridViewType", "ClusterViewType". Used as the `@for` track key and to identify the
19
+ * active option.
20
+ */
21
+ key: string;
22
+ /**
23
+ * Always `null` — retained on the interface only so any external reader doesn't break. Every
24
+ * view type is now dynamic-mounted; there is no legacy built-in render mode.
25
+ */
26
+ mode: null;
27
+ /** User-facing label. */
28
+ label: string;
29
+ /** Font Awesome icon class. */
30
+ icon: string;
31
+ /** Always `true` — every view type is dynamic-mounted via the descriptor's RendererComponent. */
32
+ isDynamic: boolean;
33
+ /** The resolved descriptor (carries the RendererComponent + PropSheetComponent). */
34
+ descriptor: IViewTypeDescriptor;
35
+ /** The `MJ: View Types` row ID — for ViewTypeID persistence + per-view-type config keying. */
36
+ viewTypeId: string;
37
+ }
38
+ /**
39
+ * Event payload for the view-type change lifecycle. Emitted (cancelable) via
40
+ * {@link EntityViewerComponent.BeforeViewTypeChange} and (notification) via
41
+ * {@link EntityViewerComponent.AfterViewTypeChange}. A handler may set `Cancel = true` on the
42
+ * *Before* event to veto the switch (mirrors the grid's `BeforeRowClick` / `BeforeCellEdit`
43
+ * cancelable pattern).
44
+ */
45
+ export interface ViewTypeChangeEventArgs {
46
+ /** The `MJ: View Types` row ID being switched to. */
47
+ ViewTypeID: string;
48
+ /** The descriptor `DriverClass` / Name being switched to (e.g. "ClusterViewType"). */
49
+ DriverClass: string;
50
+ /** The `MJ: View Types` row ID being switched FROM (null on the first selection). */
51
+ PreviousViewTypeID: string | null;
52
+ /** Set to true in a {@link EntityViewerComponent.BeforeViewTypeChange} handler to veto the switch. */
53
+ Cancel: boolean;
54
+ }
55
+ /**
56
+ * Event payload for the per-view-type configuration change lifecycle.
57
+ */
58
+ export interface ViewTypeConfigChangeEventArgs {
59
+ /** The `MJ: View Types` row ID whose config changed. */
60
+ ViewTypeID: string;
61
+ /** The new configuration payload (shape owned by the plug-in). */
62
+ Config: Record<string, unknown>;
63
+ /** Set to true in a {@link EntityViewerComponent.BeforeViewTypeConfigChange} handler to veto. */
64
+ Cancel: boolean;
65
+ }
66
+ /**
67
+ * Where the entity viewer persists view-type/render-state when {@link EntityViewerComponent.AutoSaveView}
68
+ * is enabled:
69
+ * - `'record'` — onto the loaded `UserView` row (shared; everyone who opens that view sees it).
70
+ * - `'user-settings'` — per-user via `UserInfoEngine` (the default-view case, or a personal layer).
71
+ * - `'none'` — nothing to persist to (no view + settings disabled).
72
+ */
73
+ export type ViewPersistenceTarget = 'record' | 'user-settings' | 'none';
12
74
  /**
13
75
  * EntityViewerComponent - Full-featured composite component for viewing entity data
14
76
  *
@@ -25,128 +87,108 @@ import * as i0 from "@angular/core";
25
87
  * ```html
26
88
  * <!-- Basic usage - loads data automatically -->
27
89
  * <mj-entity-viewer
28
- * [entity]="selectedEntity"
29
- * (recordSelected)="onRecordSelected($event)"
30
- * (recordOpened)="onRecordOpened($event)">
90
+ * [Entity]="selectedEntity"
91
+ * (RecordSelected)="onRecordSelected($event)"
92
+ * (RecordOpened)="onRecordOpened($event)">
31
93
  * </mj-entity-viewer>
32
94
  *
33
95
  * <!-- With external state control (like Data Explorer) -->
34
96
  * <mj-entity-viewer
35
- * [entity]="selectedEntity"
36
- * [(viewMode)]="state.viewMode"
37
- * [filterText]="state.filterText"
38
- * [selectedRecordId]="state.selectedRecordId"
39
- * (recordSelected)="onRecordSelected($event)"
40
- * (recordOpened)="onRecordOpened($event)"
41
- * (sortChanged)="onSortChanged($event)">
97
+ * [Entity]="selectedEntity"
98
+ * [ViewTypeID]="state.viewTypeId"
99
+ * [FilterText]="state.filterText"
100
+ * [SelectedRecordID]="state.selectedRecordId"
101
+ * (RecordSelected)="onRecordSelected($event)"
102
+ * (RecordOpened)="onRecordOpened($event)">
42
103
  * </mj-entity-viewer>
43
104
  * ```
44
105
  */
45
- export declare class EntityViewerComponent extends BaseAngularComponent implements OnInit, OnDestroy {
106
+ export declare class EntityViewerComponent extends BaseAngularComponent implements OnInit, OnDestroy, AfterViewInit {
46
107
  private cdr;
47
108
  private ngZone;
109
+ private elementRef;
48
110
  /**
49
- * Maximum records to load in map mode. Map view needs all records for
50
- * geographic visualization paging doesn't make sense for maps. This cap
51
- * prevents unbounded queries on very large entities.
111
+ * Safety cap on the number of records loaded when a plug-in renderer asks the container to
112
+ * load the full set (via a {@link ViewDataRequest} with `loadAll: true`). Prevents unbounded
113
+ * queries on very large entities. Generic — not tied to any specific view type.
52
114
  */
53
- private static readonly MAP_MAX_RECORDS;
115
+ private static readonly LOAD_ALL_MAX_RECORDS;
54
116
  private _entity;
55
117
  private _records;
56
118
  private _config;
57
- private _viewMode;
58
119
  private _filterText;
59
120
  private _sortState;
60
121
  private _viewEntity;
61
- private _timelineConfig;
62
122
  private _initialized;
123
+ /**
124
+ * When true, the next {@link LoadData} loads the full record set (up to
125
+ * {@link LOAD_ALL_MAX_RECORDS}) instead of paginating. Set generically from a plug-in's
126
+ * {@link ViewDataRequest} (`loadAll`) — never from any view-type check.
127
+ */
128
+ private _loadAllRecords;
63
129
  /** Whether a deferred reload has been queued via deferReload() */
64
130
  private _reloadDeferred;
65
131
  /**
66
132
  * The entity to display records for
67
133
  */
68
- get entity(): EntityInfo | null;
69
- set entity(value: EntityInfo | null);
134
+ get Entity(): EntityInfo | null;
135
+ set Entity(value: EntityInfo | null);
70
136
  /**
71
- * Pre-loaded records (optional - if not provided, component loads data)
137
+ * Convenience input: the entity to display by **name**. Resolved internally to an `EntityInfo`
138
+ * via the active provider and applied through the {@link entity} setter. Use this OR `[entity]`
139
+ * OR `[EntityID]` — whichever is most convenient for the consumer.
72
140
  */
73
- get records(): Record<string, unknown>[] | null;
74
- set records(value: Record<string, unknown>[] | null);
141
+ set EntityName(value: string | null);
75
142
  /**
76
- * Configuration options for the viewer
143
+ * Convenience input: the entity to display by **ID**. Resolved internally to an `EntityInfo`
144
+ * and applied through the {@link entity} setter.
77
145
  */
78
- get config(): Partial<EntityViewerConfig>;
79
- set config(value: Partial<EntityViewerConfig>);
146
+ set EntityID(value: string | null);
80
147
  /**
81
- * Currently selected record ID (primary key string)
148
+ * Convenience input: load and display a saved view by its `MJ: User Views` **ID**. The viewer
149
+ * loads the record via the active provider and applies it through the {@link viewEntity} setter
150
+ * (which also resolves the entity if `[entity]`/`[EntityName]`/`[EntityID]` weren't supplied).
82
151
  */
83
- selectedRecordId: string | null;
152
+ set ViewID(value: string | null);
84
153
  /**
85
- * External view mode - allows parent to control view mode
86
- * Supports two-way binding: [(viewMode)]="state.viewMode"
154
+ * Pre-loaded records (optional - if not provided, component loads data)
87
155
  */
88
- get viewMode(): EntityViewMode | null;
89
- set viewMode(value: EntityViewMode | null);
156
+ get Records(): Record<string, unknown>[] | null;
157
+ set Records(value: Record<string, unknown>[] | null);
90
158
  /**
91
- * External filter text - allows parent to control filter
92
- * Supports two-way binding: [(filterText)]="state.filterText"
159
+ * Configuration options for the viewer
93
160
  */
94
- get filterText(): string | null;
95
- set filterText(value: string | null);
161
+ get Config(): Partial<EntityViewerConfig>;
162
+ set Config(value: Partial<EntityViewerConfig>);
96
163
  /**
97
- * External sort state - allows parent to control sorting
164
+ * Currently selected record ID (primary key string)
98
165
  */
99
- get sortState(): SortState | null;
100
- set sortState(value: SortState | null);
166
+ get SelectedRecordID(): string | null;
167
+ set SelectedRecordID(value: string | null);
168
+ private _selectedRecordId;
101
169
  /**
102
- * Custom grid column definitions
170
+ * External filter text - allows parent to control filter
171
+ * Supports two-way binding: [(filterText)]="state.filterText"
103
172
  */
104
- gridColumns: GridColumnDef[];
173
+ get FilterText(): string | null;
174
+ set FilterText(value: string | null);
105
175
  /**
106
- * Custom card template
176
+ * External sort state - allows parent to control sorting
107
177
  */
108
- cardTemplate: CardTemplate | null;
178
+ get SortState(): SortState | null;
179
+ set SortState(value: SortState | null);
109
180
  /**
110
181
  * Optional User View entity that provides view configuration
111
182
  * When provided, the component will use the view's WhereClause, GridState, SortState, etc.
112
183
  * The view's filter is additive - UserSearchString is applied ON TOP of the view's WhereClause
113
184
  */
114
- get viewEntity(): MJUserViewEntityExtended | null;
115
- set viewEntity(value: MJUserViewEntityExtended | null);
185
+ get ViewEntity(): MJUserViewEntityExtended | null;
186
+ set ViewEntity(value: MJUserViewEntityExtended | null);
116
187
  /**
117
188
  * Grid state configuration from a User View
118
189
  * Controls column visibility, widths, order, and sort settings
119
190
  */
120
- gridState: ViewGridState | null;
121
- /**
122
- * Timeline configuration state
123
- * Controls which date field is used and segment grouping
124
- */
125
- get timelineConfig(): TimelineState | null;
126
- set timelineConfig(value: TimelineState | null);
127
- /**
128
- * Whether to show the grid toolbar.
129
- * When false, the grid is displayed without its own toolbar - useful when
130
- * entity-viewer provides its own filter/actions in the header.
131
- * @default false
132
- */
133
- showGridToolbar: boolean;
134
- /**
135
- * Grid toolbar configuration - controls which buttons are shown and their behavior
136
- * When not provided, uses sensible defaults
137
- */
138
- gridToolbarConfig: Partial<GridToolbarConfig> | null;
139
- /**
140
- * Grid selection mode
141
- * @default 'single'
142
- */
143
- gridSelectionMode: GridSelectionMode;
144
- /**
145
- * Show the "Add to List" button in the grid toolbar.
146
- * Requires gridSelectionMode to be 'multiple' for best UX.
147
- * @default false
148
- */
149
- showAddToListButton: boolean;
191
+ GridState: ViewGridState | null;
150
192
  /**
151
193
  * Whether to render the Recycle Bin chip in the viewer header.
152
194
  * The chip auto-hides itself when the entity has no deleted records,
@@ -158,123 +200,150 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
158
200
  /**
159
201
  * Emitted when a record is selected (single click)
160
202
  */
161
- recordSelected: EventEmitter<RecordSelectedEvent>;
203
+ RecordSelected: EventEmitter<RecordSelectedEvent>;
162
204
  /**
163
205
  * Emitted when a record should be opened (double-click or open button)
164
206
  */
165
- recordOpened: EventEmitter<RecordOpenedEvent>;
207
+ RecordOpened: EventEmitter<RecordOpenedEvent>;
166
208
  /**
167
209
  * Emitted when data is loaded
168
210
  */
169
- dataLoaded: EventEmitter<DataLoadedEvent>;
170
- /**
171
- * Emitted when the view mode changes (for two-way binding)
172
- */
173
- viewModeChange: EventEmitter<EntityViewMode>;
211
+ DataLoaded: EventEmitter<DataLoadedEvent>;
174
212
  /**
175
213
  * Emitted when filter text changes (for two-way binding)
176
214
  */
177
- filterTextChange: EventEmitter<string>;
215
+ FilterTextChange: EventEmitter<string>;
178
216
  /**
179
217
  * Emitted when filtered count changes
180
218
  */
181
- filteredCountChanged: EventEmitter<FilteredCountChangedEvent>;
219
+ FilteredCountChanged: EventEmitter<FilteredCountChangedEvent>;
182
220
  /**
183
- * Emitted when sort state changes
221
+ * NAVIGATION request bubbled up from a plug-in renderer to open a *related* record on a
222
+ * (possibly different) entity — e.g. a grid foreign-key drill-through. Routing lives in the
223
+ * outer app, so this is one of the few signals that legitimately bubbles up. The container
224
+ * forwards it untouched.
184
225
  */
185
- sortChanged: EventEmitter<SortChangedEvent>;
226
+ OpenRelatedRecordRequested: EventEmitter<ViewRelatedRecordNavigation>;
186
227
  /**
187
- * Emitted when grid state changes (column resize, reorder, etc.)
228
+ * NAVIGATION request bubbled up from a plug-in renderer to create a new record of the current
229
+ * entity (e.g. a grid's "New" button). Opening the create form is a routing concern owned by
230
+ * the outer app; the container forwards it without acting on it.
188
231
  */
189
- gridStateChanged: EventEmitter<GridStateChangedEvent>;
232
+ CreateRecordRequested: EventEmitter<void>;
190
233
  /**
191
- * Emitted when timeline configuration changes (date field, grouping, etc.)
234
+ * The initial/active view type to open in, by `MJ: View Types` row ID. Hosts that persist
235
+ * the selection (e.g. Explorer's `UserView.ViewTypeID`) bind this so the viewer opens in the
236
+ * saved type — built-in OR plug-in. Applied once the registry resolves; later user switches
237
+ * emit {@link viewTypeChange} for the host to persist.
192
238
  */
193
- timelineConfigChange: EventEmitter<import("@memberjunction/core-entities").MJUserViewEntity_ITimelineState>;
239
+ set ViewTypeID(value: string | null);
240
+ get ViewTypeID(): string | null;
241
+ private _initialViewTypeId;
194
242
  /**
195
- * Emitted when the Add/New button is clicked in the grid toolbar
243
+ * The view-type options shown in the switcher, sourced from {@link ViewTypeEngine}
244
+ * (the `MJ: View Types` registry), filtered by each descriptor's availability predicate.
245
+ * Every option is a dynamic-mounted plug-in.
196
246
  */
197
- addRequested: EventEmitter<void>;
247
+ AvailableViewTypes: ViewModeOption[];
248
+ /** Whether the registry (ViewTypeEngine) successfully sourced the available view types. */
249
+ ViewTypesFromRegistry: boolean;
198
250
  /**
199
- * Emitted when the Delete button is clicked in the grid toolbar
200
- * Includes the selected records to be deleted
251
+ * The currently-active view type's stable key (descriptor Name). Null until the registry resolves.
201
252
  */
202
- deleteRequested: EventEmitter<{
203
- records: Record<string, unknown>[];
204
- }>;
253
+ ActiveViewTypeKey: string | null;
205
254
  /**
206
- * Emitted when the Refresh button is clicked in the grid toolbar
255
+ * The currently-active view type's option (the plug-in being mounted). Null until the
256
+ * registry resolves / a type is selected. Drives the dynamic-mount host in the template.
207
257
  */
208
- refreshRequested: EventEmitter<void>;
258
+ ActiveDynamicOption: ViewModeOption | null;
259
+ /** True once a plug-in view type is mounted (drives the dynamic host's visibility). */
260
+ get IsDynamicViewActive(): boolean;
261
+ /** Whether the view-type dropdown menu is currently open. */
262
+ ViewTypeDropdownOpen: boolean;
209
263
  /**
210
- * Emitted when the Export button is clicked in the grid toolbar
264
+ * Per-view-type configuration payloads, keyed by `MJ: View Types` row ID. Seeded from
265
+ * {@link viewTypeConfigsInput} and updated as plug-in renderers emit config changes;
266
+ * handed to each dynamic renderer on mount.
211
267
  */
212
- exportRequested: EventEmitter<{
213
- format: "excel" | "csv" | "json";
214
- }>;
268
+ private viewTypeConfigById;
215
269
  /**
216
- * Emitted when the Add to List button is clicked in the grid toolbar.
217
- * Parent components should handle this to show the list management dialog.
270
+ * Per-view-type configuration provided by the host (e.g. Explorer reading
271
+ * `UserView.DisplayState.viewTypeConfigs`). The active type is controlled separately via
272
+ * the `viewMode` / ViewTypeID inputs; this carries only the config payloads.
218
273
  */
219
- addToListRequested: EventEmitter<{
220
- entityInfo: EntityInfo;
221
- records: Record<string, unknown>[];
222
- recordIds: string[];
223
- }>;
274
+ set ViewTypeConfigs(value: Array<{
275
+ viewTypeId: string;
276
+ config: Record<string, unknown>;
277
+ }> | null);
224
278
  /**
225
- * Emitted when grid selection changes.
226
- * Parent components can use this to track selected records for their own toolbar buttons.
279
+ * When true, the viewer persists view-type/config changes itself — to the loaded `UserView`
280
+ * record (when a `ViewEntity`/`ViewID` is present) or to per-user User Settings (the default-view
281
+ * case). When false (the default), the viewer only emits the `Before…`/`After…` events and the
282
+ * consumer is responsible for persistence. Persistence is provider-based (generic-safe) — never
283
+ * routing, which stays with the host app.
227
284
  */
228
- selectionChanged: EventEmitter<{
229
- records: Record<string, unknown>[];
230
- recordIds: string[];
231
- }>;
232
- internalViewMode: EntityViewMode;
233
- internalFilterText: string;
234
- debouncedFilterText: string;
235
- isLoading: boolean;
236
- loadingMessage: string;
237
- internalRecords: Record<string, unknown>[];
238
- totalRecordCount: number;
239
- filteredRecordCount: number;
285
+ AutoSaveView: boolean;
286
+ /**
287
+ * Emitted (cancelable) BEFORE the active view type changes. A handler may set
288
+ * `args.Cancel = true` to veto the switch. Fires for both built-in and plug-in types.
289
+ */
290
+ BeforeViewTypeChange: EventEmitter<ViewTypeChangeEventArgs>;
291
+ /**
292
+ * Emitted AFTER the active view type has changed (and, when {@link AutoSaveView} is on, after
293
+ * it has been persisted). Notification only.
294
+ */
295
+ AfterViewTypeChange: EventEmitter<ViewTypeChangeEventArgs>;
296
+ /**
297
+ * Emitted (cancelable) BEFORE a plug-in renderer's configuration change is applied/persisted.
298
+ */
299
+ BeforeViewTypeConfigChange: EventEmitter<ViewTypeConfigChangeEventArgs>;
300
+ /**
301
+ * Emitted AFTER a plug-in renderer's configuration change has been applied (and persisted when
302
+ * {@link AutoSaveView} is on).
303
+ */
304
+ AfterViewTypeConfigChange: EventEmitter<ViewTypeConfigChangeEventArgs>;
305
+ /** Anchor for dynamically-mounted plug-in view renderers. */
306
+ private dynamicViewHost?;
307
+ /** The currently-ACTIVE (visible) plug-in renderer, if any. */
308
+ private dynamicRendererRef;
309
+ /** Input names the active plug-in declares (from `reflectComponentType`), used to push only the
310
+ * generic inputs it accepts. Mirrors the active cache entry's input set. */
311
+ private dynamicInputNames;
312
+ /**
313
+ * Cache of mounted plug-in renderer instances for the CURRENT data context (entity + view),
314
+ * keyed by `MJ: View Types` row ID. Switching view types within the same entity+view SHOWS/HIDES
315
+ * cached instances (preserving their state — e.g. a computed cluster scatter, grid scroll) instead
316
+ * of destroy/recreate. The whole cache is destroyed + rebuilt only when the data context changes:
317
+ * entity change, or view (record / ViewID, including default↔saved) change. See
318
+ * {@link clearDynamicRendererCache}.
319
+ */
320
+ private dynamicRendererCache;
321
+ InternalFilterText: string;
322
+ DebouncedFilterText: string;
323
+ IsLoading: boolean;
324
+ LoadingMessage: string;
325
+ InternalRecords: Record<string, unknown>[];
326
+ TotalRecordCount: number;
327
+ FilteredRecordCount: number;
240
328
  /** Track which records matched on hidden (non-visible) fields */
241
- hiddenFieldMatches: Map<string, string>;
329
+ HiddenFieldMatches: Map<string, string>;
242
330
  /** Current sort state */
243
- internalSortState: SortState | null;
244
- /** Cached grid params to avoid recreating object on every change detection */
245
- private _cachedGridParams;
246
- private _lastGridParamsEntity;
247
- private _lastGridParamsViewEntity;
331
+ InternalSortState: SortState | null;
248
332
  /** Pagination state */
249
- pagination: PaginationState;
250
- /** Whether the current entity has date fields available for timeline view */
251
- hasDateFields: boolean;
252
- /** Whether the current entity supports geocoding (has SupportsGeoCoding = 1) */
253
- HasGeoCoding: boolean;
254
- /** Available date fields from the entity (sorted by priority) */
255
- availableDateFields: EntityFieldInfo[];
256
- /** Timeline groups configuration for the timeline component */
257
- get timelineGroups(): TimelineGroup<Record<string, unknown>>[];
258
- set timelineGroups(value: TimelineGroup<Record<string, unknown>>[]);
259
- private _timelineGroups;
260
- /** Timeline sort order */
261
- timelineSortOrder: TimelineSortOrder;
262
- /** Timeline segment grouping */
263
- timelineSegmentGrouping: TimeSegmentGrouping;
264
- /** Timeline orientation (vertical or horizontal) */
265
- timelineOrientation: TimelineOrientation;
266
- /** Currently selected date field for timeline */
267
- selectedTimelineDateField: string | null;
333
+ Pagination: PaginationState;
268
334
  private destroy$;
269
335
  private filterInput$;
270
336
  /** Track if this is the first load (vs. load more) */
271
337
  private isInitialLoad;
272
- /** Reference to the data grid component for flushing pending changes */
273
- private dataGridRef;
274
- constructor(cdr: ChangeDetectorRef, ngZone: NgZone);
338
+ constructor(cdr: ChangeDetectorRef, ngZone: NgZone, elementRef: ElementRef<HTMLElement>);
339
+ /** IntersectionObserver used to detect when this viewer is re-attached/re-shown (Explorer caches +
340
+ * reattaches resource components without firing Angular lifecycle hooks). See {@link ngAfterViewInit}. */
341
+ private _visibilityObserver;
342
+ private _wasVisible;
275
343
  /**
276
- * Ensures any pending grid state changes are saved immediately without waiting for debounce.
277
- * Call this before switching views or entities to ensure changes are saved.
344
+ * Hook retained for hosts (e.g. the workspace) that call this before switching views/entities.
345
+ * View-type-specific persistence (e.g. a grid's live column/sort state) is now owned by the
346
+ * mounted plug-in renderer, so the container has nothing to flush — this is a no-op.
278
347
  */
279
348
  EnsurePendingChangesSaved(): void;
280
349
  /**
@@ -282,7 +351,7 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
282
351
  * This allows callers to provide just a viewEntity without explicitly setting the entity input.
283
352
  * Uses fallback resolution when ViewEntityInfo is not available.
284
353
  */
285
- get effectiveEntity(): EntityInfo | null;
354
+ get EffectiveEntity(): EntityInfo | null;
286
355
  /**
287
356
  * Gets EntityInfo from a ViewEntity with multiple fallback strategies.
288
357
  * Priority: 1) ViewEntityInfo property (set by Load)
@@ -291,52 +360,27 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
291
360
  * Returns null if entity cannot be determined.
292
361
  */
293
362
  private getEntityInfoFromViewEntity;
294
- /**
295
- * Get the effective view mode (external or internal)
296
- */
297
- get effectiveViewMode(): EntityViewMode;
298
363
  /**
299
364
  * Get the effective filter text (external or internal)
300
365
  */
301
- get effectiveFilterText(): string;
302
- /**
303
- * Get the raw ID value from selectedRecordId for timeline selection.
304
- * The selectedRecordId is in composite key format (e.g., "ID|abc-123" or "ID=abc-123"),
305
- * but the timeline stores just the raw ID value.
306
- */
307
- get timelineSelectedEventId(): string | null;
366
+ get EffectiveFilterText(): string;
308
367
  /**
309
368
  * Get the effective sort state (external or internal)
310
369
  */
311
- get effectiveSortState(): SortState | null;
312
- /**
313
- * Get the OrderBy string for mj-entity-data-grid from the effective sort state
314
- */
315
- get effectiveSortOrderBy(): string;
370
+ get EffectiveSortState(): SortState | null;
316
371
  /**
317
372
  * Get merged configuration with defaults
318
373
  */
319
- get effectiveConfig(): Required<EntityViewerConfig>;
320
- /**
321
- * Get cached grid params - only recreates object when entity or viewEntity changes
322
- * This prevents Angular from seeing a new object reference on every change detection
323
- * which would cause the grid to reinitialize
324
- */
325
- get gridParams(): RunViewParams | null;
326
- /**
327
- * Get the effective grid toolbar configuration
328
- * Merges user-provided config with defaults appropriate for entity-viewer context
329
- */
330
- get effectiveGridToolbarConfig(): GridToolbarConfig;
374
+ get EffectiveConfig(): Required<EntityViewerConfig>;
331
375
  /**
332
376
  * Get the records to display (external or internal)
333
377
  */
334
- get displayRecords(): Record<string, unknown>[];
378
+ get DisplayRecords(): Record<string, unknown>[];
335
379
  /**
336
380
  * Get filtered records - when using server-side filtering, records are already filtered
337
381
  * When using client-side filtering, apply filter locally
338
382
  */
339
- get filteredRecords(): Record<string, unknown>[];
383
+ get FilteredRecords(): Record<string, unknown>[];
340
384
  /**
341
385
  * Check if a record matches the filter text (client-side)
342
386
  */
@@ -356,11 +400,11 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
356
400
  /**
357
401
  * Check if a record matched on a hidden field
358
402
  */
359
- hasHiddenFieldMatch(record: Record<string, unknown>): boolean;
403
+ HasHiddenFieldMatch(record: Record<string, unknown>): boolean;
360
404
  /**
361
405
  * Get the name of the hidden field that matched for display
362
406
  */
363
- getHiddenMatchFieldName(record: Record<string, unknown>): string;
407
+ GetHiddenMatchFieldName(record: Record<string, unknown>): string;
364
408
  ngOnInit(): void;
365
409
  /**
366
410
  * Defers a data reload to a microtask so that all Angular input bindings
@@ -368,6 +412,14 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
368
412
  * Multiple calls within the same change detection cycle collapse into one load.
369
413
  */
370
414
  private deferReload;
415
+ ngAfterViewInit(): void;
416
+ /**
417
+ * Called when the viewer becomes visible again after being detached (cached-tab reattach). Mounts
418
+ * the active plug-in if it was never created (host wasn't ready at selection time), or re-pushes the
419
+ * current inputs so a host-fed grid re-renders its rows (the "N records in header but empty grid on
420
+ * return" symptom).
421
+ */
422
+ private onViewerReattached;
371
423
  ngOnDestroy(): void;
372
424
  /**
373
425
  * Extracts sort state from a view entity, checking ViewSortInfo first then
@@ -392,201 +444,164 @@ export declare class EntityViewerComponent extends BaseAngularComponent implemen
392
444
  /**
393
445
  * Load data for the current entity with server-side filtering/sorting/pagination
394
446
  */
395
- loadData(): Promise<void>;
447
+ LoadData(): Promise<void>;
396
448
  /**
397
449
  * Handle page change from PaginationComponent
398
450
  */
399
- onPageChange(event: PageChangeEvent): void;
451
+ OnPageChange(event: PageChangeEvent): void;
400
452
  /**
401
453
  * Refresh data (re-load from server, starting at page 1)
402
454
  * Keeps existing records visible during refresh for better UX
403
455
  */
404
- refresh(): void;
405
- /**
406
- * Set the view mode and emit change event
407
- */
408
- setViewMode(mode: EntityViewMode): void;
409
- /**
410
- * Handle filter input change
411
- */
412
- onFilterChange(value: string): void;
413
- /**
414
- * Clear the filter
415
- */
416
- clearFilter(): void;
417
- /**
418
- * Handle sort change from grid component
419
- */
420
- onSortChanged(event: SortChangedEvent): void;
421
- /**
422
- * Handle record selection from child components (grid or cards)
423
- */
424
- onRecordSelected(event: RecordSelectedEvent): void;
425
- /**
426
- * Handle record opened from child components (grid or cards)
427
- */
428
- onRecordOpened(event: RecordOpenedEvent): void;
429
- /**
430
- * Handle grid state changes (column resize, reorder, etc.)
431
- */
432
- onGridStateChanged(event: GridStateChangedEvent): void;
456
+ Refresh(): void;
433
457
  /**
434
- * Handle page change from the data grid's pager
458
+ * Loads the ViewTypeEngine once, then recomputes the available view types for the
459
+ * current entity. Fire-and-forget from lifecycle/setters — failures simply leave the
460
+ * switcher empty until the registry is available.
435
461
  */
436
- onGridPageChange(event: PageChangeEvent): void;
462
+ private ensureViewTypesLoaded;
437
463
  /**
438
- * Handle row click from mj-entity-data-grid
439
- * Maps to recordSelected event for parent components
464
+ * Recomputes {@link AvailableViewTypes} from the registry for the current entity. Every
465
+ * available view type is a dynamic-mounted plug-in. Reconciles the active selection when the
466
+ * previously-active type is no longer available (e.g. the entity changed).
440
467
  */
441
- onDataGridRowClick(event: AfterRowClickEventArgs): void;
468
+ private refreshAvailableViewTypes;
442
469
  /**
443
- * Handle row double-click from mj-entity-data-grid
444
- * Maps to recordOpened event for parent components
470
+ * Returns the switcher option for the active view type (for the current-type chip in the
471
+ * switcher), or null before the registry resolves.
445
472
  */
446
- onDataGridRowDoubleClick(event: AfterRowDoubleClickEventArgs): void;
473
+ get ActiveViewTypeOption(): ViewModeOption | null;
447
474
  /**
448
- * Handle sort changed from mj-entity-data-grid
449
- * Maps to sortChanged event for parent components
475
+ * Selects a view type from the switcher. Built-in types route to {@link setViewMode}
476
+ * (preserving the rich grid/cards/timeline/map integration); plug-in types are
477
+ * dynamic-mounted via the descriptor's RendererComponent. Emits {@link viewTypeChange}
478
+ * so hosts can persist `UserView.ViewTypeID`.
450
479
  */
451
- onDataGridSortChanged(event: AfterSortEventArgs): void;
480
+ SelectViewType(option: ViewModeOption): void;
452
481
  /**
453
- * Handle foreign key link click from mj-entity-data-grid
454
- * Bubbles the event up for parent components to handle navigation
482
+ * Selects a view type by its `MJ: View Types` row ID. This is the entry point used by external
483
+ * chrome (e.g. the workspace toolbar's {@link ViewTypeSwitcherComponent}) that surfaces the
484
+ * switcher outside the viewer's own header. Resolves the matching available option and applies
485
+ * it through the same lifecycle as a header-driven switch (cancelable events + persistence).
486
+ * No-op when the ID isn't an available view type or is already active.
487
+ *
488
+ * @param viewTypeId the `MJ: View Types` row ID to switch to.
455
489
  */
490
+ SelectViewTypeById(viewTypeId: string | null): void;
456
491
  /**
457
- * Handle foreign key link click from mj-entity-data-grid
458
- * Converts to recordOpened event for seamless navigation integration
492
+ * The `MJ: View Types` row ID of the currently-active view type, or null before the registry
493
+ * resolves. Lets external chrome (the workspace toolbar switcher) reflect the viewer's active
494
+ * type without reaching into the viewer's internal {@link ViewModeOption}s.
459
495
  */
460
- onForeignKeyClick(event: ForeignKeyClickEvent): void;
496
+ get ActiveViewTypeId(): string | null;
461
497
  /**
462
- * Handle Add/New button click from data grid toolbar
498
+ * Applies a view-type selection. `emit` is true for user-initiated switches (fires the
499
+ * cancelable {@link BeforeViewTypeChange}, persists when {@link AutoSaveView} is on, then fires
500
+ * {@link AfterViewTypeChange}) and false for internal reconciliation (no events, no persist).
501
+ *
502
+ * Every view type is a dynamic-mounted plug-in: this tears down the previous renderer and mounts
503
+ * the selected descriptor's `RendererComponent`. The container resets its generic load mode (a
504
+ * fresh plug-in that needs the full set will re-request it via `dataRequest({loadAll:true})`) and
505
+ * reloads page-based data when the active type changes.
463
506
  */
464
- onGridAddRequested(): void;
507
+ private applyViewTypeSelection;
465
508
  /**
466
- * Handle Refresh button click from data grid toolbar
509
+ * Where view-type/config persists when {@link AutoSaveView} is on: a loaded `UserView` record,
510
+ * per-user User Settings (the default-view case), or nowhere.
467
511
  */
468
- onGridRefreshRequested(): void;
512
+ private persistenceTarget;
513
+ /** Persist the active view-type selection to the resolved target. */
514
+ private persistActiveViewType;
515
+ /** Persist a per-view-type config change to the resolved target. */
516
+ private persistViewTypeConfig;
517
+ /** Save the loaded view record, logging (not throwing) on failure. */
518
+ private saveViewEntity;
519
+ /** User Settings key for this entity's per-user default-view state. */
520
+ private defaultViewSettingKey;
521
+ /** Persist the per-user default-view state (active view type + per-type configs) to User Settings. */
522
+ private saveDefaultViewSetting;
523
+ /** Convert the in-memory per-view-type config map to the persisted array shape. */
524
+ private serializeViewTypeConfigs;
469
525
  /**
470
- * Handle Delete button click from data grid toolbar
526
+ * Resolve which view type the viewer should open in, in priority order:
527
+ * explicit `ViewTypeID` input → the loaded `UserView` record's `ViewTypeID` → the per-user
528
+ * default-view setting (User Settings). Returns null to let the caller fall back to the legacy
529
+ * mode / first available type. This is how the viewer is self-contained for both the saved-view
530
+ * and default-view cases without the consumer wiring anything.
471
531
  */
472
- onGridDeleteRequested(records: Record<string, unknown>[]): void;
532
+ private resolveInitialViewTypeId;
473
533
  /**
474
- * Handle Export button click from data grid toolbar
534
+ * Load a saved view by ID via the active provider and apply it through the {@link viewEntity}
535
+ * setter. Backs the {@link ViewID} convenience input. Logs (does not throw) on failure.
475
536
  */
476
- onGridExportRequested(): void;
537
+ private loadViewById;
538
+ /** Read the per-user default-view setting for the current entity (or null). */
539
+ private readDefaultViewSetting;
477
540
  /**
478
- * Handle Add to List button click from data grid toolbar.
479
- * Forwards the event to parent components for list management.
541
+ * Seed the in-memory per-view-type config map from the available sources when the consumer
542
+ * hasn't supplied them via the {@link ViewTypeConfigs} input: the loaded `UserView` record's
543
+ * `DisplayState.viewTypeConfigs` (saved-view case) or the per-user default-view setting.
544
+ * Only seeds when the map is empty, so an explicit input always wins.
480
545
  */
481
- onGridAddToListRequested(event: {
482
- entityInfo: EntityInfo;
483
- records: Record<string, unknown>[];
484
- recordIds: string[];
485
- }): void;
546
+ private seedViewTypeConfigsIfEmpty;
486
547
  /**
487
- * Handle selection change from data grid.
488
- * Converts selected keys to records and forwards to parent components.
548
+ * Makes `option`'s plug-in the ACTIVE view: reuses its cached instance when present (preserving
549
+ * state), otherwise creates it. All other cached instances are hidden (kept mounted). The container
550
+ * has zero knowledge of which plug-in this is — it only knows the {@link IViewRenderer} contract.
489
551
  */
490
- onGridSelectionChange(selectedKeys: string[]): void;
552
+ private selectDynamicRenderer;
491
553
  /**
492
- * Handle timeline event click - emit as record selection
554
+ * Creates a plug-in renderer instance, wires its generic outputs, captures its declared inputs,
555
+ * and caches it by `MJ: View Types` row ID. (Does not show/activate it — {@link selectDynamicRenderer}
556
+ * does that.)
493
557
  */
494
- onTimelineEventClick(event: AfterEventClickArgs): void;
558
+ private createDynamicRenderer;
495
559
  /**
496
- * Update HasGeoCoding based on the current effectiveEntity.
497
- * Called from entity setter and after data loads (when effectiveEntity may resolve via viewEntity).
560
+ * Toggle a cached renderer's host element visibility without destroying it (preserves state).
561
+ * When visible, force `display: block` + `height: 100%` rather than clearing the style: the wrapper
562
+ * components use `ViewEncapsulation.None`, under which their `:host { display:block; height:100% }`
563
+ * rule is a no-op, so a custom element defaults to `display: inline` — which gives AG Grid a
564
+ * zero-width viewport (no rows/columns render), especially after a hide → show cycle. Forcing block
565
+ * here guarantees every view-type plug-in gets a full-size block container.
498
566
  */
499
- private updateGeoCodingSupport;
567
+ private setRendererVisible;
500
568
  /**
501
- * Handle map marker click emit the record for the parent to handle (open record, etc.)
569
+ * Destroys ALL cached plug-in instances and clears the host. Called when the data context changes
570
+ * (entity change / view (record / ViewID) change) so the next selection rebuilds fresh. NOT called
571
+ * on a plain view-type switch within the same context — that path reuses cached instances.
502
572
  */
503
- onMapMarkerClick(event: {
504
- RecordID: string;
505
- Latitude: number;
506
- Longitude: number;
507
- Record: Record<string, unknown>;
508
- }): void;
509
- /** Map display state (zoom, center) — passed from parent for persistence across reloads. */
510
- mapDisplayState: Partial<MapDisplayState> | null;
511
- /** Map render mode — separate from DisplayState for clear single-source-of-truth. */
512
- mapRenderMode: MapRenderMode;
513
- /** Emitted when the map's display state changes (zoom, center). */
514
- mapDisplayStateChange: EventEmitter<MapDisplayState>;
515
- /** Emitted when the map's render mode changes (user clicks mode buttons). */
516
- mapRenderModeChange: EventEmitter<MapRenderMode>;
573
+ private clearDynamicRendererCache;
517
574
  /**
518
- * Handle map display state changes bubble up to parent for persistence.
575
+ * Pushes the current generic data-context into the mounted plug-in renderer via `setInput`.
576
+ * Every input is part of the generic {@link IViewRenderer} contract; lean plug-ins may not declare
577
+ * all of them, so each `setInput` is wrapped in try/catch (Angular throws on undeclared inputs).
519
578
  */
520
- onMapDisplayStateChange(state: MapDisplayState): void;
521
- onMapRenderModeChange(mode: MapRenderMode): void;
579
+ private pushDynamicRendererInputs;
522
580
  /**
523
- * Toggle timeline orientation between vertical and horizontal
581
+ * Guarded `setInput`: lean plug-ins implement only the core contract, so we only set an input the
582
+ * mounted plug-in actually declares (per {@link dynamicInputNames}, captured at mount via
583
+ * `reflectComponentType`). This avoids NG0303 dev errors for optional inputs the plug-in omits and
584
+ * keeps the container plug-in-agnostic.
524
585
  */
525
- toggleTimelineOrientation(): void;
586
+ private setDynamicInput;
587
+ private onDynamicRecordSelected;
588
+ private onDynamicRecordOpened;
589
+ private onDynamicConfigChanged;
526
590
  /**
527
- * Toggle timeline sort order between newest first (desc) and oldest first (asc)
591
+ * Honors a generic {@link ViewDataRequest} from the mounted plug-in. Fully view-type-agnostic
592
+ * the container applies whatever is present (sort / page / pageSize / loadAll) against its
593
+ * existing generic data-loading path. No per-view-type branching.
528
594
  */
529
- toggleTimelineSortOrder(): void;
595
+ private onDynamicDataRequest;
530
596
  /**
531
- * Change the date field used for the timeline
532
- */
533
- setTimelineDateField(fieldName: string): void;
534
- /**
535
- * Get the display name of the currently selected timeline date field
536
- */
537
- get selectedDateFieldDisplayName(): string;
538
- /**
539
- * Emit the current timeline configuration for persistence
540
- */
541
- private emitTimelineConfigChange;
542
- /**
543
- * Detect and configure timeline based on entity's date fields
544
- * Called when entity changes
545
- */
546
- private detectDateFields;
547
- /**
548
- * If currently on timeline view but timeline is no longer available,
549
- * fall back to grid view
550
- */
551
- private fallbackFromTimelineIfNeeded;
552
- /**
553
- * If currently on map view but geocoding is no longer available,
554
- * fall back to grid view
555
- */
556
- private fallbackFromMapIfNeeded;
557
- /**
558
- * Sort date fields by priority:
559
- * 1. DefaultInView=true fields, sorted by Sequence (lowest first)
560
- * 2. Other date fields, sorted by Sequence (lowest first)
561
- */
562
- private sortDateFieldsByPriority;
563
- /**
564
- * Configure the timeline with the current date field and records
565
- */
566
- private configureTimeline;
567
- /**
568
- * Get the effective date field to use for timeline
569
- * Priority: timelineConfig > first available date field
570
- */
571
- private getEffectiveTimelineDateField;
572
- /**
573
- * Update timeline groups with current records
574
- * Called when records change
575
- */
576
- private updateTimelineGroups;
577
- /**
578
- * Find the best field to use as the title
579
- */
580
- private findTitleField;
581
- /**
582
- * Find a suitable description field
597
+ * Handle filter input change
583
598
  */
584
- private findDescriptionField;
599
+ OnFilterChange(value: string): void;
585
600
  /**
586
- * Find a suitable subtitle field (different from title)
601
+ * Clear the filter
587
602
  */
588
- private findSubtitleField;
603
+ ClearFilter(): void;
589
604
  static ɵfac: i0.ɵɵFactoryDeclaration<EntityViewerComponent, never>;
590
- static ɵcmp: i0.ɵɵComponentDeclaration<EntityViewerComponent, "mj-entity-viewer", never, { "entity": { "alias": "entity"; "required": false; }; "records": { "alias": "records"; "required": false; }; "config": { "alias": "config"; "required": false; }; "selectedRecordId": { "alias": "selectedRecordId"; "required": false; }; "viewMode": { "alias": "viewMode"; "required": false; }; "filterText": { "alias": "filterText"; "required": false; }; "sortState": { "alias": "sortState"; "required": false; }; "gridColumns": { "alias": "gridColumns"; "required": false; }; "cardTemplate": { "alias": "cardTemplate"; "required": false; }; "viewEntity": { "alias": "viewEntity"; "required": false; }; "gridState": { "alias": "gridState"; "required": false; }; "timelineConfig": { "alias": "timelineConfig"; "required": false; }; "showGridToolbar": { "alias": "showGridToolbar"; "required": false; }; "gridToolbarConfig": { "alias": "gridToolbarConfig"; "required": false; }; "gridSelectionMode": { "alias": "gridSelectionMode"; "required": false; }; "showAddToListButton": { "alias": "showAddToListButton"; "required": false; }; "ShowRecycleBin": { "alias": "ShowRecycleBin"; "required": false; }; "mapDisplayState": { "alias": "mapDisplayState"; "required": false; }; "mapRenderMode": { "alias": "mapRenderMode"; "required": false; }; }, { "recordSelected": "recordSelected"; "recordOpened": "recordOpened"; "dataLoaded": "dataLoaded"; "viewModeChange": "viewModeChange"; "filterTextChange": "filterTextChange"; "filteredCountChanged": "filteredCountChanged"; "sortChanged": "sortChanged"; "gridStateChanged": "gridStateChanged"; "timelineConfigChange": "timelineConfigChange"; "addRequested": "addRequested"; "deleteRequested": "deleteRequested"; "refreshRequested": "refreshRequested"; "exportRequested": "exportRequested"; "addToListRequested": "addToListRequested"; "selectionChanged": "selectionChanged"; "mapDisplayStateChange": "mapDisplayStateChange"; "mapRenderModeChange": "mapRenderModeChange"; }, never, never, false, never>;
605
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntityViewerComponent, "mj-entity-viewer", never, { "Entity": { "alias": "Entity"; "required": false; }; "EntityName": { "alias": "EntityName"; "required": false; }; "EntityID": { "alias": "EntityID"; "required": false; }; "ViewID": { "alias": "ViewID"; "required": false; }; "Records": { "alias": "Records"; "required": false; }; "Config": { "alias": "Config"; "required": false; }; "SelectedRecordID": { "alias": "SelectedRecordID"; "required": false; }; "FilterText": { "alias": "FilterText"; "required": false; }; "SortState": { "alias": "SortState"; "required": false; }; "ViewEntity": { "alias": "ViewEntity"; "required": false; }; "GridState": { "alias": "GridState"; "required": false; }; "ShowRecycleBin": { "alias": "ShowRecycleBin"; "required": false; }; "ViewTypeID": { "alias": "ViewTypeID"; "required": false; }; "ViewTypeConfigs": { "alias": "ViewTypeConfigs"; "required": false; }; "AutoSaveView": { "alias": "AutoSaveView"; "required": false; }; }, { "RecordSelected": "RecordSelected"; "RecordOpened": "RecordOpened"; "DataLoaded": "DataLoaded"; "FilterTextChange": "FilterTextChange"; "FilteredCountChanged": "FilteredCountChanged"; "OpenRelatedRecordRequested": "OpenRelatedRecordRequested"; "CreateRecordRequested": "CreateRecordRequested"; "BeforeViewTypeChange": "BeforeViewTypeChange"; "AfterViewTypeChange": "AfterViewTypeChange"; "BeforeViewTypeConfigChange": "BeforeViewTypeConfigChange"; "AfterViewTypeConfigChange": "AfterViewTypeConfigChange"; }, never, never, false, never>;
591
606
  }
592
607
  //# sourceMappingURL=entity-viewer.component.d.ts.map