@memberjunction/ng-query-viewer 5.49.0 → 5.51.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.
@@ -151,6 +151,16 @@ export declare class QueryDataGridComponent implements OnInit, OnDestroy {
151
151
  PageNumber: number;
152
152
  /** Page size for server-side paging */
153
153
  PageSize: number;
154
+ /**
155
+ * Optional provider that returns the FULL result set for export. When the grid is server-side
156
+ * paged, `Data` only holds the current page (default 100 rows), so exporting `Data` would silently
157
+ * cap the export at the page size (bug B3/C1). A host that owns the query (with its parameters) can
158
+ * supply this callback to fetch every matching row on demand; the grid awaits it when the user
159
+ * exports without an explicit row selection. When not provided, export falls back to the loaded page.
160
+ */
161
+ ExportDataProvider: (() => Promise<Record<string, unknown>[]>) | null;
162
+ /** True while an export is fetching the full result set via ExportDataProvider. */
163
+ IsPreparingExport: boolean;
154
164
  /** Fired when the user navigates to a different page */
155
165
  PageChange: EventEmitter<PageChangeEvent>;
156
166
  GridApi: GridApi | null;
@@ -226,7 +236,7 @@ export declare class QueryDataGridComponent implements OnInit, OnDestroy {
226
236
  /**
227
237
  * Opens the export dialog with current grid data
228
238
  */
229
- OpenExportDialog(): void;
239
+ OpenExportDialog(): Promise<void>;
230
240
  /**
231
241
  * Handle export dialog close
232
242
  */
@@ -236,9 +246,12 @@ export declare class QueryDataGridComponent implements OnInit, OnDestroy {
236
246
  */
237
247
  Export(options?: Partial<ExportOptions>, download?: boolean): Promise<ExportResult>;
238
248
  /**
239
- * Get the current grid data formatted for export
249
+ * Resolves the rows to export. An explicit row selection always wins. Otherwise, if a host
250
+ * supplied an ExportDataProvider, the full result set is fetched (so export isn't silently
251
+ * capped at the current page — bug B3/C1); if it isn't supplied or the fetch yields nothing,
252
+ * export falls back to the loaded page (`_data`).
240
253
  */
241
- private getExportData;
254
+ private resolveExportData;
242
255
  /**
243
256
  * Get column definitions for export based on current grid columns
244
257
  */
@@ -267,6 +280,6 @@ export declare class QueryDataGridComponent implements OnInit, OnDestroy {
267
280
  */
268
281
  OnRowDetailEntityLinkClick(event: RowDetailEntityLinkEvent): void;
269
282
  static ɵfac: i0.ɵɵFactoryDeclaration<QueryDataGridComponent, never>;
270
- static ɵcmp: i0.ɵɵComponentDeclaration<QueryDataGridComponent, "mj-query-data-grid", never, { "QueryInfo": { "alias": "QueryInfo"; "required": false; }; "ColumnConfigs": { "alias": "ColumnConfigs"; "required": false; }; "Data": { "alias": "Data"; "required": false; }; "SelectionMode": { "alias": "SelectionMode"; "required": false; }; "ShowToolbar": { "alias": "ShowToolbar"; "required": false; }; "ShowRowCount": { "alias": "ShowRowCount"; "required": false; }; "ShowSelectionCount": { "alias": "ShowSelectionCount"; "required": false; }; "ShowExport": { "alias": "ShowExport"; "required": false; }; "ShowRefresh": { "alias": "ShowRefresh"; "required": false; }; "AllowSorting": { "alias": "AllowSorting"; "required": false; }; "AllowColumnResize": { "alias": "AllowColumnResize"; "required": false; }; "AllowColumnReorder": { "alias": "AllowColumnReorder"; "required": false; }; "VisualConfig": { "alias": "VisualConfig"; "required": false; }; "IsLoading": { "alias": "IsLoading"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "InitialGridState": { "alias": "InitialGridState"; "required": false; }; "PersistState": { "alias": "PersistState"; "required": false; }; "TotalRowCount": { "alias": "TotalRowCount"; "required": false; }; "PageNumber": { "alias": "PageNumber"; "required": false; }; "PageSize": { "alias": "PageSize"; "required": false; }; }, { "RowClick": "RowClick"; "RowDoubleClick": "RowDoubleClick"; "EntityLinkClick": "EntityLinkClick"; "SelectionChange": "SelectionChange"; "GridStateChange": "GridStateChange"; "RefreshRequest": "RefreshRequest"; "PageChange": "PageChange"; }, never, never, false, never>;
283
+ static ɵcmp: i0.ɵɵComponentDeclaration<QueryDataGridComponent, "mj-query-data-grid", never, { "QueryInfo": { "alias": "QueryInfo"; "required": false; }; "ColumnConfigs": { "alias": "ColumnConfigs"; "required": false; }; "Data": { "alias": "Data"; "required": false; }; "SelectionMode": { "alias": "SelectionMode"; "required": false; }; "ShowToolbar": { "alias": "ShowToolbar"; "required": false; }; "ShowRowCount": { "alias": "ShowRowCount"; "required": false; }; "ShowSelectionCount": { "alias": "ShowSelectionCount"; "required": false; }; "ShowExport": { "alias": "ShowExport"; "required": false; }; "ShowRefresh": { "alias": "ShowRefresh"; "required": false; }; "AllowSorting": { "alias": "AllowSorting"; "required": false; }; "AllowColumnResize": { "alias": "AllowColumnResize"; "required": false; }; "AllowColumnReorder": { "alias": "AllowColumnReorder"; "required": false; }; "VisualConfig": { "alias": "VisualConfig"; "required": false; }; "IsLoading": { "alias": "IsLoading"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "InitialGridState": { "alias": "InitialGridState"; "required": false; }; "PersistState": { "alias": "PersistState"; "required": false; }; "TotalRowCount": { "alias": "TotalRowCount"; "required": false; }; "PageNumber": { "alias": "PageNumber"; "required": false; }; "PageSize": { "alias": "PageSize"; "required": false; }; "ExportDataProvider": { "alias": "ExportDataProvider"; "required": false; }; }, { "RowClick": "RowClick"; "RowDoubleClick": "RowDoubleClick"; "EntityLinkClick": "EntityLinkClick"; "SelectionChange": "SelectionChange"; "GridStateChange": "GridStateChange"; "RefreshRequest": "RefreshRequest"; "PageChange": "PageChange"; }, never, never, false, never>;
271
284
  }
272
285
  //# sourceMappingURL=query-data-grid.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-data-grid.component.d.ts","sourceRoot":"","sources":["../../../src/lib/query-data-grid/query-data-grid.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-data-grid.component.d.ts","sourceRoot":"","sources":["../../../src/lib/query-data-grid/query-data-grid.component.ts"],"names":[],"mappings":"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"}
@@ -74,7 +74,9 @@ function QueryDataGridComponent_Conditional_1_Conditional_6_Template(rf, ctx) {
74
74
  i0.ɵɵelementEnd()();
75
75
  } if (rf & 2) {
76
76
  const ctx_r0 = i0.ɵɵnextContext(2);
77
- i0.ɵɵproperty("disabled", ctx_r0.RowCount === 0);
77
+ i0.ɵɵproperty("disabled", ctx_r0.RowCount === 0 || ctx_r0.IsPreparingExport);
78
+ i0.ɵɵadvance();
79
+ i0.ɵɵclassProp("fa-file-export", !ctx_r0.IsPreparingExport)("fa-spinner", ctx_r0.IsPreparingExport)("fa-spin", ctx_r0.IsPreparingExport);
78
80
  } }
79
81
  function QueryDataGridComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
80
82
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 9);
@@ -83,7 +85,7 @@ function QueryDataGridComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
83
85
  i0.ɵɵelementEnd();
84
86
  i0.ɵɵelementStart(4, "div", 12);
85
87
  i0.ɵɵconditionalCreate(5, QueryDataGridComponent_Conditional_1_Conditional_5_Template, 2, 3, "button", 13);
86
- i0.ɵɵconditionalCreate(6, QueryDataGridComponent_Conditional_1_Conditional_6_Template, 4, 1, "button", 14);
88
+ i0.ɵɵconditionalCreate(6, QueryDataGridComponent_Conditional_1_Conditional_6_Template, 4, 7, "button", 14);
87
89
  i0.ɵɵelementEnd()();
88
90
  } if (rf & 2) {
89
91
  const ctx_r0 = i0.ɵɵnextContext();
@@ -311,6 +313,16 @@ export class QueryDataGridComponent {
311
313
  PageNumber = 1;
312
314
  /** Page size for server-side paging */
313
315
  PageSize = 100;
316
+ /**
317
+ * Optional provider that returns the FULL result set for export. When the grid is server-side
318
+ * paged, `Data` only holds the current page (default 100 rows), so exporting `Data` would silently
319
+ * cap the export at the page size (bug B3/C1). A host that owns the query (with its parameters) can
320
+ * supply this callback to fetch every matching row on demand; the grid awaits it when the user
321
+ * exports without an explicit row selection. When not provided, export falls back to the loaded page.
322
+ */
323
+ ExportDataProvider = null;
324
+ /** True while an export is fetching the full result set via ExportDataProvider. */
325
+ IsPreparingExport = false;
314
326
  /** Fired when the user navigates to a different page */
315
327
  PageChange = new EventEmitter();
316
328
  // ========================================
@@ -905,10 +917,18 @@ export class QueryDataGridComponent {
905
917
  /**
906
918
  * Opens the export dialog with current grid data
907
919
  */
908
- OpenExportDialog() {
920
+ async OpenExportDialog() {
909
921
  if (!this._data.length)
910
922
  return;
911
- const data = this.getExportData();
923
+ this.IsPreparingExport = true;
924
+ this.cdr.detectChanges();
925
+ let data;
926
+ try {
927
+ data = await this.resolveExportData();
928
+ }
929
+ finally {
930
+ this.IsPreparingExport = false;
931
+ }
912
932
  const columns = this.getExportColumns();
913
933
  const fileName = this._queryInfo?.Name || 'query-export';
914
934
  this.ExportDialogConfig = {
@@ -936,7 +956,7 @@ export class QueryDataGridComponent {
936
956
  * Export grid data directly without showing dialog
937
957
  */
938
958
  async Export(options, download = true) {
939
- const data = this.getExportData();
959
+ const data = await this.resolveExportData();
940
960
  const columns = this.getExportColumns();
941
961
  const fileName = options?.fileName || this._queryInfo?.Name || 'query-export';
942
962
  const exportOptions = {
@@ -953,12 +973,27 @@ export class QueryDataGridComponent {
953
973
  return result;
954
974
  }
955
975
  /**
956
- * Get the current grid data formatted for export
976
+ * Resolves the rows to export. An explicit row selection always wins. Otherwise, if a host
977
+ * supplied an ExportDataProvider, the full result set is fetched (so export isn't silently
978
+ * capped at the current page — bug B3/C1); if it isn't supplied or the fetch yields nothing,
979
+ * export falls back to the loaded page (`_data`).
957
980
  */
958
- getExportData() {
959
- // Use selected rows if any, otherwise all data
960
- const rows = this.SelectedRows.length > 0 ? this.SelectedRows : this._data;
961
- return rows;
981
+ async resolveExportData() {
982
+ if (this.SelectedRows.length > 0) {
983
+ return this.SelectedRows;
984
+ }
985
+ if (this.ExportDataProvider) {
986
+ try {
987
+ const allRows = await this.ExportDataProvider();
988
+ if (allRows && allRows.length > 0) {
989
+ return allRows;
990
+ }
991
+ }
992
+ catch {
993
+ // Fall through to the loaded page on any fetch failure.
994
+ }
995
+ }
996
+ return this._data;
962
997
  }
963
998
  /**
964
999
  * Get column definitions for export based on current grid columns
@@ -1109,7 +1144,7 @@ export class QueryDataGridComponent {
1109
1144
  });
1110
1145
  }
1111
1146
  static ɵfac = function QueryDataGridComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || QueryDataGridComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.ExportService)); };
1112
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryDataGridComponent, selectors: [["mj-query-data-grid"]], inputs: { QueryInfo: "QueryInfo", ColumnConfigs: "ColumnConfigs", Data: "Data", SelectionMode: "SelectionMode", ShowToolbar: "ShowToolbar", ShowRowCount: "ShowRowCount", ShowSelectionCount: "ShowSelectionCount", ShowExport: "ShowExport", ShowRefresh: "ShowRefresh", AllowSorting: "AllowSorting", AllowColumnResize: "AllowColumnResize", AllowColumnReorder: "AllowColumnReorder", VisualConfig: "VisualConfig", IsLoading: "IsLoading", Height: "Height", InitialGridState: "InitialGridState", PersistState: "PersistState", TotalRowCount: "TotalRowCount", PageNumber: "PageNumber", PageSize: "PageSize" }, outputs: { RowClick: "RowClick", RowDoubleClick: "RowDoubleClick", EntityLinkClick: "EntityLinkClick", SelectionChange: "SelectionChange", GridStateChange: "GridStateChange", RefreshRequest: "RefreshRequest", PageChange: "PageChange" }, standalone: false, decls: 9, vars: 24, consts: [[1, "query-data-grid-container", 3, "ngClass"], [1, "grid-toolbar"], [1, "loading-overlay"], [1, "grid-wrapper"], [1, "query-grid", 3, "gridReady", "rowClicked", "rowDoubleClicked", "selectionChanged", "sortChanged", "columnResized", "columnMoved", "theme", "rowData", "columnDefs", "defaultColDef", "gridOptions", "rowSelection", "getRowId"], [3, "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], ["Icon", "fa-solid fa-database", "Title", "No results", "Message", "Run the query to see results", 1, "empty-state"], [3, "closed", "visible", "config"], [3, "Close", "EntityLinkClick", "NavigateRow", "RowData", "Columns", "QueryInfo", "Visible", "RowIndex", "TotalRows"], [1, "toolbar-left"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], ["title", "Refresh data", 1, "toolbar-btn", "icon-only", 3, "disabled"], ["title", "Export data", 1, "toolbar-btn", 3, "disabled"], [1, "fa-solid", "fa-table-list"], [1, "fa-solid", "fa-check-square"], ["title", "Clear selection", 1, "clear-selection-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["title", "Refresh data", 1, "toolbar-btn", "icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-sync-alt"], ["title", "Export data", 1, "toolbar-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-file-export"], [1, "button-text"], ["text", "Loading query results..."], [3, "PageChange", "TotalRowCount", "PageNumber", "PageSize", "IsLoading"]], template: function QueryDataGridComponent_Template(rf, ctx) { if (rf & 1) {
1147
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryDataGridComponent, selectors: [["mj-query-data-grid"]], inputs: { QueryInfo: "QueryInfo", ColumnConfigs: "ColumnConfigs", Data: "Data", SelectionMode: "SelectionMode", ShowToolbar: "ShowToolbar", ShowRowCount: "ShowRowCount", ShowSelectionCount: "ShowSelectionCount", ShowExport: "ShowExport", ShowRefresh: "ShowRefresh", AllowSorting: "AllowSorting", AllowColumnResize: "AllowColumnResize", AllowColumnReorder: "AllowColumnReorder", VisualConfig: "VisualConfig", IsLoading: "IsLoading", Height: "Height", InitialGridState: "InitialGridState", PersistState: "PersistState", TotalRowCount: "TotalRowCount", PageNumber: "PageNumber", PageSize: "PageSize", ExportDataProvider: "ExportDataProvider" }, outputs: { RowClick: "RowClick", RowDoubleClick: "RowDoubleClick", EntityLinkClick: "EntityLinkClick", SelectionChange: "SelectionChange", GridStateChange: "GridStateChange", RefreshRequest: "RefreshRequest", PageChange: "PageChange" }, standalone: false, decls: 9, vars: 24, consts: [[1, "query-data-grid-container", 3, "ngClass"], [1, "grid-toolbar"], [1, "loading-overlay"], [1, "grid-wrapper"], [1, "query-grid", 3, "gridReady", "rowClicked", "rowDoubleClicked", "selectionChanged", "sortChanged", "columnResized", "columnMoved", "theme", "rowData", "columnDefs", "defaultColDef", "gridOptions", "rowSelection", "getRowId"], [3, "TotalRowCount", "PageNumber", "PageSize", "IsLoading"], ["Icon", "fa-solid fa-database", "Title", "No results", "Message", "Run the query to see results", 1, "empty-state"], [3, "closed", "visible", "config"], [3, "Close", "EntityLinkClick", "NavigateRow", "RowData", "Columns", "QueryInfo", "Visible", "RowIndex", "TotalRows"], [1, "toolbar-left"], [1, "row-count"], [1, "selection-count"], [1, "toolbar-right"], ["title", "Refresh data", 1, "toolbar-btn", "icon-only", 3, "disabled"], ["title", "Export data", 1, "toolbar-btn", 3, "disabled"], [1, "fa-solid", "fa-table-list"], [1, "fa-solid", "fa-check-square"], ["title", "Clear selection", 1, "clear-selection-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["title", "Refresh data", 1, "toolbar-btn", "icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-sync-alt"], ["title", "Export data", 1, "toolbar-btn", 3, "click", "disabled"], [1, "fa-solid"], [1, "button-text"], ["text", "Loading query results..."], [3, "PageChange", "TotalRowCount", "PageNumber", "PageSize", "IsLoading"]], template: function QueryDataGridComponent_Template(rf, ctx) { if (rf & 1) {
1113
1148
  i0.ɵɵelementStart(0, "div", 0);
1114
1149
  i0.ɵɵconditionalCreate(1, QueryDataGridComponent_Conditional_1_Template, 7, 4, "div", 1);
1115
1150
  i0.ɵɵconditionalCreate(2, QueryDataGridComponent_Conditional_2_Template, 2, 1, "div", 2);
@@ -1168,7 +1203,7 @@ export class QueryDataGridComponent {
1168
1203
  animate('100ms ease-in', style({ opacity: 0, transform: 'translateY(-8px)' }))
1169
1204
  ])
1170
1205
  ])
1171
- ], template: "<!-- Query Data Grid Component -->\n<div class=\"query-data-grid-container\" [ngClass]=\"GetContainerClasses()\" [style.height]=\"Height\">\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Row count -->\n @if (ShowRowCount) {\n <span class=\"row-count\">\n <i class=\"fa-solid fa-table-list\"></i>\n @if (TotalRowCount > RowCount) {\n {{ RowCount | number }} of {{ TotalRowCount | number }} {{ TotalRowCount === 1 ? 'row' : 'rows' }}\n } @else {\n {{ RowCount | number }} {{ RowCount === 1 ? 'row' : 'rows' }}\n }\n </span>\n }\n <!-- Selection count -->\n @if (ShowSelectionCount && SelectionCount > 0) {\n <span class=\"selection-count\">\n <i class=\"fa-solid fa-check-square\"></i>\n {{ SelectionCount }} selected\n <button class=\"clear-selection-btn\" (click)=\"ClearSelection()\" title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Refresh button -->\n @if (ShowRefresh) {\n <button\n (click)=\"Refresh()\"\n [disabled]=\"IsLoading\"\n title=\"Refresh data\"\n class=\"toolbar-btn icon-only\">\n <i class=\"fa-solid fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i>\n </button>\n }\n <!-- Export button -->\n @if (ShowExport) {\n <button\n [disabled]=\"RowCount === 0\"\n title=\"Export data\"\n class=\"toolbar-btn\"\n (click)=\"OpenExportDialog()\">\n <i class=\"fa-solid fa-file-export\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Loading overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\" @fadeIn>\n <mj-loading text=\"Loading query results...\"></mj-loading>\n </div>\n }\n\n <!-- AG Grid -->\n <div class=\"grid-wrapper\" [class.loading]=\"IsLoading\">\n <ag-grid-angular\n class=\"query-grid\"\n [theme]=\"Theme\"\n [rowData]=\"Data\"\n [columnDefs]=\"ColumnDefs\"\n [defaultColDef]=\"DefaultColDef\"\n [gridOptions]=\"GridOptions\"\n [rowSelection]=\"GetRowSelectionConfig()\"\n [getRowId]=\"GetRowId\"\n (gridReady)=\"OnGridReady($event)\"\n (rowClicked)=\"OnRowClicked($event)\"\n (rowDoubleClicked)=\"OnRowDoubleClicked($event)\"\n (selectionChanged)=\"OnSelectionChanged($event)\"\n (sortChanged)=\"OnSortChanged($event)\"\n (columnResized)=\"OnColumnResized($event)\"\n (columnMoved)=\"OnColumnMoved($event)\">\n </ag-grid-angular>\n </div>\n\n <!-- Pagination (only shown when server-side paging is active) -->\n @if (TotalRowCount > 0) {\n <mj-pagination\n [TotalRowCount]=\"TotalRowCount\"\n [PageNumber]=\"PageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && RowCount === 0) {\n <mj-empty-state\n class=\"empty-state\"\n @fadeIn\n Icon=\"fa-solid fa-database\"\n Title=\"No results\"\n Message=\"Run the query to see results\" />\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"ShowExportDialog\"\n [config]=\"ExportDialogConfig\"\n (closed)=\"OnExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Row Detail Panel -->\n<mj-query-row-detail\n [RowData]=\"RowDetailData\"\n [Columns]=\"Columns\"\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowRowDetailPanel\"\n [RowIndex]=\"RowDetailIndex\"\n [TotalRows]=\"RowCount\"\n (Close)=\"CloseRowDetailPanel()\"\n (EntityLinkClick)=\"OnRowDetailEntityLinkClick($event)\"\n (NavigateRow)=\"NavigateRowDetail($event)\">\n</mj-query-row-detail>\n", styles: ["/* Query Data Grid Component Styles */\n\n:host {\n display: block;\n height: 100%;\n --grid-accent-color: var(--mj-brand-primary);\n --grid-selection-indicator: var(--mj-status-warning);\n --grid-selection-bg: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n --grid-sort-indicator-color: var(--mj-brand-primary);\n}\n\n.query-data-grid-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: 4px;\n overflow: hidden;\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.grid-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n min-height: 48px;\n flex-shrink: 0;\n}\n\n.toolbar-left,\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count,\n.selection-count {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.row-count i,\n.selection-count i {\n color: var(--mj-text-muted);\n}\n\n.selection-count {\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n border-radius: 4px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.clear-selection-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n margin-left: 4px;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 50%;\n transition: all 0.15s ease;\n}\n\n.clear-selection-btn:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 10%, transparent);\n color: var(--mj-text-primary);\n}\n\n/* Toolbar buttons - consistent styling */\n.toolbar-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-btn i {\n font-size: 14px;\n}\n\n/* Icon-only button */\n.toolbar-btn.icon-only {\n padding: 6px 8px;\n}\n\n.toolbar-btn.icon-only i {\n margin-right: 0;\n}\n\n/* ========================================\n Grid wrapper\n ======================================== */\n\n.grid-wrapper {\n flex: 1;\n min-height: 0;\n position: relative;\n transition: opacity 0.2s ease;\n}\n\n.grid-wrapper.loading {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.query-grid {\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Loading overlay\n ======================================== */\n\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 100;\n}\n\n/* ========================================\n Empty state\n ======================================== */\n\n/* Absolute-center the empty state over the grid; mj-empty-state owns its content. */\n.empty-state {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n/* ========================================\n Entity link cell\n ======================================== */\n\n::ng-deep .entity-link-cell {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n::ng-deep .entity-link {\n color: var(--grid-accent-color);\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n::ng-deep .entity-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n::ng-deep .entity-link-icon {\n font-size: 10px;\n color: var(--mj-text-disabled);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n::ng-deep .entity-link-cell:hover .entity-link-icon {\n opacity: 1;\n}\n\n/* ========================================\n AG Grid customizations\n ======================================== */\n\n/* ========================================\n Visual Config: Zebra Striping\n (copied from entity-data-grid pattern)\n ======================================== */\n\n/* Subtle contrast */\n.alternate-rows-subtle ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 1.5%, transparent);\n}\n\n.alternate-rows-subtle ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n/* Medium contrast (default) */\n.alternate-rows-medium ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 2.5%, transparent);\n}\n\n.alternate-rows-medium ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n/* Strong contrast */\n.alternate-rows-strong ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n.alternate-rows-strong ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n::ng-deep .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n::ng-deep .ag-header-cell:hover {\n background-color: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n/* Selected row styling */\n::ng-deep .ag-row-selected {\n background-color: var(--grid-selection-bg) !important;\n color: var(--mj-text-primary) !important;\n box-shadow: inset 4px 0 0 0 var(--grid-selection-indicator);\n}\n\n::ng-deep .ag-row-selected .ag-cell {\n color: var(--mj-text-primary) !important;\n}\n\n/* Row border */\n::ng-deep .ag-row {\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n/* Header alignment */\n::ng-deep .header-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n::ng-deep .header-center .ag-header-cell-label {\n justify-content: center;\n}\n\n/* Checkbox styling */\n::ng-deep .ag-checkbox-input-wrapper {\n border-radius: 4px;\n width: 18px;\n height: 18px;\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-accent-color);\n border-color: var(--grid-accent-color);\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n/* ========================================\n Sort Indicators - Arrow Only\n ======================================== */\n\n/* Sort icons - colored arrows only */\n:host ::ng-deep .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n:host ::ng-deep .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n:host ::ng-deep .ag-sort-ascending-icon .ag-icon,\n:host ::ng-deep .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n/* Sort order number (for multi-sort) */\n:host ::ng-deep .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-text-secondary) !important;\n}\n\n/* Hover state for sortable headers */\n:host ::ng-deep .ag-header-cell-sortable:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* ========================================\n Responsive adjustments\n ======================================== */\n\n@media (max-width: 768px) {\n .grid-toolbar {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .toolbar-left,\n .toolbar-right {\n flex-wrap: wrap;\n }\n\n /* Hide button text on mobile */\n .toolbar-btn .button-text {\n display: none;\n }\n}\n"] }]
1206
+ ], template: "<!-- Query Data Grid Component -->\n<div class=\"query-data-grid-container\" [ngClass]=\"GetContainerClasses()\" [style.height]=\"Height\">\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Row count -->\n @if (ShowRowCount) {\n <span class=\"row-count\">\n <i class=\"fa-solid fa-table-list\"></i>\n @if (TotalRowCount > RowCount) {\n {{ RowCount | number }} of {{ TotalRowCount | number }} {{ TotalRowCount === 1 ? 'row' : 'rows' }}\n } @else {\n {{ RowCount | number }} {{ RowCount === 1 ? 'row' : 'rows' }}\n }\n </span>\n }\n <!-- Selection count -->\n @if (ShowSelectionCount && SelectionCount > 0) {\n <span class=\"selection-count\">\n <i class=\"fa-solid fa-check-square\"></i>\n {{ SelectionCount }} selected\n <button class=\"clear-selection-btn\" (click)=\"ClearSelection()\" title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Refresh button -->\n @if (ShowRefresh) {\n <button\n (click)=\"Refresh()\"\n [disabled]=\"IsLoading\"\n title=\"Refresh data\"\n class=\"toolbar-btn icon-only\">\n <i class=\"fa-solid fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i>\n </button>\n }\n <!-- Export button -->\n @if (ShowExport) {\n <button\n [disabled]=\"RowCount === 0 || IsPreparingExport\"\n title=\"Export data\"\n class=\"toolbar-btn\"\n (click)=\"OpenExportDialog()\">\n <i class=\"fa-solid\" [class.fa-file-export]=\"!IsPreparingExport\" [class.fa-spinner]=\"IsPreparingExport\" [class.fa-spin]=\"IsPreparingExport\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Loading overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\" @fadeIn>\n <mj-loading text=\"Loading query results...\"></mj-loading>\n </div>\n }\n\n <!-- AG Grid -->\n <div class=\"grid-wrapper\" [class.loading]=\"IsLoading\">\n <ag-grid-angular\n class=\"query-grid\"\n [theme]=\"Theme\"\n [rowData]=\"Data\"\n [columnDefs]=\"ColumnDefs\"\n [defaultColDef]=\"DefaultColDef\"\n [gridOptions]=\"GridOptions\"\n [rowSelection]=\"GetRowSelectionConfig()\"\n [getRowId]=\"GetRowId\"\n (gridReady)=\"OnGridReady($event)\"\n (rowClicked)=\"OnRowClicked($event)\"\n (rowDoubleClicked)=\"OnRowDoubleClicked($event)\"\n (selectionChanged)=\"OnSelectionChanged($event)\"\n (sortChanged)=\"OnSortChanged($event)\"\n (columnResized)=\"OnColumnResized($event)\"\n (columnMoved)=\"OnColumnMoved($event)\">\n </ag-grid-angular>\n </div>\n\n <!-- Pagination (only shown when server-side paging is active) -->\n @if (TotalRowCount > 0) {\n <mj-pagination\n [TotalRowCount]=\"TotalRowCount\"\n [PageNumber]=\"PageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && RowCount === 0) {\n <mj-empty-state\n class=\"empty-state\"\n @fadeIn\n Icon=\"fa-solid fa-database\"\n Title=\"No results\"\n Message=\"Run the query to see results\" />\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"ShowExportDialog\"\n [config]=\"ExportDialogConfig\"\n (closed)=\"OnExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Row Detail Panel -->\n<mj-query-row-detail\n [RowData]=\"RowDetailData\"\n [Columns]=\"Columns\"\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowRowDetailPanel\"\n [RowIndex]=\"RowDetailIndex\"\n [TotalRows]=\"RowCount\"\n (Close)=\"CloseRowDetailPanel()\"\n (EntityLinkClick)=\"OnRowDetailEntityLinkClick($event)\"\n (NavigateRow)=\"NavigateRowDetail($event)\">\n</mj-query-row-detail>\n", styles: ["/* Query Data Grid Component Styles */\n\n:host {\n display: block;\n height: 100%;\n --grid-accent-color: var(--mj-brand-primary);\n --grid-selection-indicator: var(--mj-status-warning);\n --grid-selection-bg: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n --grid-sort-indicator-color: var(--mj-brand-primary);\n}\n\n.query-data-grid-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n position: relative;\n background: var(--mj-bg-surface);\n border-radius: 4px;\n overflow: hidden;\n}\n\n/* ========================================\n Toolbar\n ======================================== */\n\n.grid-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n min-height: 48px;\n flex-shrink: 0;\n}\n\n.toolbar-left,\n.toolbar-right {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.row-count,\n.selection-count {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.row-count i,\n.selection-count i {\n color: var(--mj-text-muted);\n}\n\n.selection-count {\n padding: 4px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-text-primary);\n border-radius: 4px;\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.clear-selection-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n padding: 0;\n margin-left: 4px;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n border-radius: 50%;\n transition: all 0.15s ease;\n}\n\n.clear-selection-btn:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 10%, transparent);\n color: var(--mj-text-primary);\n}\n\n/* Toolbar buttons - consistent styling */\n.toolbar-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background-color 0.2s, border-color 0.2s;\n}\n\n.toolbar-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.toolbar-btn i {\n font-size: 14px;\n}\n\n/* Icon-only button */\n.toolbar-btn.icon-only {\n padding: 6px 8px;\n}\n\n.toolbar-btn.icon-only i {\n margin-right: 0;\n}\n\n/* ========================================\n Grid wrapper\n ======================================== */\n\n.grid-wrapper {\n flex: 1;\n min-height: 0;\n position: relative;\n transition: opacity 0.2s ease;\n}\n\n.grid-wrapper.loading {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.query-grid {\n width: 100%;\n height: 100%;\n}\n\n/* ========================================\n Loading overlay\n ======================================== */\n\n.loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-overlay);\n z-index: 100;\n}\n\n/* ========================================\n Empty state\n ======================================== */\n\n/* Absolute-center the empty state over the grid; mj-empty-state owns its content. */\n.empty-state {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n/* ========================================\n Entity link cell\n ======================================== */\n\n::ng-deep .entity-link-cell {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n::ng-deep .entity-link {\n color: var(--grid-accent-color);\n text-decoration: none;\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n::ng-deep .entity-link:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n::ng-deep .entity-link-icon {\n font-size: 10px;\n color: var(--mj-text-disabled);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n::ng-deep .entity-link-cell:hover .entity-link-icon {\n opacity: 1;\n}\n\n/* ========================================\n AG Grid customizations\n ======================================== */\n\n/* ========================================\n Visual Config: Zebra Striping\n (copied from entity-data-grid pattern)\n ======================================== */\n\n/* Subtle contrast */\n.alternate-rows-subtle ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 1.5%, transparent);\n}\n\n.alternate-rows-subtle ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n/* Medium contrast (default) */\n.alternate-rows-medium ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 2.5%, transparent);\n}\n\n.alternate-rows-medium ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n/* Strong contrast */\n.alternate-rows-strong ::ng-deep .ag-row-odd {\n background-color: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n.alternate-rows-strong ::ng-deep .ag-row-odd:hover:not(.ag-row-selected) {\n background-color: var(--mj-bg-surface-hover);\n}\n\n::ng-deep .ag-header-cell {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-secondary);\n}\n\n::ng-deep .ag-header-cell:hover {\n background-color: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n/* Selected row styling */\n::ng-deep .ag-row-selected {\n background-color: var(--grid-selection-bg) !important;\n color: var(--mj-text-primary) !important;\n box-shadow: inset 4px 0 0 0 var(--grid-selection-indicator);\n}\n\n::ng-deep .ag-row-selected .ag-cell {\n color: var(--mj-text-primary) !important;\n}\n\n/* Row border */\n::ng-deep .ag-row {\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n/* Header alignment */\n::ng-deep .header-right .ag-header-cell-label {\n justify-content: flex-end;\n}\n\n::ng-deep .header-center .ag-header-cell-label {\n justify-content: center;\n}\n\n/* Checkbox styling */\n::ng-deep .ag-checkbox-input-wrapper {\n border-radius: 4px;\n width: 18px;\n height: 18px;\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked {\n background-color: var(--grid-accent-color);\n border-color: var(--grid-accent-color);\n}\n\n::ng-deep .ag-checkbox-input-wrapper.ag-checked::after {\n color: var(--mj-text-inverse);\n}\n\n/* ========================================\n Sort Indicators - Arrow Only\n ======================================== */\n\n/* Sort icons - colored arrows only */\n:host ::ng-deep .ag-sort-ascending-icon {\n color: var(--mj-brand-primary) !important;\n}\n\n:host ::ng-deep .ag-sort-descending-icon {\n color: var(--mj-status-error) !important;\n}\n\n:host ::ng-deep .ag-sort-ascending-icon .ag-icon,\n:host ::ng-deep .ag-sort-descending-icon .ag-icon {\n font-size: 14px !important;\n}\n\n/* Sort order number (for multi-sort) */\n:host ::ng-deep .ag-sort-order {\n margin-left: 4px;\n font-size: 11px !important;\n font-weight: 700 !important;\n color: var(--mj-text-secondary) !important;\n}\n\n/* Hover state for sortable headers */\n:host ::ng-deep .ag-header-cell-sortable:hover {\n background: color-mix(in srgb, var(--mj-text-primary) 4%, transparent);\n}\n\n/* ========================================\n Scrollbar Styling\n ======================================== */\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 4px;\n}\n\n::ng-deep .ag-body-viewport::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* ========================================\n Responsive adjustments\n ======================================== */\n\n@media (max-width: 768px) {\n .grid-toolbar {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .toolbar-left,\n .toolbar-right {\n flex-wrap: wrap;\n }\n\n /* Hide button text on mobile */\n .toolbar-btn .button-text {\n display: none;\n }\n}\n"] }]
1172
1207
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.ExportService }], { QueryInfo: [{
1173
1208
  type: Input
1174
1209
  }], ColumnConfigs: [{
@@ -1221,6 +1256,8 @@ export class QueryDataGridComponent {
1221
1256
  type: Input
1222
1257
  }], PageSize: [{
1223
1258
  type: Input
1259
+ }], ExportDataProvider: [{
1260
+ type: Input
1224
1261
  }], PageChange: [{
1225
1262
  type: Output
1226
1263
  }] }); })();
@@ -1 +1 @@
1
- {"version":3,"file":"query-data-grid.component.js","sourceRoot":"","sources":["../../../src/lib/query-data-grid/query-data-grid.component.ts","../../../src/lib/query-data-grid/query-data-grid.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ElementRef,\n ViewChild\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { MJQueryEntityExtended } from '@memberjunction/core-entities';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport {\n ColDef,\n GridReadyEvent,\n RowClickedEvent,\n GridApi,\n RowDoubleClickedEvent,\n ModuleRegistry,\n AllCommunityModule,\n RowSelectionOptions,\n GetRowIdParams,\n themeAlpine,\n SortChangedEvent as AgSortChangedEvent,\n type Theme,\n ColumnResizedEvent,\n ColumnMovedEvent,\n SelectionChangedEvent,\n ICellRendererParams,\n GridOptions\n} from 'ag-grid-community';\nimport {\n ExportService,\n ExportDialogConfig,\n ExportDialogResult\n} from '@memberjunction/ng-export-service';\nimport {\n ExportOptions,\n ExportResult,\n ExportColumn,\n ExportData\n} from '@memberjunction/export-engine';\nimport {\n QueryGridSelectionMode,\n QueryGridColumnConfig,\n QueryGridSortState,\n QueryGridState,\n QueryGridVisualConfig,\n DEFAULT_QUERY_VISUAL_CONFIG,\n QueryRowClickEvent,\n QueryEntityLinkClickEvent,\n QueryGridStateChangedEvent,\n QuerySelectionChangedEvent,\n QueryExportOptions,\n buildColumnsFromQueryFields,\n buildColumnsFromData,\n getQueryGridStateKey\n} from './models/query-grid-types';\nimport { RowDetailEntityLinkEvent } from '../query-row-detail/query-row-detail.component';\n\n// Register AG Grid modules\nModuleRegistry.registerModules([AllCommunityModule]);\n\n/**\n * A data grid component for displaying query results with full interactivity.\n * Features:\n * - Client-side sorting with multi-column support\n * - Column resizing, reordering, and visibility toggle\n * - Entity linking for columns with SourceEntityID\n * - State persistence to User Settings\n * - Export to Excel/CSV\n * - Row selection (single, multiple, checkbox modes)\n *\n * @example\n * ```html\n * <mj-query-data-grid\n * [queryInfo]=\"query\"\n * [data]=\"queryResults\"\n * [selectionMode]=\"'multiple'\"\n * (entityLinkClick)=\"onEntityLinkClick($event)\">\n * </mj-query-data-grid>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-query-data-grid',\n templateUrl: './query-data-grid.component.html',\n styleUrls: ['./query-data-grid.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('fadeIn', [\n transition(':enter', [\n style({ opacity: 0, transform: 'translateY(-8px)' }),\n animate('150ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))\n ]),\n transition(':leave', [\n animate('100ms ease-in', style({ opacity: 0, transform: 'translateY(-8px)' }))\n ])\n ])\n ]\n})\nexport class QueryDataGridComponent implements OnInit, OnDestroy {\n // ========================================\n // Inputs\n // ========================================\n\n private _queryInfo: MJQueryEntityExtended | null = null;\n /**\n * The QueryInfo metadata for the query being displayed.\n * Used to derive column configurations and entity linking.\n */\n @Input()\n set QueryInfo(value: MJQueryEntityExtended | null) {\n const previous = this._queryInfo;\n // Flush state for the previous query before switching\n if (previous && value !== previous) {\n this.FlushState();\n }\n this._queryInfo = value;\n if (value && value !== previous) {\n this.onQueryInfoChanged();\n }\n }\n get QueryInfo(): MJQueryEntityExtended | null {\n return this._queryInfo;\n }\n\n private _columnConfigs: QueryGridColumnConfig[] | null = null;\n /**\n * Optional pre-built column configurations for ad-hoc queries without saved metadata.\n * When provided, overrides both QueryInfo-derived columns and auto-inferred columns.\n * Enables entity linking without requiring a saved Query or QueryInfo object.\n *\n * Set this BEFORE setting Data to ensure columns are configured before the grid renders.\n */\n @Input()\n set ColumnConfigs(value: QueryGridColumnConfig[] | null) {\n this._columnConfigs = value;\n if (value && value.length > 0) {\n this.Columns = value;\n this.buildColumnDefs();\n this.cdr.markForCheck();\n }\n }\n get ColumnConfigs(): QueryGridColumnConfig[] | null {\n return this._columnConfigs;\n }\n\n private _data: Record<string, unknown>[] = [];\n\n /**\n * Per-row synthetic identity for rows that have no natural key column, so the\n * `getRowId` fallback can never return duplicate ids (ag-Grid silently merges\n * rows that share an id). Keyed by the row object reference; entries are added\n * as Data is assigned. A WeakMap so it never retains rows past their lifetime.\n */\n private _syntheticRowIds = new WeakMap<object, string>();\n private _syntheticRowIdSeq = 0;\n\n /**\n * The query result data to display in the grid.\n */\n @Input()\n set Data(value: Record<string, unknown>[]) {\n this._data = value || [];\n\n // Assign a stable synthetic id to each row up front, so the getRowId\n // fallback (used only when a row has no natural key column) is\n // collision-proof — rows with identical column values must NOT be merged.\n for (const row of this._data) {\n if (row && !this._syntheticRowIds.has(row)) {\n this._syntheticRowIds.set(row, `mjrow_${this._syntheticRowIdSeq++}`);\n }\n }\n\n // If we have data but no columns from metadata or explicit configs, build from data\n if (this._data.length > 0 && this.Columns.length === 0 && !this._columnConfigs) {\n this.Columns = buildColumnsFromData(this._data);\n this.buildColumnDefs();\n }\n\n if (this.GridApi) {\n this.GridApi.setGridOption('rowData', this._data);\n }\n this.cdr.markForCheck();\n }\n get Data(): Record<string, unknown>[] {\n return this._data;\n }\n\n /**\n * Selection mode for the grid\n */\n @Input() SelectionMode: QueryGridSelectionMode = 'multiple';\n\n /**\n * Whether to show the toolbar\n */\n @Input() ShowToolbar: boolean = true;\n\n /**\n * Whether to show row count in toolbar\n */\n @Input() ShowRowCount: boolean = true;\n\n /**\n * Whether to show selection count in toolbar\n */\n @Input() ShowSelectionCount: boolean = true;\n\n /**\n * Whether to show export button\n */\n @Input() ShowExport: boolean = true;\n\n /**\n * Whether to show refresh button\n */\n @Input() ShowRefresh: boolean = true;\n\n /**\n * Whether to allow sorting\n */\n @Input() AllowSorting: boolean = true;\n\n /**\n * Whether to allow column resizing\n */\n @Input() AllowColumnResize: boolean = true;\n\n /**\n * Whether to allow column reordering\n */\n @Input() AllowColumnReorder: boolean = true;\n\n /**\n * Visual configuration\n */\n @Input() VisualConfig: QueryGridVisualConfig = {};\n\n /**\n * External loading state - when true, shows loading overlay\n */\n @Input() IsLoading: boolean = false;\n\n /**\n * Height of the grid container\n */\n @Input() Height: string = '100%';\n\n /**\n * Initial grid state (for restoring from persistence)\n */\n @Input() InitialGridState: QueryGridState | null = null;\n\n /**\n * Whether to automatically persist grid state (column widths, order, sort) to User Settings\n */\n @Input() PersistState: boolean = true;\n\n // ========================================\n // Outputs\n // ========================================\n\n /**\n * Fired when a row is clicked\n */\n @Output() RowClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when a row is double-clicked\n */\n @Output() RowDoubleClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when an entity link is clicked\n */\n @Output() EntityLinkClick = new EventEmitter<QueryEntityLinkClickEvent>();\n\n /**\n * Fired when selection changes\n */\n @Output() SelectionChange = new EventEmitter<QuerySelectionChangedEvent>();\n\n /**\n * Fired when grid state changes (for persistence)\n */\n @Output() GridStateChange = new EventEmitter<QueryGridStateChangedEvent>();\n\n /**\n * Fired when refresh is requested\n */\n @Output() RefreshRequest = new EventEmitter<void>();\n\n /**\n * Total row count for server-side paging (from RunQueryResult.TotalRowCount).\n * When > 0 and TotalPages > 1, the data pager is displayed below the grid.\n */\n @Input() TotalRowCount: number = 0;\n\n /** Current page number (1-based) for server-side paging */\n @Input() PageNumber: number = 1;\n\n /** Page size for server-side paging */\n @Input() PageSize: number = 100;\n\n /** Fired when the user navigates to a different page */\n @Output() PageChange = new EventEmitter<PageChangeEvent>();\n\n // ========================================\n // Internal State\n // ========================================\n\n public GridApi: GridApi | null = null;\n public ColumnDefs: ColDef[] = [];\n public Columns: QueryGridColumnConfig[] = [];\n public SortState: QueryGridSortState[] = [];\n public SelectedRows: Record<string, unknown>[] = [];\n public Theme: Theme = themeAlpine.withParams({\n backgroundColor: 'var(--mj-bg-surface)',\n foregroundColor: 'var(--mj-text-primary)',\n textColor: 'var(--mj-text-primary)',\n borderColor: 'var(--mj-border-default)',\n chromeBackgroundColor: 'var(--mj-bg-surface-card)',\n headerBackgroundColor: 'var(--mj-bg-surface-card)',\n headerTextColor: 'var(--mj-text-secondary)',\n cellTextColor: 'var(--mj-text-primary)',\n subtleTextColor: 'var(--mj-text-muted)',\n dataBackgroundColor: 'var(--mj-bg-surface)',\n oddRowBackgroundColor: 'var(--mj-bg-surface-card)',\n rowHoverColor: 'var(--mj-bg-surface-hover, color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface)))',\n selectedRowBackgroundColor: 'color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface))',\n accentColor: 'var(--mj-brand-primary)',\n borderRadius: 'var(--mj-radius-sm)',\n browserColorScheme: 'inherit',\n });\n\n private destroy$ = new Subject<void>();\n private stateChangeSubject = new Subject<QueryGridStateChangedEvent>();\n private statePersistSubject = new Subject<QueryGridState>();\n private _mergedVisualConfig: Required<QueryGridVisualConfig> = DEFAULT_QUERY_VISUAL_CONFIG;\n private _pendingState: QueryGridState | null = null;\n\n // Grid options\n public GridOptions: GridOptions = {\n animateRows: true,\n rowHeight: 36,\n headerHeight: 40,\n suppressCellFocus: false,\n enableCellTextSelection: true,\n ensureDomOrder: true,\n suppressNoRowsOverlay: true\n };\n\n /** Default column settings - enables sorting, resizing */\n public DefaultColDef: ColDef = {\n sortable: true,\n resizable: true,\n minWidth: 50\n };\n\n constructor(\n private cdr: ChangeDetectorRef,\n private elementRef: ElementRef,\n private exportService: ExportService\n ) {\n // Debounce state changes for persistence\n this.stateChangeSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(event => {\n this.GridStateChange.emit(event);\n // Also persist to User Settings if enabled\n if (this.PersistState && this._queryInfo) {\n this.statePersistSubject.next(event.state);\n }\n });\n\n // Debounce state persistence to User Settings\n this.statePersistSubject.pipe(\n debounceTime(1000),\n takeUntil(this.destroy$)\n ).subscribe(state => {\n this.persistGridState(state);\n });\n }\n\n ngOnInit(): void {\n this._mergedVisualConfig = { ...DEFAULT_QUERY_VISUAL_CONFIG, ...this.VisualConfig };\n this.applyVisualConfig();\n }\n\n ngOnDestroy(): void {\n // Flush any pending state changes before destroy\n this.FlushState();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Grid Setup\n // ========================================\n\n public OnGridReady(event: GridReadyEvent): void {\n this.GridApi = event.api;\n\n // Apply initial data if available\n if (this._data.length > 0) {\n this.GridApi.setGridOption('rowData', this._data);\n }\n\n // Apply initial state if provided via Input\n if (this.InitialGridState) {\n this.applyFullGridState(this.InitialGridState);\n }\n // Otherwise apply pending state from persistence\n else if (this._pendingState) {\n this.applyFullGridState(this._pendingState);\n this._pendingState = null;\n }\n // Only auto-size if no persisted state was applied\n else {\n setTimeout(() => {\n if (this.GridApi) {\n this.GridApi.autoSizeAllColumns();\n }\n }, 100);\n }\n }\n\n private onQueryInfoChanged(): void {\n if (!this._queryInfo) {\n this.Columns = [];\n this.ColumnDefs = [];\n return;\n }\n\n // Build columns from query fields\n this.Columns = buildColumnsFromQueryFields(this._queryInfo.QueryFields);\n\n // Apply initial state if provided via prop (takes precedence)\n if (this.InitialGridState) {\n this.applyColumnStateFromGridState(this.InitialGridState);\n } else {\n // Otherwise try to load from User Settings\n this.loadPersistedState();\n }\n\n // Build AG Grid column definitions\n this.buildColumnDefs();\n\n // If grid is already initialized and we have pending state, apply it now\n if (this.GridApi && this._pendingState) {\n this.applyFullGridState(this._pendingState);\n this._pendingState = null;\n }\n\n this.cdr.markForCheck();\n }\n\n private applyColumnStateFromGridState(state: QueryGridState): void {\n if (!state.columns) return;\n\n for (const colState of state.columns) {\n const column = this.Columns.find(c => c.field === colState.field);\n if (column) {\n if (colState.width !== undefined) column.width = colState.width;\n column.visible = colState.visible;\n column.order = colState.order;\n column.pinned = colState.pinned || null;\n }\n }\n\n // Apply sort state\n if (state.sort) {\n this.SortState = [...state.sort];\n }\n\n // Re-sort columns by order\n this.Columns.sort((a, b) => a.order - b.order);\n }\n\n private buildColumnDefs(): void {\n const visibleColumns = this.Columns.filter(c => c.visible);\n\n // Add checkbox column if needed\n const defs: ColDef[] = [];\n\n if (this.SelectionMode === 'checkbox') {\n defs.push({\n headerName: '',\n field: '__checkbox',\n width: 50,\n minWidth: 50,\n maxWidth: 50,\n checkboxSelection: true,\n headerCheckboxSelection: true,\n pinned: 'left',\n suppressSizeToFit: true,\n sortable: false,\n filter: false,\n resizable: false\n });\n }\n\n // Add data columns\n for (const col of visibleColumns) {\n const colDef: ColDef = {\n field: col.field,\n headerName: col.title,\n headerTooltip: col.description || undefined,\n width: col.width,\n minWidth: col.minWidth,\n maxWidth: col.maxWidth,\n sortable: this.AllowSorting && col.sortable,\n resizable: this.AllowColumnResize && col.resizable,\n pinned: col.pinned || undefined,\n flex: col.flex,\n cellStyle: this.getCellStyle(col),\n headerClass: this.getHeaderClass(col),\n comparator: (a, b) => this.defaultComparator(a, b, col)\n };\n\n // Add entity link cell renderer if applicable\n if (col.isEntityLink && col.targetEntityName) {\n colDef.cellRenderer = (params: ICellRendererParams) =>\n this.renderEntityLinkCell(params, col);\n // Add custom header with entity icon and column name\n colDef.headerComponentParams = {\n template: this.getEntityLinkHeaderTemplate(col)\n };\n } else {\n // Apply type-specific formatting\n colDef.valueFormatter = (params) => this.formatCellValue(params.value, col);\n }\n\n defs.push(colDef);\n }\n\n this.ColumnDefs = defs;\n\n // Apply to grid if ready\n if (this.GridApi) {\n this.GridApi.setGridOption('columnDefs', this.ColumnDefs);\n }\n }\n\n // ========================================\n // Cell Rendering\n // ========================================\n\n private getCellStyle(col: QueryGridColumnConfig): Record<string, string> {\n const style: Record<string, string> = {};\n\n if (col.align === 'right') {\n style['text-align'] = 'right';\n style['justify-content'] = 'flex-end';\n } else if (col.align === 'center') {\n style['text-align'] = 'center';\n style['justify-content'] = 'center';\n }\n\n return style;\n }\n\n private getHeaderClass(col: QueryGridColumnConfig): string {\n const classes: string[] = [];\n\n if (col.align === 'right') {\n classes.push('header-right');\n } else if (col.align === 'center') {\n classes.push('header-center');\n }\n\n return classes.join(' ');\n }\n\n private formatCellValue(value: unknown, col: QueryGridColumnConfig): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n const baseType = col.sqlBaseType.toLowerCase();\n\n // Boolean formatting\n if (baseType === 'bit') {\n if (this._mergedVisualConfig.booleanIcons) {\n return value ? '✓' : '✗';\n }\n return value ? 'Yes' : 'No';\n }\n\n // Date formatting\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n const date = new Date(value as string);\n if (isNaN(date.getTime())) return String(value);\n\n if (this._mergedVisualConfig.friendlyDates) {\n if (baseType === 'date') {\n return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });\n }\n return date.toLocaleString('en-US', {\n year: 'numeric', month: 'short', day: 'numeric',\n hour: 'numeric', minute: '2-digit'\n });\n }\n return date.toISOString();\n }\n\n // Number formatting - check if value is actually numeric first\n if (['int', 'bigint', 'smallint', 'tinyint'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return num.toLocaleString();\n }\n\n if (['decimal', 'numeric', 'float', 'real'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 });\n }\n\n if (['money', 'smallmoney'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(num);\n }\n\n return String(value);\n }\n\n private renderEntityLinkCell(params: ICellRendererParams, col: QueryGridColumnConfig): HTMLElement {\n const container = document.createElement('div');\n container.className = 'entity-link-cell';\n\n if (params.value === null || params.value === undefined) {\n return container;\n }\n\n const link = document.createElement('a');\n link.href = 'javascript:void(0)';\n link.className = 'entity-link';\n link.textContent = String(params.value);\n link.title = `Open ${col.targetEntityName} record`;\n\n link.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.EntityLinkClick.emit({\n entityName: col.targetEntityName!,\n recordId: String(params.value),\n column: col,\n rowData: params.data\n });\n });\n\n container.appendChild(link);\n\n const icon = document.createElement('i');\n icon.className = 'fa-solid fa-arrow-up-right-from-square entity-link-icon';\n container.appendChild(icon);\n\n return container;\n }\n\n /**\n * Generates header template HTML with entity icon from metadata\n * Shows: [Entity Icon] Column Name [Sort Icons]\n */\n private getEntityLinkHeaderTemplate(col: QueryGridColumnConfig): string {\n // Use the target entity's icon from metadata, fallback to generic icons\n const entityIcon = col.targetEntityIcon || (col.isPrimaryKey ? 'fa-solid fa-key' : 'fa-solid fa-link');\n const tooltip = col.isPrimaryKey\n ? `Primary key - links to ${col.targetEntityName}`\n : `Foreign key - links to ${col.targetEntityName}`;\n // Escape the title for safe HTML insertion\n const escapedTitle = col.title.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n return `\n <div class=\"ag-cell-label-container\" role=\"presentation\">\n <span ref=\"eMenu\" class=\"ag-header-icon ag-header-cell-menu-button\" aria-hidden=\"true\"></span>\n <div ref=\"eLabel\" class=\"ag-header-cell-label\" role=\"presentation\">\n <i class=\"${entityIcon} entity-header-icon\" style=\"color: #5c6bc0; margin-right: 6px; font-size: 12px;\" title=\"${tooltip}\"></i>\n <span ref=\"eText\" class=\"ag-header-cell-text\">${escapedTitle}</span>\n <span ref=\"eFilter\" class=\"ag-header-icon ag-header-label-icon ag-filter-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortOrder\" class=\"ag-header-icon ag-header-label-icon ag-sort-order\" aria-hidden=\"true\"></span>\n <span ref=\"eSortAsc\" class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortDesc\" class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortNone\" class=\"ag-header-icon ag-header-label-icon ag-sort-none-icon\" aria-hidden=\"true\"></span>\n </div>\n </div>\n `;\n }\n\n private defaultComparator(a: unknown, b: unknown, col: QueryGridColumnConfig): number {\n if (a === null || a === undefined) return 1;\n if (b === null || b === undefined) return -1;\n\n const baseType = col.sqlBaseType.toLowerCase();\n\n // Numeric comparison\n if (['int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney'].includes(baseType)) {\n return Number(a) - Number(b);\n }\n\n // Date comparison\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n return new Date(a as string).getTime() - new Date(b as string).getTime();\n }\n\n // String comparison (case-insensitive)\n return String(a).toLowerCase().localeCompare(String(b).toLowerCase());\n }\n\n // ========================================\n // Event Handlers\n // ========================================\n\n public OnRowClicked(event: RowClickedEvent): void {\n const clickEvent: QueryRowClickEvent = {\n rowData: event.data,\n rowIndex: event.rowIndex!,\n mouseEvent: event.event as MouseEvent\n };\n this.RowClick.emit(clickEvent);\n\n // Open row detail panel on single click\n this.OpenRowDetailPanel(event.data, event.rowIndex!);\n }\n\n public OnRowDoubleClicked(event: RowDoubleClickedEvent): void {\n const clickEvent: QueryRowClickEvent = {\n rowData: event.data,\n rowIndex: event.rowIndex!,\n mouseEvent: event.event as MouseEvent\n };\n this.RowDoubleClick.emit(clickEvent);\n }\n\n public OnSelectionChanged(event: SelectionChangedEvent): void {\n if (!this.GridApi) return;\n\n this.SelectedRows = this.GridApi.getSelectedRows();\n const selectedIndices: number[] = [];\n\n this.GridApi.forEachNode((node, index) => {\n if (node.isSelected()) {\n selectedIndices.push(index);\n }\n });\n\n this.SelectionChange.emit({\n selectedIndices,\n selectedRows: this.SelectedRows\n });\n\n this.cdr.markForCheck();\n }\n\n public OnSortChanged(event: AgSortChangedEvent): void {\n if (!this.GridApi) return;\n\n const columnState = this.GridApi.getColumnState();\n const newSortState: QueryGridSortState[] = [];\n\n columnState\n .filter(cs => cs.sort)\n .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))\n .forEach((cs, index) => {\n newSortState.push({\n field: cs.colId,\n direction: cs.sort as 'asc' | 'desc',\n index\n });\n });\n\n this.SortState = newSortState;\n this.emitStateChange('sort');\n }\n\n public OnColumnResized(event: ColumnResizedEvent): void {\n if (!event.finished || !event.column) return;\n\n const field = event.column.getColId();\n const column = this.Columns.find(c => c.field === field);\n if (column) {\n column.width = event.column.getActualWidth();\n this.emitStateChange('column-resize');\n }\n }\n\n public OnColumnMoved(event: ColumnMovedEvent): void {\n if (!this.GridApi || !event.finished) return;\n\n // Update column order from grid state\n const columnState = this.GridApi.getColumnState();\n columnState.forEach((cs, index) => {\n const column = this.Columns.find(c => c.field === cs.colId);\n if (column) {\n column.order = index;\n }\n });\n\n this.emitStateChange('column-move');\n }\n\n // ========================================\n // State Management\n // ========================================\n\n private emitStateChange(changeType: 'column-resize' | 'column-move' | 'column-visibility' | 'sort'): void {\n const state = this.GetGridState();\n this.stateChangeSubject.next({ state, changeType });\n }\n\n public GetGridState(): QueryGridState {\n return {\n columns: this.Columns.map(c => ({\n field: c.field,\n width: c.width,\n visible: c.visible,\n order: c.order,\n pinned: c.pinned\n })),\n sort: this.SortState\n };\n }\n\n public ApplyGridState(state: QueryGridState): void {\n this.applyColumnStateFromGridState(state);\n this.buildColumnDefs();\n\n // Apply sort state to grid\n if (this.GridApi && state.sort.length > 0) {\n const columnState = state.sort.map(s => ({\n colId: s.field,\n sort: s.direction,\n sortIndex: s.index\n }));\n this.GridApi.applyColumnState({ state: columnState });\n }\n }\n\n /**\n * Loads persisted grid state from User Settings\n */\n private loadPersistedState(): void {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n try {\n const settingKey = getQueryGridStateKey(this._queryInfo.ID);\n const savedState = UserInfoEngine.Instance.GetSetting(settingKey);\n\n if (savedState) {\n const state = JSON.parse(savedState) as QueryGridState;\n\n // Apply column state immediately (affects buildColumnDefs)\n this.applyColumnStateFromGridState(state);\n\n // Store for applying via Grid API when ready\n this._pendingState = state;\n\n // If grid is already ready, apply full state now\n if (this.GridApi) {\n this.applyFullGridState(state);\n this._pendingState = null;\n }\n }\n } catch (error) {\n console.error('[query-data-grid] Failed to load persisted state:', error);\n }\n }\n\n /**\n * Applies the full grid state (column widths, order, and sort) via the Grid API.\n * This is called after grid is ready to ensure all state is applied correctly.\n */\n private applyFullGridState(state: QueryGridState): void {\n if (!this.GridApi) {\n return;\n }\n\n // Build column state array that includes widths and sort\n const columnState: Array<{\n colId: string;\n width?: number;\n sort?: 'asc' | 'desc' | null;\n sortIndex?: number | null;\n }> = [];\n\n // First, add column widths from saved state\n if (state.columns) {\n for (const col of state.columns) {\n const stateItem: {\n colId: string;\n width?: number;\n sort?: 'asc' | 'desc' | null;\n sortIndex?: number | null;\n } = { colId: col.field };\n\n if (col.width !== undefined) {\n stateItem.width = col.width;\n }\n\n // Check if this column has sort state\n const sortInfo = state.sort?.find(s => s.field === col.field);\n if (sortInfo) {\n stateItem.sort = sortInfo.direction;\n stateItem.sortIndex = sortInfo.index;\n }\n\n columnState.push(stateItem);\n }\n }\n\n // Apply all column state at once\n if (columnState.length > 0) {\n this.GridApi.applyColumnState({\n state: columnState,\n applyOrder: true // Apply column order as well\n });\n }\n }\n\n /**\n * Persists grid state to User Settings\n */\n private async persistGridState(state: QueryGridState): Promise<void> {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n try {\n const settingKey = getQueryGridStateKey(this._queryInfo.ID);\n await UserInfoEngine.Instance.SetSetting(settingKey, JSON.stringify(state));\n } catch (error) {\n console.error('[query-data-grid] Failed to persist grid state:', error);\n }\n }\n\n /**\n * Flushes any pending state changes immediately.\n * Call this before destroying the component or switching queries\n * to ensure all state changes are persisted.\n */\n public FlushState(): void {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n // Get current state and persist immediately\n const state = this.GetGridState();\n this.persistGridState(state);\n }\n\n // ========================================\n // Visual Config\n // ========================================\n\n private applyVisualConfig(): void {\n const el = this.elementRef.nativeElement;\n\n // Apply CSS variables\n if (this._mergedVisualConfig.accentColor) {\n el.style.setProperty('--grid-accent-color', this._mergedVisualConfig.accentColor);\n }\n if (this._mergedVisualConfig.selectionIndicatorColor) {\n el.style.setProperty('--grid-selection-indicator', this._mergedVisualConfig.selectionIndicatorColor);\n }\n if (this._mergedVisualConfig.selectionBackground) {\n el.style.setProperty('--grid-selection-bg', this._mergedVisualConfig.selectionBackground);\n }\n }\n\n /**\n * Returns CSS classes for the container based on visual config\n */\n public GetContainerClasses(): Record<string, boolean> {\n const contrast = this._mergedVisualConfig.alternateRowContrast || 'medium';\n return {\n [`alternate-rows-${contrast}`]: true\n };\n }\n\n // ========================================\n // Export Dialog\n // ========================================\n\n public ShowExportDialog: boolean = false;\n public ExportDialogConfig: ExportDialogConfig | null = null;\n\n // ========================================\n // Row Detail Panel State\n // ========================================\n\n public ShowRowDetailPanel: boolean = false;\n public RowDetailData: Record<string, unknown> | null = null;\n public RowDetailIndex: number = 0;\n\n // ========================================\n // Toolbar Actions\n // ========================================\n\n public Refresh(): void {\n this.RefreshRequest.emit();\n }\n\n /**\n * Opens the export dialog with current grid data\n */\n public OpenExportDialog(): void {\n if (!this._data.length) return;\n\n const data = this.getExportData();\n const columns = this.getExportColumns();\n const fileName = this._queryInfo?.Name || 'query-export';\n\n this.ExportDialogConfig = {\n data,\n columns,\n defaultFileName: fileName,\n availableFormats: ['excel', 'csv', 'json'],\n defaultFormat: 'excel',\n showSamplingOptions: true,\n defaultSamplingMode: 'all',\n dialogTitle: `Export ${this._queryInfo?.Name || 'Query Results'}`\n };\n this.ShowExportDialog = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle export dialog close\n */\n public OnExportDialogClosed(result: ExportDialogResult): void {\n this.ShowExportDialog = false;\n this.ExportDialogConfig = null;\n this.cdr.detectChanges();\n }\n\n /**\n * Export grid data directly without showing dialog\n */\n public async Export(options?: Partial<ExportOptions>, download: boolean = true): Promise<ExportResult> {\n const data = this.getExportData();\n const columns = this.getExportColumns();\n const fileName = options?.fileName || this._queryInfo?.Name || 'query-export';\n\n const exportOptions: Partial<ExportOptions> = {\n format: 'excel',\n fileName,\n columns,\n includeHeaders: true,\n ...options\n };\n\n const result = await this.exportService.export(data, exportOptions);\n\n if (result.success && download) {\n this.exportService.downloadResult(result);\n }\n\n return result;\n }\n\n /**\n * Get the current grid data formatted for export\n */\n private getExportData(): ExportData {\n // Use selected rows if any, otherwise all data\n const rows = this.SelectedRows.length > 0 ? this.SelectedRows : this._data;\n return rows as ExportData;\n }\n\n /**\n * Get column definitions for export based on current grid columns\n */\n private getExportColumns(): ExportColumn[] {\n return this.Columns\n .filter(c => c.visible)\n .map(c => ({\n name: c.field,\n displayName: c.title,\n type: this.mapSqlTypeToExportType(c.sqlBaseType)\n }));\n }\n\n private mapSqlTypeToExportType(sqlType: string): 'string' | 'number' | 'boolean' | 'date' {\n const baseType = sqlType.toLowerCase();\n if (['int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney'].includes(baseType)) {\n return 'number';\n }\n if (['bit'].includes(baseType)) {\n return 'boolean';\n }\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n return 'date';\n }\n return 'string';\n }\n\n public ClearSelection(): void {\n if (this.GridApi) {\n this.GridApi.deselectAll();\n }\n }\n\n // ========================================\n // Public API\n // ========================================\n\n public GetSelectedRows(): Record<string, unknown>[] {\n return this.SelectedRows;\n }\n\n public get RowCount(): number {\n return this._data.length;\n }\n\n public get SelectionCount(): number {\n return this.SelectedRows.length;\n }\n\n // ========================================\n // AG Grid Configuration\n // ========================================\n\n public GetRowSelectionConfig(): RowSelectionOptions | undefined {\n if (this.SelectionMode === 'none') {\n return undefined;\n }\n\n if (this.SelectionMode === 'single') {\n return {\n mode: 'singleRow',\n enableClickSelection: true\n };\n }\n\n // Multi-row selection (both 'multiple' and 'checkbox' modes)\n return {\n mode: 'multiRow',\n enableClickSelection: true,\n checkboxes: this.SelectionMode === 'checkbox',\n enableSelectionWithoutKeys: this.SelectionMode === 'multiple'\n };\n }\n\n public GetRowId = (params: GetRowIdParams): string => {\n const data = params.data as Record<string, unknown>;\n if (!data) return `mjrow_${this._syntheticRowIdSeq++}`;\n\n // Prefer a natural unique key when the result exposes one — this keeps row\n // identity (and selection) stable across data refreshes.\n const idFields = ['ID', 'Id', 'id', 'RowNumber', 'RowNum', '__row_index'];\n for (const field of idFields) {\n if (data[field] !== undefined && data[field] !== null) {\n return String(data[field]);\n }\n }\n\n // No natural key — use the per-row synthetic id assigned when Data was set.\n // The previous fallback hashed only the first 3 columns, so any rows that\n // matched on those columns collided to the same id and ag-Grid dropped all\n // but one (silently collapsing aggregate/GROUP BY results, or any query\n // without an ID column). A per-row synthetic id can never collide.\n // Trade-off: the id is per-object (not value-derived), so an id-less row\n // loses its selection across a data refresh — acceptable for query results,\n // where NOT dropping rows matters far more than preserving a selection.\n let synthetic = this._syntheticRowIds.get(data);\n if (!synthetic) {\n synthetic = `mjrow_${this._syntheticRowIdSeq++}`;\n this._syntheticRowIds.set(data, synthetic);\n }\n return synthetic;\n };\n\n // ========================================\n // Row Detail Panel\n // ========================================\n\n /**\n * Opens the row detail panel with the given row data\n */\n public OpenRowDetailPanel(rowData: Record<string, unknown>, rowIndex: number): void {\n this.RowDetailData = rowData;\n this.RowDetailIndex = rowIndex;\n this.ShowRowDetailPanel = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Closes the row detail panel\n */\n public CloseRowDetailPanel(): void {\n this.ShowRowDetailPanel = false;\n this.RowDetailData = null;\n this.cdr.markForCheck();\n }\n\n /**\n * Navigate to the previous row in the detail panel\n */\n public NavigateRowDetail(direction: 'prev' | 'next'): void {\n if (!this._data.length) return;\n\n if (direction === 'prev' && this.RowDetailIndex > 0) {\n this.RowDetailIndex--;\n this.RowDetailData = this._data[this.RowDetailIndex];\n } else if (direction === 'next' && this.RowDetailIndex < this._data.length - 1) {\n this.RowDetailIndex++;\n this.RowDetailData = this._data[this.RowDetailIndex];\n }\n\n // Select the row in the grid\n if (this.GridApi) {\n this.GridApi.deselectAll();\n const node = this.GridApi.getRowNode(String(this.RowDetailIndex));\n if (node) {\n node.setSelected(true);\n this.GridApi.ensureNodeVisible(node);\n }\n }\n\n this.cdr.markForCheck();\n }\n\n /**\n * Handle entity link click from the row detail panel\n */\n public OnRowDetailEntityLinkClick(event: RowDetailEntityLinkEvent): void {\n // Find the column config to include in the entity link event\n const column = this.Columns.find(c => c.field === event.fieldName);\n\n this.EntityLinkClick.emit({\n entityName: event.entityName,\n recordId: event.recordId,\n column: column || null,\n rowData: this.RowDetailData || {}\n });\n }\n}\n","<!-- Query Data Grid Component -->\n<div class=\"query-data-grid-container\" [ngClass]=\"GetContainerClasses()\" [style.height]=\"Height\">\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Row count -->\n @if (ShowRowCount) {\n <span class=\"row-count\">\n <i class=\"fa-solid fa-table-list\"></i>\n @if (TotalRowCount > RowCount) {\n {{ RowCount | number }} of {{ TotalRowCount | number }} {{ TotalRowCount === 1 ? 'row' : 'rows' }}\n } @else {\n {{ RowCount | number }} {{ RowCount === 1 ? 'row' : 'rows' }}\n }\n </span>\n }\n <!-- Selection count -->\n @if (ShowSelectionCount && SelectionCount > 0) {\n <span class=\"selection-count\">\n <i class=\"fa-solid fa-check-square\"></i>\n {{ SelectionCount }} selected\n <button class=\"clear-selection-btn\" (click)=\"ClearSelection()\" title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Refresh button -->\n @if (ShowRefresh) {\n <button\n (click)=\"Refresh()\"\n [disabled]=\"IsLoading\"\n title=\"Refresh data\"\n class=\"toolbar-btn icon-only\">\n <i class=\"fa-solid fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i>\n </button>\n }\n <!-- Export button -->\n @if (ShowExport) {\n <button\n [disabled]=\"RowCount === 0\"\n title=\"Export data\"\n class=\"toolbar-btn\"\n (click)=\"OpenExportDialog()\">\n <i class=\"fa-solid fa-file-export\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Loading overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\" @fadeIn>\n <mj-loading text=\"Loading query results...\"></mj-loading>\n </div>\n }\n\n <!-- AG Grid -->\n <div class=\"grid-wrapper\" [class.loading]=\"IsLoading\">\n <ag-grid-angular\n class=\"query-grid\"\n [theme]=\"Theme\"\n [rowData]=\"Data\"\n [columnDefs]=\"ColumnDefs\"\n [defaultColDef]=\"DefaultColDef\"\n [gridOptions]=\"GridOptions\"\n [rowSelection]=\"GetRowSelectionConfig()\"\n [getRowId]=\"GetRowId\"\n (gridReady)=\"OnGridReady($event)\"\n (rowClicked)=\"OnRowClicked($event)\"\n (rowDoubleClicked)=\"OnRowDoubleClicked($event)\"\n (selectionChanged)=\"OnSelectionChanged($event)\"\n (sortChanged)=\"OnSortChanged($event)\"\n (columnResized)=\"OnColumnResized($event)\"\n (columnMoved)=\"OnColumnMoved($event)\">\n </ag-grid-angular>\n </div>\n\n <!-- Pagination (only shown when server-side paging is active) -->\n @if (TotalRowCount > 0) {\n <mj-pagination\n [TotalRowCount]=\"TotalRowCount\"\n [PageNumber]=\"PageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && RowCount === 0) {\n <mj-empty-state\n class=\"empty-state\"\n @fadeIn\n Icon=\"fa-solid fa-database\"\n Title=\"No results\"\n Message=\"Run the query to see results\" />\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"ShowExportDialog\"\n [config]=\"ExportDialogConfig\"\n (closed)=\"OnExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Row Detail Panel -->\n<mj-query-row-detail\n [RowData]=\"RowDetailData\"\n [Columns]=\"Columns\"\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowRowDetailPanel\"\n [RowIndex]=\"RowDetailIndex\"\n [TotalRows]=\"RowCount\"\n (Close)=\"CloseRowDetailPanel()\"\n (EntityLinkClick)=\"OnRowDetailEntityLinkClick($event)\"\n (NavigateRow)=\"NavigateRowDetail($event)\">\n</mj-query-row-detail>\n"]}
1
+ {"version":3,"file":"query-data-grid.component.js","sourceRoot":"","sources":["../../../src/lib/query-data-grid/query-data-grid.component.ts","../../../src/lib/query-data-grid/query-data-grid.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ElementRef,\n ViewChild\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { debounceTime, takeUntil } from 'rxjs/operators';\nimport { MJQueryEntityExtended } from '@memberjunction/core-entities';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport {\n ColDef,\n GridReadyEvent,\n RowClickedEvent,\n GridApi,\n RowDoubleClickedEvent,\n ModuleRegistry,\n AllCommunityModule,\n RowSelectionOptions,\n GetRowIdParams,\n themeAlpine,\n SortChangedEvent as AgSortChangedEvent,\n type Theme,\n ColumnResizedEvent,\n ColumnMovedEvent,\n SelectionChangedEvent,\n ICellRendererParams,\n GridOptions\n} from 'ag-grid-community';\nimport {\n ExportService,\n ExportDialogConfig,\n ExportDialogResult\n} from '@memberjunction/ng-export-service';\nimport {\n ExportOptions,\n ExportResult,\n ExportColumn,\n ExportData\n} from '@memberjunction/export-engine';\nimport {\n QueryGridSelectionMode,\n QueryGridColumnConfig,\n QueryGridSortState,\n QueryGridState,\n QueryGridVisualConfig,\n DEFAULT_QUERY_VISUAL_CONFIG,\n QueryRowClickEvent,\n QueryEntityLinkClickEvent,\n QueryGridStateChangedEvent,\n QuerySelectionChangedEvent,\n QueryExportOptions,\n buildColumnsFromQueryFields,\n buildColumnsFromData,\n getQueryGridStateKey\n} from './models/query-grid-types';\nimport { RowDetailEntityLinkEvent } from '../query-row-detail/query-row-detail.component';\n\n// Register AG Grid modules\nModuleRegistry.registerModules([AllCommunityModule]);\n\n/**\n * A data grid component for displaying query results with full interactivity.\n * Features:\n * - Client-side sorting with multi-column support\n * - Column resizing, reordering, and visibility toggle\n * - Entity linking for columns with SourceEntityID\n * - State persistence to User Settings\n * - Export to Excel/CSV\n * - Row selection (single, multiple, checkbox modes)\n *\n * @example\n * ```html\n * <mj-query-data-grid\n * [queryInfo]=\"query\"\n * [data]=\"queryResults\"\n * [selectionMode]=\"'multiple'\"\n * (entityLinkClick)=\"onEntityLinkClick($event)\">\n * </mj-query-data-grid>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-query-data-grid',\n templateUrl: './query-data-grid.component.html',\n styleUrls: ['./query-data-grid.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('fadeIn', [\n transition(':enter', [\n style({ opacity: 0, transform: 'translateY(-8px)' }),\n animate('150ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))\n ]),\n transition(':leave', [\n animate('100ms ease-in', style({ opacity: 0, transform: 'translateY(-8px)' }))\n ])\n ])\n ]\n})\nexport class QueryDataGridComponent implements OnInit, OnDestroy {\n // ========================================\n // Inputs\n // ========================================\n\n private _queryInfo: MJQueryEntityExtended | null = null;\n /**\n * The QueryInfo metadata for the query being displayed.\n * Used to derive column configurations and entity linking.\n */\n @Input()\n set QueryInfo(value: MJQueryEntityExtended | null) {\n const previous = this._queryInfo;\n // Flush state for the previous query before switching\n if (previous && value !== previous) {\n this.FlushState();\n }\n this._queryInfo = value;\n if (value && value !== previous) {\n this.onQueryInfoChanged();\n }\n }\n get QueryInfo(): MJQueryEntityExtended | null {\n return this._queryInfo;\n }\n\n private _columnConfigs: QueryGridColumnConfig[] | null = null;\n /**\n * Optional pre-built column configurations for ad-hoc queries without saved metadata.\n * When provided, overrides both QueryInfo-derived columns and auto-inferred columns.\n * Enables entity linking without requiring a saved Query or QueryInfo object.\n *\n * Set this BEFORE setting Data to ensure columns are configured before the grid renders.\n */\n @Input()\n set ColumnConfigs(value: QueryGridColumnConfig[] | null) {\n this._columnConfigs = value;\n if (value && value.length > 0) {\n this.Columns = value;\n this.buildColumnDefs();\n this.cdr.markForCheck();\n }\n }\n get ColumnConfigs(): QueryGridColumnConfig[] | null {\n return this._columnConfigs;\n }\n\n private _data: Record<string, unknown>[] = [];\n\n /**\n * Per-row synthetic identity for rows that have no natural key column, so the\n * `getRowId` fallback can never return duplicate ids (ag-Grid silently merges\n * rows that share an id). Keyed by the row object reference; entries are added\n * as Data is assigned. A WeakMap so it never retains rows past their lifetime.\n */\n private _syntheticRowIds = new WeakMap<object, string>();\n private _syntheticRowIdSeq = 0;\n\n /**\n * The query result data to display in the grid.\n */\n @Input()\n set Data(value: Record<string, unknown>[]) {\n this._data = value || [];\n\n // Assign a stable synthetic id to each row up front, so the getRowId\n // fallback (used only when a row has no natural key column) is\n // collision-proof — rows with identical column values must NOT be merged.\n for (const row of this._data) {\n if (row && !this._syntheticRowIds.has(row)) {\n this._syntheticRowIds.set(row, `mjrow_${this._syntheticRowIdSeq++}`);\n }\n }\n\n // If we have data but no columns from metadata or explicit configs, build from data\n if (this._data.length > 0 && this.Columns.length === 0 && !this._columnConfigs) {\n this.Columns = buildColumnsFromData(this._data);\n this.buildColumnDefs();\n }\n\n if (this.GridApi) {\n this.GridApi.setGridOption('rowData', this._data);\n }\n this.cdr.markForCheck();\n }\n get Data(): Record<string, unknown>[] {\n return this._data;\n }\n\n /**\n * Selection mode for the grid\n */\n @Input() SelectionMode: QueryGridSelectionMode = 'multiple';\n\n /**\n * Whether to show the toolbar\n */\n @Input() ShowToolbar: boolean = true;\n\n /**\n * Whether to show row count in toolbar\n */\n @Input() ShowRowCount: boolean = true;\n\n /**\n * Whether to show selection count in toolbar\n */\n @Input() ShowSelectionCount: boolean = true;\n\n /**\n * Whether to show export button\n */\n @Input() ShowExport: boolean = true;\n\n /**\n * Whether to show refresh button\n */\n @Input() ShowRefresh: boolean = true;\n\n /**\n * Whether to allow sorting\n */\n @Input() AllowSorting: boolean = true;\n\n /**\n * Whether to allow column resizing\n */\n @Input() AllowColumnResize: boolean = true;\n\n /**\n * Whether to allow column reordering\n */\n @Input() AllowColumnReorder: boolean = true;\n\n /**\n * Visual configuration\n */\n @Input() VisualConfig: QueryGridVisualConfig = {};\n\n /**\n * External loading state - when true, shows loading overlay\n */\n @Input() IsLoading: boolean = false;\n\n /**\n * Height of the grid container\n */\n @Input() Height: string = '100%';\n\n /**\n * Initial grid state (for restoring from persistence)\n */\n @Input() InitialGridState: QueryGridState | null = null;\n\n /**\n * Whether to automatically persist grid state (column widths, order, sort) to User Settings\n */\n @Input() PersistState: boolean = true;\n\n // ========================================\n // Outputs\n // ========================================\n\n /**\n * Fired when a row is clicked\n */\n @Output() RowClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when a row is double-clicked\n */\n @Output() RowDoubleClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when an entity link is clicked\n */\n @Output() EntityLinkClick = new EventEmitter<QueryEntityLinkClickEvent>();\n\n /**\n * Fired when selection changes\n */\n @Output() SelectionChange = new EventEmitter<QuerySelectionChangedEvent>();\n\n /**\n * Fired when grid state changes (for persistence)\n */\n @Output() GridStateChange = new EventEmitter<QueryGridStateChangedEvent>();\n\n /**\n * Fired when refresh is requested\n */\n @Output() RefreshRequest = new EventEmitter<void>();\n\n /**\n * Total row count for server-side paging (from RunQueryResult.TotalRowCount).\n * When > 0 and TotalPages > 1, the data pager is displayed below the grid.\n */\n @Input() TotalRowCount: number = 0;\n\n /** Current page number (1-based) for server-side paging */\n @Input() PageNumber: number = 1;\n\n /** Page size for server-side paging */\n @Input() PageSize: number = 100;\n\n /**\n * Optional provider that returns the FULL result set for export. When the grid is server-side\n * paged, `Data` only holds the current page (default 100 rows), so exporting `Data` would silently\n * cap the export at the page size (bug B3/C1). A host that owns the query (with its parameters) can\n * supply this callback to fetch every matching row on demand; the grid awaits it when the user\n * exports without an explicit row selection. When not provided, export falls back to the loaded page.\n */\n @Input() ExportDataProvider: (() => Promise<Record<string, unknown>[]>) | null = null;\n\n /** True while an export is fetching the full result set via ExportDataProvider. */\n public IsPreparingExport: boolean = false;\n\n /** Fired when the user navigates to a different page */\n @Output() PageChange = new EventEmitter<PageChangeEvent>();\n\n // ========================================\n // Internal State\n // ========================================\n\n public GridApi: GridApi | null = null;\n public ColumnDefs: ColDef[] = [];\n public Columns: QueryGridColumnConfig[] = [];\n public SortState: QueryGridSortState[] = [];\n public SelectedRows: Record<string, unknown>[] = [];\n public Theme: Theme = themeAlpine.withParams({\n backgroundColor: 'var(--mj-bg-surface)',\n foregroundColor: 'var(--mj-text-primary)',\n textColor: 'var(--mj-text-primary)',\n borderColor: 'var(--mj-border-default)',\n chromeBackgroundColor: 'var(--mj-bg-surface-card)',\n headerBackgroundColor: 'var(--mj-bg-surface-card)',\n headerTextColor: 'var(--mj-text-secondary)',\n cellTextColor: 'var(--mj-text-primary)',\n subtleTextColor: 'var(--mj-text-muted)',\n dataBackgroundColor: 'var(--mj-bg-surface)',\n oddRowBackgroundColor: 'var(--mj-bg-surface-card)',\n rowHoverColor: 'var(--mj-bg-surface-hover, color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface)))',\n selectedRowBackgroundColor: 'color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface))',\n accentColor: 'var(--mj-brand-primary)',\n borderRadius: 'var(--mj-radius-sm)',\n browserColorScheme: 'inherit',\n });\n\n private destroy$ = new Subject<void>();\n private stateChangeSubject = new Subject<QueryGridStateChangedEvent>();\n private statePersistSubject = new Subject<QueryGridState>();\n private _mergedVisualConfig: Required<QueryGridVisualConfig> = DEFAULT_QUERY_VISUAL_CONFIG;\n private _pendingState: QueryGridState | null = null;\n\n // Grid options\n public GridOptions: GridOptions = {\n animateRows: true,\n rowHeight: 36,\n headerHeight: 40,\n suppressCellFocus: false,\n enableCellTextSelection: true,\n ensureDomOrder: true,\n suppressNoRowsOverlay: true\n };\n\n /** Default column settings - enables sorting, resizing */\n public DefaultColDef: ColDef = {\n sortable: true,\n resizable: true,\n minWidth: 50\n };\n\n constructor(\n private cdr: ChangeDetectorRef,\n private elementRef: ElementRef,\n private exportService: ExportService\n ) {\n // Debounce state changes for persistence\n this.stateChangeSubject.pipe(\n debounceTime(500),\n takeUntil(this.destroy$)\n ).subscribe(event => {\n this.GridStateChange.emit(event);\n // Also persist to User Settings if enabled\n if (this.PersistState && this._queryInfo) {\n this.statePersistSubject.next(event.state);\n }\n });\n\n // Debounce state persistence to User Settings\n this.statePersistSubject.pipe(\n debounceTime(1000),\n takeUntil(this.destroy$)\n ).subscribe(state => {\n this.persistGridState(state);\n });\n }\n\n ngOnInit(): void {\n this._mergedVisualConfig = { ...DEFAULT_QUERY_VISUAL_CONFIG, ...this.VisualConfig };\n this.applyVisualConfig();\n }\n\n ngOnDestroy(): void {\n // Flush any pending state changes before destroy\n this.FlushState();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Grid Setup\n // ========================================\n\n public OnGridReady(event: GridReadyEvent): void {\n this.GridApi = event.api;\n\n // Apply initial data if available\n if (this._data.length > 0) {\n this.GridApi.setGridOption('rowData', this._data);\n }\n\n // Apply initial state if provided via Input\n if (this.InitialGridState) {\n this.applyFullGridState(this.InitialGridState);\n }\n // Otherwise apply pending state from persistence\n else if (this._pendingState) {\n this.applyFullGridState(this._pendingState);\n this._pendingState = null;\n }\n // Only auto-size if no persisted state was applied\n else {\n setTimeout(() => {\n if (this.GridApi) {\n this.GridApi.autoSizeAllColumns();\n }\n }, 100);\n }\n }\n\n private onQueryInfoChanged(): void {\n if (!this._queryInfo) {\n this.Columns = [];\n this.ColumnDefs = [];\n return;\n }\n\n // Build columns from query fields\n this.Columns = buildColumnsFromQueryFields(this._queryInfo.QueryFields);\n\n // Apply initial state if provided via prop (takes precedence)\n if (this.InitialGridState) {\n this.applyColumnStateFromGridState(this.InitialGridState);\n } else {\n // Otherwise try to load from User Settings\n this.loadPersistedState();\n }\n\n // Build AG Grid column definitions\n this.buildColumnDefs();\n\n // If grid is already initialized and we have pending state, apply it now\n if (this.GridApi && this._pendingState) {\n this.applyFullGridState(this._pendingState);\n this._pendingState = null;\n }\n\n this.cdr.markForCheck();\n }\n\n private applyColumnStateFromGridState(state: QueryGridState): void {\n if (!state.columns) return;\n\n for (const colState of state.columns) {\n const column = this.Columns.find(c => c.field === colState.field);\n if (column) {\n if (colState.width !== undefined) column.width = colState.width;\n column.visible = colState.visible;\n column.order = colState.order;\n column.pinned = colState.pinned || null;\n }\n }\n\n // Apply sort state\n if (state.sort) {\n this.SortState = [...state.sort];\n }\n\n // Re-sort columns by order\n this.Columns.sort((a, b) => a.order - b.order);\n }\n\n private buildColumnDefs(): void {\n const visibleColumns = this.Columns.filter(c => c.visible);\n\n // Add checkbox column if needed\n const defs: ColDef[] = [];\n\n if (this.SelectionMode === 'checkbox') {\n defs.push({\n headerName: '',\n field: '__checkbox',\n width: 50,\n minWidth: 50,\n maxWidth: 50,\n checkboxSelection: true,\n headerCheckboxSelection: true,\n pinned: 'left',\n suppressSizeToFit: true,\n sortable: false,\n filter: false,\n resizable: false\n });\n }\n\n // Add data columns\n for (const col of visibleColumns) {\n const colDef: ColDef = {\n field: col.field,\n headerName: col.title,\n headerTooltip: col.description || undefined,\n width: col.width,\n minWidth: col.minWidth,\n maxWidth: col.maxWidth,\n sortable: this.AllowSorting && col.sortable,\n resizable: this.AllowColumnResize && col.resizable,\n pinned: col.pinned || undefined,\n flex: col.flex,\n cellStyle: this.getCellStyle(col),\n headerClass: this.getHeaderClass(col),\n comparator: (a, b) => this.defaultComparator(a, b, col)\n };\n\n // Add entity link cell renderer if applicable\n if (col.isEntityLink && col.targetEntityName) {\n colDef.cellRenderer = (params: ICellRendererParams) =>\n this.renderEntityLinkCell(params, col);\n // Add custom header with entity icon and column name\n colDef.headerComponentParams = {\n template: this.getEntityLinkHeaderTemplate(col)\n };\n } else {\n // Apply type-specific formatting\n colDef.valueFormatter = (params) => this.formatCellValue(params.value, col);\n }\n\n defs.push(colDef);\n }\n\n this.ColumnDefs = defs;\n\n // Apply to grid if ready\n if (this.GridApi) {\n this.GridApi.setGridOption('columnDefs', this.ColumnDefs);\n }\n }\n\n // ========================================\n // Cell Rendering\n // ========================================\n\n private getCellStyle(col: QueryGridColumnConfig): Record<string, string> {\n const style: Record<string, string> = {};\n\n if (col.align === 'right') {\n style['text-align'] = 'right';\n style['justify-content'] = 'flex-end';\n } else if (col.align === 'center') {\n style['text-align'] = 'center';\n style['justify-content'] = 'center';\n }\n\n return style;\n }\n\n private getHeaderClass(col: QueryGridColumnConfig): string {\n const classes: string[] = [];\n\n if (col.align === 'right') {\n classes.push('header-right');\n } else if (col.align === 'center') {\n classes.push('header-center');\n }\n\n return classes.join(' ');\n }\n\n private formatCellValue(value: unknown, col: QueryGridColumnConfig): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n const baseType = col.sqlBaseType.toLowerCase();\n\n // Boolean formatting\n if (baseType === 'bit') {\n if (this._mergedVisualConfig.booleanIcons) {\n return value ? '✓' : '✗';\n }\n return value ? 'Yes' : 'No';\n }\n\n // Date formatting\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n const date = new Date(value as string);\n if (isNaN(date.getTime())) return String(value);\n\n if (this._mergedVisualConfig.friendlyDates) {\n if (baseType === 'date') {\n return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });\n }\n return date.toLocaleString('en-US', {\n year: 'numeric', month: 'short', day: 'numeric',\n hour: 'numeric', minute: '2-digit'\n });\n }\n return date.toISOString();\n }\n\n // Number formatting - check if value is actually numeric first\n if (['int', 'bigint', 'smallint', 'tinyint'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return num.toLocaleString();\n }\n\n if (['decimal', 'numeric', 'float', 'real'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 });\n }\n\n if (['money', 'smallmoney'].includes(baseType)) {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(num);\n }\n\n return String(value);\n }\n\n private renderEntityLinkCell(params: ICellRendererParams, col: QueryGridColumnConfig): HTMLElement {\n const container = document.createElement('div');\n container.className = 'entity-link-cell';\n\n if (params.value === null || params.value === undefined) {\n return container;\n }\n\n const link = document.createElement('a');\n link.href = 'javascript:void(0)';\n link.className = 'entity-link';\n link.textContent = String(params.value);\n link.title = `Open ${col.targetEntityName} record`;\n\n link.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.EntityLinkClick.emit({\n entityName: col.targetEntityName!,\n recordId: String(params.value),\n column: col,\n rowData: params.data\n });\n });\n\n container.appendChild(link);\n\n const icon = document.createElement('i');\n icon.className = 'fa-solid fa-arrow-up-right-from-square entity-link-icon';\n container.appendChild(icon);\n\n return container;\n }\n\n /**\n * Generates header template HTML with entity icon from metadata\n * Shows: [Entity Icon] Column Name [Sort Icons]\n */\n private getEntityLinkHeaderTemplate(col: QueryGridColumnConfig): string {\n // Use the target entity's icon from metadata, fallback to generic icons\n const entityIcon = col.targetEntityIcon || (col.isPrimaryKey ? 'fa-solid fa-key' : 'fa-solid fa-link');\n const tooltip = col.isPrimaryKey\n ? `Primary key - links to ${col.targetEntityName}`\n : `Foreign key - links to ${col.targetEntityName}`;\n // Escape the title for safe HTML insertion\n const escapedTitle = col.title.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n return `\n <div class=\"ag-cell-label-container\" role=\"presentation\">\n <span ref=\"eMenu\" class=\"ag-header-icon ag-header-cell-menu-button\" aria-hidden=\"true\"></span>\n <div ref=\"eLabel\" class=\"ag-header-cell-label\" role=\"presentation\">\n <i class=\"${entityIcon} entity-header-icon\" style=\"color: #5c6bc0; margin-right: 6px; font-size: 12px;\" title=\"${tooltip}\"></i>\n <span ref=\"eText\" class=\"ag-header-cell-text\">${escapedTitle}</span>\n <span ref=\"eFilter\" class=\"ag-header-icon ag-header-label-icon ag-filter-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortOrder\" class=\"ag-header-icon ag-header-label-icon ag-sort-order\" aria-hidden=\"true\"></span>\n <span ref=\"eSortAsc\" class=\"ag-header-icon ag-header-label-icon ag-sort-ascending-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortDesc\" class=\"ag-header-icon ag-header-label-icon ag-sort-descending-icon\" aria-hidden=\"true\"></span>\n <span ref=\"eSortNone\" class=\"ag-header-icon ag-header-label-icon ag-sort-none-icon\" aria-hidden=\"true\"></span>\n </div>\n </div>\n `;\n }\n\n private defaultComparator(a: unknown, b: unknown, col: QueryGridColumnConfig): number {\n if (a === null || a === undefined) return 1;\n if (b === null || b === undefined) return -1;\n\n const baseType = col.sqlBaseType.toLowerCase();\n\n // Numeric comparison\n if (['int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney'].includes(baseType)) {\n return Number(a) - Number(b);\n }\n\n // Date comparison\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n return new Date(a as string).getTime() - new Date(b as string).getTime();\n }\n\n // String comparison (case-insensitive)\n return String(a).toLowerCase().localeCompare(String(b).toLowerCase());\n }\n\n // ========================================\n // Event Handlers\n // ========================================\n\n public OnRowClicked(event: RowClickedEvent): void {\n const clickEvent: QueryRowClickEvent = {\n rowData: event.data,\n rowIndex: event.rowIndex!,\n mouseEvent: event.event as MouseEvent\n };\n this.RowClick.emit(clickEvent);\n\n // Open row detail panel on single click\n this.OpenRowDetailPanel(event.data, event.rowIndex!);\n }\n\n public OnRowDoubleClicked(event: RowDoubleClickedEvent): void {\n const clickEvent: QueryRowClickEvent = {\n rowData: event.data,\n rowIndex: event.rowIndex!,\n mouseEvent: event.event as MouseEvent\n };\n this.RowDoubleClick.emit(clickEvent);\n }\n\n public OnSelectionChanged(event: SelectionChangedEvent): void {\n if (!this.GridApi) return;\n\n this.SelectedRows = this.GridApi.getSelectedRows();\n const selectedIndices: number[] = [];\n\n this.GridApi.forEachNode((node, index) => {\n if (node.isSelected()) {\n selectedIndices.push(index);\n }\n });\n\n this.SelectionChange.emit({\n selectedIndices,\n selectedRows: this.SelectedRows\n });\n\n this.cdr.markForCheck();\n }\n\n public OnSortChanged(event: AgSortChangedEvent): void {\n if (!this.GridApi) return;\n\n const columnState = this.GridApi.getColumnState();\n const newSortState: QueryGridSortState[] = [];\n\n columnState\n .filter(cs => cs.sort)\n .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))\n .forEach((cs, index) => {\n newSortState.push({\n field: cs.colId,\n direction: cs.sort as 'asc' | 'desc',\n index\n });\n });\n\n this.SortState = newSortState;\n this.emitStateChange('sort');\n }\n\n public OnColumnResized(event: ColumnResizedEvent): void {\n if (!event.finished || !event.column) return;\n\n const field = event.column.getColId();\n const column = this.Columns.find(c => c.field === field);\n if (column) {\n column.width = event.column.getActualWidth();\n this.emitStateChange('column-resize');\n }\n }\n\n public OnColumnMoved(event: ColumnMovedEvent): void {\n if (!this.GridApi || !event.finished) return;\n\n // Update column order from grid state\n const columnState = this.GridApi.getColumnState();\n columnState.forEach((cs, index) => {\n const column = this.Columns.find(c => c.field === cs.colId);\n if (column) {\n column.order = index;\n }\n });\n\n this.emitStateChange('column-move');\n }\n\n // ========================================\n // State Management\n // ========================================\n\n private emitStateChange(changeType: 'column-resize' | 'column-move' | 'column-visibility' | 'sort'): void {\n const state = this.GetGridState();\n this.stateChangeSubject.next({ state, changeType });\n }\n\n public GetGridState(): QueryGridState {\n return {\n columns: this.Columns.map(c => ({\n field: c.field,\n width: c.width,\n visible: c.visible,\n order: c.order,\n pinned: c.pinned\n })),\n sort: this.SortState\n };\n }\n\n public ApplyGridState(state: QueryGridState): void {\n this.applyColumnStateFromGridState(state);\n this.buildColumnDefs();\n\n // Apply sort state to grid\n if (this.GridApi && state.sort.length > 0) {\n const columnState = state.sort.map(s => ({\n colId: s.field,\n sort: s.direction,\n sortIndex: s.index\n }));\n this.GridApi.applyColumnState({ state: columnState });\n }\n }\n\n /**\n * Loads persisted grid state from User Settings\n */\n private loadPersistedState(): void {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n try {\n const settingKey = getQueryGridStateKey(this._queryInfo.ID);\n const savedState = UserInfoEngine.Instance.GetSetting(settingKey);\n\n if (savedState) {\n const state = JSON.parse(savedState) as QueryGridState;\n\n // Apply column state immediately (affects buildColumnDefs)\n this.applyColumnStateFromGridState(state);\n\n // Store for applying via Grid API when ready\n this._pendingState = state;\n\n // If grid is already ready, apply full state now\n if (this.GridApi) {\n this.applyFullGridState(state);\n this._pendingState = null;\n }\n }\n } catch (error) {\n console.error('[query-data-grid] Failed to load persisted state:', error);\n }\n }\n\n /**\n * Applies the full grid state (column widths, order, and sort) via the Grid API.\n * This is called after grid is ready to ensure all state is applied correctly.\n */\n private applyFullGridState(state: QueryGridState): void {\n if (!this.GridApi) {\n return;\n }\n\n // Build column state array that includes widths and sort\n const columnState: Array<{\n colId: string;\n width?: number;\n sort?: 'asc' | 'desc' | null;\n sortIndex?: number | null;\n }> = [];\n\n // First, add column widths from saved state\n if (state.columns) {\n for (const col of state.columns) {\n const stateItem: {\n colId: string;\n width?: number;\n sort?: 'asc' | 'desc' | null;\n sortIndex?: number | null;\n } = { colId: col.field };\n\n if (col.width !== undefined) {\n stateItem.width = col.width;\n }\n\n // Check if this column has sort state\n const sortInfo = state.sort?.find(s => s.field === col.field);\n if (sortInfo) {\n stateItem.sort = sortInfo.direction;\n stateItem.sortIndex = sortInfo.index;\n }\n\n columnState.push(stateItem);\n }\n }\n\n // Apply all column state at once\n if (columnState.length > 0) {\n this.GridApi.applyColumnState({\n state: columnState,\n applyOrder: true // Apply column order as well\n });\n }\n }\n\n /**\n * Persists grid state to User Settings\n */\n private async persistGridState(state: QueryGridState): Promise<void> {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n try {\n const settingKey = getQueryGridStateKey(this._queryInfo.ID);\n await UserInfoEngine.Instance.SetSetting(settingKey, JSON.stringify(state));\n } catch (error) {\n console.error('[query-data-grid] Failed to persist grid state:', error);\n }\n }\n\n /**\n * Flushes any pending state changes immediately.\n * Call this before destroying the component or switching queries\n * to ensure all state changes are persisted.\n */\n public FlushState(): void {\n if (!this.PersistState || !this._queryInfo) {\n return;\n }\n\n // Get current state and persist immediately\n const state = this.GetGridState();\n this.persistGridState(state);\n }\n\n // ========================================\n // Visual Config\n // ========================================\n\n private applyVisualConfig(): void {\n const el = this.elementRef.nativeElement;\n\n // Apply CSS variables\n if (this._mergedVisualConfig.accentColor) {\n el.style.setProperty('--grid-accent-color', this._mergedVisualConfig.accentColor);\n }\n if (this._mergedVisualConfig.selectionIndicatorColor) {\n el.style.setProperty('--grid-selection-indicator', this._mergedVisualConfig.selectionIndicatorColor);\n }\n if (this._mergedVisualConfig.selectionBackground) {\n el.style.setProperty('--grid-selection-bg', this._mergedVisualConfig.selectionBackground);\n }\n }\n\n /**\n * Returns CSS classes for the container based on visual config\n */\n public GetContainerClasses(): Record<string, boolean> {\n const contrast = this._mergedVisualConfig.alternateRowContrast || 'medium';\n return {\n [`alternate-rows-${contrast}`]: true\n };\n }\n\n // ========================================\n // Export Dialog\n // ========================================\n\n public ShowExportDialog: boolean = false;\n public ExportDialogConfig: ExportDialogConfig | null = null;\n\n // ========================================\n // Row Detail Panel State\n // ========================================\n\n public ShowRowDetailPanel: boolean = false;\n public RowDetailData: Record<string, unknown> | null = null;\n public RowDetailIndex: number = 0;\n\n // ========================================\n // Toolbar Actions\n // ========================================\n\n public Refresh(): void {\n this.RefreshRequest.emit();\n }\n\n /**\n * Opens the export dialog with current grid data\n */\n public async OpenExportDialog(): Promise<void> {\n if (!this._data.length) return;\n\n this.IsPreparingExport = true;\n this.cdr.detectChanges();\n let data: ExportData;\n try {\n data = await this.resolveExportData();\n } finally {\n this.IsPreparingExport = false;\n }\n const columns = this.getExportColumns();\n const fileName = this._queryInfo?.Name || 'query-export';\n\n this.ExportDialogConfig = {\n data,\n columns,\n defaultFileName: fileName,\n availableFormats: ['excel', 'csv', 'json'],\n defaultFormat: 'excel',\n showSamplingOptions: true,\n defaultSamplingMode: 'all',\n dialogTitle: `Export ${this._queryInfo?.Name || 'Query Results'}`\n };\n this.ShowExportDialog = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle export dialog close\n */\n public OnExportDialogClosed(result: ExportDialogResult): void {\n this.ShowExportDialog = false;\n this.ExportDialogConfig = null;\n this.cdr.detectChanges();\n }\n\n /**\n * Export grid data directly without showing dialog\n */\n public async Export(options?: Partial<ExportOptions>, download: boolean = true): Promise<ExportResult> {\n const data = await this.resolveExportData();\n const columns = this.getExportColumns();\n const fileName = options?.fileName || this._queryInfo?.Name || 'query-export';\n\n const exportOptions: Partial<ExportOptions> = {\n format: 'excel',\n fileName,\n columns,\n includeHeaders: true,\n ...options\n };\n\n const result = await this.exportService.export(data, exportOptions);\n\n if (result.success && download) {\n this.exportService.downloadResult(result);\n }\n\n return result;\n }\n\n /**\n * Resolves the rows to export. An explicit row selection always wins. Otherwise, if a host\n * supplied an ExportDataProvider, the full result set is fetched (so export isn't silently\n * capped at the current page — bug B3/C1); if it isn't supplied or the fetch yields nothing,\n * export falls back to the loaded page (`_data`).\n */\n private async resolveExportData(): Promise<ExportData> {\n if (this.SelectedRows.length > 0) {\n return this.SelectedRows as ExportData;\n }\n if (this.ExportDataProvider) {\n try {\n const allRows = await this.ExportDataProvider();\n if (allRows && allRows.length > 0) {\n return allRows as ExportData;\n }\n } catch {\n // Fall through to the loaded page on any fetch failure.\n }\n }\n return this._data as ExportData;\n }\n\n /**\n * Get column definitions for export based on current grid columns\n */\n private getExportColumns(): ExportColumn[] {\n return this.Columns\n .filter(c => c.visible)\n .map(c => ({\n name: c.field,\n displayName: c.title,\n type: this.mapSqlTypeToExportType(c.sqlBaseType)\n }));\n }\n\n private mapSqlTypeToExportType(sqlType: string): 'string' | 'number' | 'boolean' | 'date' {\n const baseType = sqlType.toLowerCase();\n if (['int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real', 'money', 'smallmoney'].includes(baseType)) {\n return 'number';\n }\n if (['bit'].includes(baseType)) {\n return 'boolean';\n }\n if (['date', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset'].includes(baseType)) {\n return 'date';\n }\n return 'string';\n }\n\n public ClearSelection(): void {\n if (this.GridApi) {\n this.GridApi.deselectAll();\n }\n }\n\n // ========================================\n // Public API\n // ========================================\n\n public GetSelectedRows(): Record<string, unknown>[] {\n return this.SelectedRows;\n }\n\n public get RowCount(): number {\n return this._data.length;\n }\n\n public get SelectionCount(): number {\n return this.SelectedRows.length;\n }\n\n // ========================================\n // AG Grid Configuration\n // ========================================\n\n public GetRowSelectionConfig(): RowSelectionOptions | undefined {\n if (this.SelectionMode === 'none') {\n return undefined;\n }\n\n if (this.SelectionMode === 'single') {\n return {\n mode: 'singleRow',\n enableClickSelection: true\n };\n }\n\n // Multi-row selection (both 'multiple' and 'checkbox' modes)\n return {\n mode: 'multiRow',\n enableClickSelection: true,\n checkboxes: this.SelectionMode === 'checkbox',\n enableSelectionWithoutKeys: this.SelectionMode === 'multiple'\n };\n }\n\n public GetRowId = (params: GetRowIdParams): string => {\n const data = params.data as Record<string, unknown>;\n if (!data) return `mjrow_${this._syntheticRowIdSeq++}`;\n\n // Prefer a natural unique key when the result exposes one — this keeps row\n // identity (and selection) stable across data refreshes.\n const idFields = ['ID', 'Id', 'id', 'RowNumber', 'RowNum', '__row_index'];\n for (const field of idFields) {\n if (data[field] !== undefined && data[field] !== null) {\n return String(data[field]);\n }\n }\n\n // No natural key — use the per-row synthetic id assigned when Data was set.\n // The previous fallback hashed only the first 3 columns, so any rows that\n // matched on those columns collided to the same id and ag-Grid dropped all\n // but one (silently collapsing aggregate/GROUP BY results, or any query\n // without an ID column). A per-row synthetic id can never collide.\n // Trade-off: the id is per-object (not value-derived), so an id-less row\n // loses its selection across a data refresh — acceptable for query results,\n // where NOT dropping rows matters far more than preserving a selection.\n let synthetic = this._syntheticRowIds.get(data);\n if (!synthetic) {\n synthetic = `mjrow_${this._syntheticRowIdSeq++}`;\n this._syntheticRowIds.set(data, synthetic);\n }\n return synthetic;\n };\n\n // ========================================\n // Row Detail Panel\n // ========================================\n\n /**\n * Opens the row detail panel with the given row data\n */\n public OpenRowDetailPanel(rowData: Record<string, unknown>, rowIndex: number): void {\n this.RowDetailData = rowData;\n this.RowDetailIndex = rowIndex;\n this.ShowRowDetailPanel = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Closes the row detail panel\n */\n public CloseRowDetailPanel(): void {\n this.ShowRowDetailPanel = false;\n this.RowDetailData = null;\n this.cdr.markForCheck();\n }\n\n /**\n * Navigate to the previous row in the detail panel\n */\n public NavigateRowDetail(direction: 'prev' | 'next'): void {\n if (!this._data.length) return;\n\n if (direction === 'prev' && this.RowDetailIndex > 0) {\n this.RowDetailIndex--;\n this.RowDetailData = this._data[this.RowDetailIndex];\n } else if (direction === 'next' && this.RowDetailIndex < this._data.length - 1) {\n this.RowDetailIndex++;\n this.RowDetailData = this._data[this.RowDetailIndex];\n }\n\n // Select the row in the grid\n if (this.GridApi) {\n this.GridApi.deselectAll();\n const node = this.GridApi.getRowNode(String(this.RowDetailIndex));\n if (node) {\n node.setSelected(true);\n this.GridApi.ensureNodeVisible(node);\n }\n }\n\n this.cdr.markForCheck();\n }\n\n /**\n * Handle entity link click from the row detail panel\n */\n public OnRowDetailEntityLinkClick(event: RowDetailEntityLinkEvent): void {\n // Find the column config to include in the entity link event\n const column = this.Columns.find(c => c.field === event.fieldName);\n\n this.EntityLinkClick.emit({\n entityName: event.entityName,\n recordId: event.recordId,\n column: column || null,\n rowData: this.RowDetailData || {}\n });\n }\n}\n","<!-- Query Data Grid Component -->\n<div class=\"query-data-grid-container\" [ngClass]=\"GetContainerClasses()\" [style.height]=\"Height\">\n <!-- Toolbar -->\n @if (ShowToolbar) {\n <div class=\"grid-toolbar\">\n <div class=\"toolbar-left\">\n <!-- Row count -->\n @if (ShowRowCount) {\n <span class=\"row-count\">\n <i class=\"fa-solid fa-table-list\"></i>\n @if (TotalRowCount > RowCount) {\n {{ RowCount | number }} of {{ TotalRowCount | number }} {{ TotalRowCount === 1 ? 'row' : 'rows' }}\n } @else {\n {{ RowCount | number }} {{ RowCount === 1 ? 'row' : 'rows' }}\n }\n </span>\n }\n <!-- Selection count -->\n @if (ShowSelectionCount && SelectionCount > 0) {\n <span class=\"selection-count\">\n <i class=\"fa-solid fa-check-square\"></i>\n {{ SelectionCount }} selected\n <button class=\"clear-selection-btn\" (click)=\"ClearSelection()\" title=\"Clear selection\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </span>\n }\n </div>\n <div class=\"toolbar-right\">\n <!-- Refresh button -->\n @if (ShowRefresh) {\n <button\n (click)=\"Refresh()\"\n [disabled]=\"IsLoading\"\n title=\"Refresh data\"\n class=\"toolbar-btn icon-only\">\n <i class=\"fa-solid fa-sync-alt\" [class.fa-spin]=\"IsLoading\"></i>\n </button>\n }\n <!-- Export button -->\n @if (ShowExport) {\n <button\n [disabled]=\"RowCount === 0 || IsPreparingExport\"\n title=\"Export data\"\n class=\"toolbar-btn\"\n (click)=\"OpenExportDialog()\">\n <i class=\"fa-solid\" [class.fa-file-export]=\"!IsPreparingExport\" [class.fa-spinner]=\"IsPreparingExport\" [class.fa-spin]=\"IsPreparingExport\"></i>\n <span class=\"button-text\">Export</span>\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Loading overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\" @fadeIn>\n <mj-loading text=\"Loading query results...\"></mj-loading>\n </div>\n }\n\n <!-- AG Grid -->\n <div class=\"grid-wrapper\" [class.loading]=\"IsLoading\">\n <ag-grid-angular\n class=\"query-grid\"\n [theme]=\"Theme\"\n [rowData]=\"Data\"\n [columnDefs]=\"ColumnDefs\"\n [defaultColDef]=\"DefaultColDef\"\n [gridOptions]=\"GridOptions\"\n [rowSelection]=\"GetRowSelectionConfig()\"\n [getRowId]=\"GetRowId\"\n (gridReady)=\"OnGridReady($event)\"\n (rowClicked)=\"OnRowClicked($event)\"\n (rowDoubleClicked)=\"OnRowDoubleClicked($event)\"\n (selectionChanged)=\"OnSelectionChanged($event)\"\n (sortChanged)=\"OnSortChanged($event)\"\n (columnResized)=\"OnColumnResized($event)\"\n (columnMoved)=\"OnColumnMoved($event)\">\n </ag-grid-angular>\n </div>\n\n <!-- Pagination (only shown when server-side paging is active) -->\n @if (TotalRowCount > 0) {\n <mj-pagination\n [TotalRowCount]=\"TotalRowCount\"\n [PageNumber]=\"PageNumber\"\n [PageSize]=\"PageSize\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"PageChange.emit($event)\">\n </mj-pagination>\n }\n\n <!-- Empty state -->\n @if (!IsLoading && RowCount === 0) {\n <mj-empty-state\n class=\"empty-state\"\n @fadeIn\n Icon=\"fa-solid fa-database\"\n Title=\"No results\"\n Message=\"Run the query to see results\" />\n }\n</div>\n\n<!-- Export Dialog -->\n<mj-export-dialog\n [visible]=\"ShowExportDialog\"\n [config]=\"ExportDialogConfig\"\n (closed)=\"OnExportDialogClosed($event)\">\n</mj-export-dialog>\n\n<!-- Row Detail Panel -->\n<mj-query-row-detail\n [RowData]=\"RowDetailData\"\n [Columns]=\"Columns\"\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowRowDetailPanel\"\n [RowIndex]=\"RowDetailIndex\"\n [TotalRows]=\"RowCount\"\n (Close)=\"CloseRowDetailPanel()\"\n (EntityLinkClick)=\"OnRowDetailEntityLinkClick($event)\"\n (NavigateRow)=\"NavigateRowDetail($event)\">\n</mj-query-row-detail>\n"]}
@@ -27,6 +27,12 @@ import * as i0 from "@angular/core";
27
27
  */
28
28
  export declare class QueryViewerComponent extends BaseAngularComponent implements OnInit, OnDestroy {
29
29
  private cdr;
30
+ /**
31
+ * Safety cap for the export path — deliberately large (exports should cover the full result set)
32
+ * but bounded to protect the browser from an unbounded query. Kept in lockstep with the
33
+ * entity-viewer's EXPORT_MAX_RECORDS so Export behaves the same across Queries and Data Explorer.
34
+ */
35
+ private static readonly EXPORT_MAX_RECORDS;
30
36
  private _queryId;
31
37
  /**
32
38
  * The ID of the query to display
@@ -124,6 +130,15 @@ export declare class QueryViewerComponent extends BaseAngularComponent implement
124
130
  private getUserSetting;
125
131
  private setUserSetting;
126
132
  RunQuery(params: QueryParameterValues, pageNumber?: number): Promise<void>;
133
+ /**
134
+ * Fetches the FULL result set for the current query, used by the grid's export flow so exports
135
+ * aren't capped at the on-screen page (bug B3). Bound as an arrow property so it can be passed to
136
+ * the grid's ExportDataProvider input without losing `this`. Loads up to {@link EXPORT_MAX_RECORDS}
137
+ * (kept in lockstep with the entity-viewer's export cap) and warns — rather than silently
138
+ * truncating — when the query returns more. Uses the provider-scoped RunQuery so it targets the
139
+ * correct server in multi-provider setups. Falls back to the currently-loaded page on failure.
140
+ */
141
+ FetchAllRowsForExport: () => Promise<Record<string, unknown>[]>;
127
142
  OnParametersSubmit(params: QueryParameterValues): void;
128
143
  OnParamsPanelClose(): void;
129
144
  OnGridStateChange(event: QueryGridStateChangedEvent): void;
@@ -1 +1 @@
1
- {"version":3,"file":"query-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/query-viewer/query-viewer.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-viewer.component.d.ts","sourceRoot":"","sources":["../../../src/lib/query-viewer/query-viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,YAAY,EACZ,MAAM,EACN,SAAS,EACT,iBAAiB,EAGpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAA4B,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EAAE,qBAAqB,EAAe,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EACH,sBAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,kBAAkB,EAGrB,MAAM,4CAA4C,CAAC;;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAOa,oBAAqB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAyI3E,OAAO,CAAC,GAAG;IAxIvB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAMpD,OAAO,CAAC,QAAQ,CAAuB;IACvC;;OAEG;IACH,IACI,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAM/B;IACD,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED;;OAEG;IACM,OAAO,EAAE,OAAO,CAAQ;IAEjC;;OAEG;IACM,aAAa,EAAE,sBAAsB,CAAY;IAE1D;;OAEG;IACM,WAAW,EAAE,OAAO,CAAQ;IAErC;;OAEG;IACM,YAAY,EAAE,qBAAqB,CAAM;IAElD;;OAEG;IACM,YAAY,EAAE,OAAO,CAAQ;IAEtC;;OAEG;IACM,iBAAiB,EAAE,OAAO,CAAQ;IAE3C;;;OAGG;IACM,QAAQ,EAAE,MAAM,CAAO;IAMhC;;OAEG;IACO,eAAe,0CAAiD;IAE1E;;OAEG;IACO,cAAc,mCAA0C;IAElE;;OAEG;IACO,eAAe,2CAAkD;IAE3E;;OAEG;IACO,UAAU,qBAA4B;IAEhD;;OAEG;IACO,aAAa,+BAAsC;IAE7D;;OAEG;IACO,UAAU,sBAA6B;IAEjD;;OAEG;IACO,eAAe;iBAA+B,MAAM;mBAAa,MAAM;OAAM;IAEvF;;OAEG;IACO,qBAAqB,2CAAkD;IAM9C,QAAQ,EAAG,sBAAsB,CAAC;IAM9D,SAAS,EAAE,qBAAqB,GAAG,IAAI,CAAQ;IAC/C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAC1C,SAAS,EAAE,OAAO,CAAS;IAC3B,eAAe,EAAE,OAAO,CAAS;IACjC,aAAa,EAAE,OAAO,CAAS;IAC/B,MAAM,EAAE,OAAO,CAAS;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAQ;IAC7C,WAAW,EAAE,oBAAoB,CAAM;IAE9C,mBAAmB;IACZ,kBAAkB,EAAE,MAAM,CAAK;IAC/B,iBAAiB,EAAE,MAAM,CAAK;IAErC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,cAAc,CAA2B;gBAE7B,GAAG,EAAE,iBAAiB;IAE1C,QAAQ,IAAI,IAAI;IAEhB,WAAW,IAAI,IAAI;YASL,gBAAgB;IAqD9B,OAAO,CAAC,yBAAyB;YAsBnB,cAAc;YA0Bd,aAAa;YAWb,cAAc;YAWd,cAAc;YAId,cAAc;IAQf,QAAQ,CAAC,MAAM,EAAE,oBAAoB,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAuE1F;;;;;;;OAOG;IACI,qBAAqB,QAAa,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CA4BzE;IAMK,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAItD,kBAAkB,IAAI,IAAI;IAK1B,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI;IAI1D,iBAAiB,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;IAIzD,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAIjD,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI;IAI1D,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI1C,gBAAgB,IAAI,IAAI;IAexB,mBAAmB,IAAI,IAAI;IAK3B,aAAa,IAAI,IAAI;IAKrB,cAAc,IAAI,IAAI;IAKtB,iBAAiB,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAItE,uBAAuB,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI;IAIhE,OAAO,IAAI,IAAI;IAItB,IAAW,aAAa,IAAI,OAAO,CAElC;IAED;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;yCA/dnB,oBAAoB;2CAApB,oBAAoB;CA2fhC"}
@@ -122,7 +122,7 @@ function QueryViewerComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
122
122
  i0.ɵɵelementEnd();
123
123
  } if (rf & 2) {
124
124
  const ctx_r1 = i0.ɵɵnextContext();
125
- i0.ɵɵproperty("QueryInfo", ctx_r1.QueryInfo)("Data", ctx_r1.QueryData)("TotalRowCount", ctx_r1.QueryTotalRowCount)("PageNumber", ctx_r1.CurrentPageNumber)("PageSize", ctx_r1.PageSize)("SelectionMode", ctx_r1.SelectionMode)("ShowToolbar", ctx_r1.ShowToolbar)("VisualConfig", ctx_r1.VisualConfig)("IsLoading", ctx_r1.IsLoading);
125
+ i0.ɵɵproperty("QueryInfo", ctx_r1.QueryInfo)("Data", ctx_r1.QueryData)("ExportDataProvider", ctx_r1.FetchAllRowsForExport)("TotalRowCount", ctx_r1.QueryTotalRowCount)("PageNumber", ctx_r1.CurrentPageNumber)("PageSize", ctx_r1.PageSize)("SelectionMode", ctx_r1.SelectionMode)("ShowToolbar", ctx_r1.ShowToolbar)("VisualConfig", ctx_r1.VisualConfig)("IsLoading", ctx_r1.IsLoading);
126
126
  } }
127
127
  /**
128
128
  * A composite component that provides a complete query viewing experience.
@@ -144,6 +144,12 @@ function QueryViewerComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
144
144
  */
145
145
  export class QueryViewerComponent extends BaseAngularComponent {
146
146
  cdr;
147
+ /**
148
+ * Safety cap for the export path — deliberately large (exports should cover the full result set)
149
+ * but bounded to protect the browser from an unbounded query. Kept in lockstep with the
150
+ * entity-viewer's EXPORT_MAX_RECORDS so Export behaves the same across Queries and Data Explorer.
151
+ */
152
+ static EXPORT_MAX_RECORDS = 100000;
147
153
  // ========================================
148
154
  // Inputs
149
155
  // ========================================
@@ -434,6 +440,40 @@ export class QueryViewerComponent extends BaseAngularComponent {
434
440
  this.cdr.markForCheck();
435
441
  }
436
442
  }
443
+ /**
444
+ * Fetches the FULL result set for the current query, used by the grid's export flow so exports
445
+ * aren't capped at the on-screen page (bug B3). Bound as an arrow property so it can be passed to
446
+ * the grid's ExportDataProvider input without losing `this`. Loads up to {@link EXPORT_MAX_RECORDS}
447
+ * (kept in lockstep with the entity-viewer's export cap) and warns — rather than silently
448
+ * truncating — when the query returns more. Uses the provider-scoped RunQuery so it targets the
449
+ * correct server in multi-provider setups. Falls back to the currently-loaded page on failure.
450
+ */
451
+ FetchAllRowsForExport = async () => {
452
+ if (!this._queryId) {
453
+ return this.QueryData;
454
+ }
455
+ try {
456
+ // MaxRows caps the pull to protect the browser from an unbounded query; StartRow 0 = from
457
+ // the top. This is a much larger window than the on-screen page, so export covers the set.
458
+ const result = await this.RunQueryToUse.RunQuery({
459
+ QueryID: this._queryId,
460
+ Parameters: this.SavedParams,
461
+ MaxRows: QueryViewerComponent.EXPORT_MAX_RECORDS,
462
+ StartRow: 0
463
+ });
464
+ if (result.Success) {
465
+ if (result.TotalRowCount > QueryViewerComponent.EXPORT_MAX_RECORDS) {
466
+ MJNotificationService.Instance.CreateSimpleNotification(`This export is limited to the first ${QueryViewerComponent.EXPORT_MAX_RECORDS.toLocaleString()} of ` +
467
+ `${result.TotalRowCount.toLocaleString()} rows. Refine the query to include the rest.`, 'warning', 6000);
468
+ }
469
+ return result.Results || [];
470
+ }
471
+ }
472
+ catch {
473
+ // Fall through to the loaded page.
474
+ }
475
+ return this.QueryData;
476
+ };
437
477
  // ========================================
438
478
  // Event Handlers
439
479
  // ========================================
@@ -539,7 +579,7 @@ export class QueryViewerComponent extends BaseAngularComponent {
539
579
  } if (rf & 2) {
540
580
  let _t;
541
581
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.DataGrid = _t.first);
542
- } }, inputs: { QueryId: "QueryId", AutoRun: "AutoRun", SelectionMode: "SelectionMode", ShowToolbar: "ShowToolbar", VisualConfig: "VisualConfig", PersistState: "PersistState", PersistParameters: "PersistParameters", PageSize: "PageSize" }, outputs: { EntityLinkClick: "EntityLinkClick", RowDoubleClick: "RowDoubleClick", SelectionChange: "SelectionChange", QueryStart: "QueryStart", QueryComplete: "QueryComplete", QueryError: "QueryError", OpenQueryRecord: "OpenQueryRecord", CompositionTokenClick: "CompositionTokenClick" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 11, consts: [[1, "query-viewer-container"], [1, "query-header"], [1, "query-content"], [1, "no-query-state"], [1, "error-state"], [1, "query-description"], [1, "execution-error"], [3, "QueryInfo", "Data", "TotalRowCount", "PageNumber", "PageSize", "SelectionMode", "ShowToolbar", "VisualConfig", "IsLoading"], [3, "ParametersSubmit", "Close", "QueryInfo", "InitialValues", "IsOpen"], [3, "Close", "OpenRecord", "CompositionTokenClick", "QueryInfo", "Visible"], [1, "query-info"], [1, "query-name"], [1, "query-category"], [1, "query-actions"], ["title", "Query information", 1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-info-circle"], ["title", "Edit parameters", 1, "btn", "btn-secondary", 3, "disabled"], [1, "execution-stats"], [1, "fa-solid", "fa-folder"], ["title", "Edit parameters", 1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-sliders"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-database", "state-icon"], [1, "state-message"], [1, "fa-solid", "fa-exclamation-triangle", "state-icon", "error"], [1, "fa-solid", "fa-exclamation-circle"], [1, "btn", "btn-secondary", 3, "click"], [3, "PageChange", "EntityLinkClick", "RowDoubleClick", "SelectionChange", "GridStateChange", "RefreshRequest", "QueryInfo", "Data", "TotalRowCount", "PageNumber", "PageSize", "SelectionMode", "ShowToolbar", "VisualConfig", "IsLoading"]], template: function QueryViewerComponent_Template(rf, ctx) { if (rf & 1) {
582
+ } }, inputs: { QueryId: "QueryId", AutoRun: "AutoRun", SelectionMode: "SelectionMode", ShowToolbar: "ShowToolbar", VisualConfig: "VisualConfig", PersistState: "PersistState", PersistParameters: "PersistParameters", PageSize: "PageSize" }, outputs: { EntityLinkClick: "EntityLinkClick", RowDoubleClick: "RowDoubleClick", SelectionChange: "SelectionChange", QueryStart: "QueryStart", QueryComplete: "QueryComplete", QueryError: "QueryError", OpenQueryRecord: "OpenQueryRecord", CompositionTokenClick: "CompositionTokenClick" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 11, consts: [[1, "query-viewer-container"], [1, "query-header"], [1, "query-content"], [1, "no-query-state"], [1, "error-state"], [1, "query-description"], [1, "execution-error"], [3, "QueryInfo", "Data", "ExportDataProvider", "TotalRowCount", "PageNumber", "PageSize", "SelectionMode", "ShowToolbar", "VisualConfig", "IsLoading"], [3, "ParametersSubmit", "Close", "QueryInfo", "InitialValues", "IsOpen"], [3, "Close", "OpenRecord", "CompositionTokenClick", "QueryInfo", "Visible"], [1, "query-info"], [1, "query-name"], [1, "query-category"], [1, "query-actions"], ["title", "Query information", 1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-info-circle"], ["title", "Edit parameters", 1, "btn", "btn-secondary", 3, "disabled"], [1, "execution-stats"], [1, "fa-solid", "fa-folder"], ["title", "Edit parameters", 1, "btn", "btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-sliders"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-database", "state-icon"], [1, "state-message"], [1, "fa-solid", "fa-exclamation-triangle", "state-icon", "error"], [1, "fa-solid", "fa-exclamation-circle"], [1, "btn", "btn-secondary", 3, "click"], [3, "PageChange", "EntityLinkClick", "RowDoubleClick", "SelectionChange", "GridStateChange", "RefreshRequest", "QueryInfo", "Data", "ExportDataProvider", "TotalRowCount", "PageNumber", "PageSize", "SelectionMode", "ShowToolbar", "VisualConfig", "IsLoading"]], template: function QueryViewerComponent_Template(rf, ctx) { if (rf & 1) {
543
583
  i0.ɵɵelementStart(0, "div", 0);
544
584
  i0.ɵɵconditionalCreate(1, QueryViewerComponent_Conditional_1_Template, 11, 5, "div", 1);
545
585
  i0.ɵɵelementStart(2, "div", 2);
@@ -547,7 +587,7 @@ export class QueryViewerComponent extends BaseAngularComponent {
547
587
  i0.ɵɵconditionalCreate(4, QueryViewerComponent_Conditional_4_Template, 4, 1, "div", 4);
548
588
  i0.ɵɵconditionalCreate(5, QueryViewerComponent_Conditional_5_Template, 3, 1, "div", 5);
549
589
  i0.ɵɵconditionalCreate(6, QueryViewerComponent_Conditional_6_Template, 6, 1, "div", 6);
550
- i0.ɵɵconditionalCreate(7, QueryViewerComponent_Conditional_7_Template, 1, 9, "mj-query-data-grid", 7);
590
+ i0.ɵɵconditionalCreate(7, QueryViewerComponent_Conditional_7_Template, 1, 10, "mj-query-data-grid", 7);
551
591
  i0.ɵɵelementEnd();
552
592
  i0.ɵɵelementStart(8, "mj-query-parameter-form", 8);
553
593
  i0.ɵɵlistener("ParametersSubmit", function QueryViewerComponent_Template_mj_query_parameter_form_ParametersSubmit_8_listener($event) { return ctx.OnParametersSubmit($event); })("Close", function QueryViewerComponent_Template_mj_query_parameter_form_Close_8_listener() { return ctx.OnParamsPanelClose(); });
@@ -576,7 +616,7 @@ export class QueryViewerComponent extends BaseAngularComponent {
576
616
  }
577
617
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(QueryViewerComponent, [{
578
618
  type: Component,
579
- args: [{ standalone: false, selector: 'mj-query-viewer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Query Viewer Component -->\n<div class=\"query-viewer-container\">\n <!-- Header bar when query is loaded -->\n @if (QueryInfo) {\n <div class=\"query-header\">\n <div class=\"query-info\">\n <h3 class=\"query-name\">{{ QueryInfo.Name }}</h3>\n @if (QueryInfo.Category) {\n <span class=\"query-category\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ QueryInfo.Category }}\n </span>\n }\n </div>\n <div class=\"query-actions\">\n <!-- Info button -->\n <button (click)=\"OpenInfoPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Query information\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Info\n </button>\n <!-- Parameters button -->\n @if (HasParameters) {\n <button\n (click)=\"OpenParametersPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Edit parameters\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </button>\n }\n <!-- Execution stats -->\n @if (ExecutionTimeMs !== null) {\n <span class=\"execution-stats\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ ExecutionTimeMs }}ms\n </span>\n }\n </div>\n </div>\n }\n\n <!-- Main content area -->\n <div class=\"query-content\">\n <!-- No query selected state -->\n @if (!QueryId) {\n <div class=\"no-query-state\">\n <i class=\"fa-solid fa-database state-icon\"></i>\n <p class=\"state-message\">Select a query to view results</p>\n </div>\n }\n\n <!-- Query not found error -->\n @if (QueryId && !QueryInfo && LastError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle state-icon error\"></i>\n <p class=\"state-message\">{{ LastError }}</p>\n </div>\n }\n\n <!-- Query description -->\n @if (QueryInfo?.Description && !HasRun) {\n <div class=\"query-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ QueryInfo?.Description }}\n </div>\n }\n\n <!-- Query execution error -->\n @if (LastError && HasRun) {\n <div class=\"execution-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ LastError }}</span>\n <button class=\"btn btn-secondary\" (click)=\"Refresh()\">Try Again</button>\n </div>\n }\n\n <!-- Grid -->\n @if (QueryInfo) {\n <mj-query-data-grid\n [QueryInfo]=\"QueryInfo\"\n [Data]=\"QueryData\"\n [TotalRowCount]=\"QueryTotalRowCount\"\n [PageNumber]=\"CurrentPageNumber\"\n [PageSize]=\"PageSize\"\n [SelectionMode]=\"SelectionMode\"\n [ShowToolbar]=\"ShowToolbar\"\n [VisualConfig]=\"VisualConfig\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"OnPageChange($event)\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (RowDoubleClick)=\"OnRowDoubleClick($event)\"\n (SelectionChange)=\"OnSelectionChange($event)\"\n (GridStateChange)=\"OnGridStateChange($event)\"\n (RefreshRequest)=\"OnRefreshRequest()\">\n </mj-query-data-grid>\n }\n </div>\n\n <!-- Parameter form panel -->\n <mj-query-parameter-form\n [QueryInfo]=\"QueryInfo\"\n [InitialValues]=\"SavedParams\"\n [IsOpen]=\"ShowParamsPanel\"\n (ParametersSubmit)=\"OnParametersSubmit($event)\"\n (Close)=\"OnParamsPanelClose()\">\n </mj-query-parameter-form>\n\n <!-- Query info panel -->\n <mj-query-info-panel\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowInfoPanel\"\n (Close)=\"CloseInfoPanel()\"\n (OpenRecord)=\"OnOpenQueryRecord($event)\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-query-info-panel>\n</div>\n", styles: ["/* Query Viewer Component Styles */\n\n:host {\n display: block;\n height: 100%;\n}\n\n.query-viewer-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n position: relative;\n overflow: hidden;\n}\n\n/* Header */\n.query-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.query-info {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.query-name {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.query-category {\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.query-category i {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.query-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-actions button i {\n margin-right: 6px;\n}\n\n.execution-stats {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.execution-stats i {\n font-size: 10px;\n}\n\n/* Content area */\n.query-content {\n flex: 1;\n min-height: 0;\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n/* State displays */\n.no-query-state,\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n}\n\n.state-icon {\n font-size: 64px;\n color: var(--mj-border-strong);\n margin-bottom: 20px;\n}\n\n.state-icon.error {\n color: var(--mj-status-error);\n}\n\n.state-message {\n font-size: 16px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* Query description */\n.query-description {\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.query-description i {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Execution error */\n.execution-error {\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-error i {\n flex-shrink: 0;\n}\n\n.execution-error span {\n flex: 1;\n}\n\n/* Grid takes remaining space */\nmj-query-data-grid {\n flex: 1;\n min-height: 0;\n}\n\n/* Buttons */\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid transparent;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn i {\n font-size: 11px;\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .query-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .query-actions {\n width: 100%;\n justify-content: flex-end;\n }\n}\n"] }]
619
+ args: [{ standalone: false, selector: 'mj-query-viewer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Query Viewer Component -->\n<div class=\"query-viewer-container\">\n <!-- Header bar when query is loaded -->\n @if (QueryInfo) {\n <div class=\"query-header\">\n <div class=\"query-info\">\n <h3 class=\"query-name\">{{ QueryInfo.Name }}</h3>\n @if (QueryInfo.Category) {\n <span class=\"query-category\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ QueryInfo.Category }}\n </span>\n }\n </div>\n <div class=\"query-actions\">\n <!-- Info button -->\n <button (click)=\"OpenInfoPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Query information\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Info\n </button>\n <!-- Parameters button -->\n @if (HasParameters) {\n <button\n (click)=\"OpenParametersPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Edit parameters\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </button>\n }\n <!-- Execution stats -->\n @if (ExecutionTimeMs !== null) {\n <span class=\"execution-stats\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ ExecutionTimeMs }}ms\n </span>\n }\n </div>\n </div>\n }\n\n <!-- Main content area -->\n <div class=\"query-content\">\n <!-- No query selected state -->\n @if (!QueryId) {\n <div class=\"no-query-state\">\n <i class=\"fa-solid fa-database state-icon\"></i>\n <p class=\"state-message\">Select a query to view results</p>\n </div>\n }\n\n <!-- Query not found error -->\n @if (QueryId && !QueryInfo && LastError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle state-icon error\"></i>\n <p class=\"state-message\">{{ LastError }}</p>\n </div>\n }\n\n <!-- Query description -->\n @if (QueryInfo?.Description && !HasRun) {\n <div class=\"query-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ QueryInfo?.Description }}\n </div>\n }\n\n <!-- Query execution error -->\n @if (LastError && HasRun) {\n <div class=\"execution-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ LastError }}</span>\n <button class=\"btn btn-secondary\" (click)=\"Refresh()\">Try Again</button>\n </div>\n }\n\n <!-- Grid -->\n @if (QueryInfo) {\n <mj-query-data-grid\n [QueryInfo]=\"QueryInfo\"\n [Data]=\"QueryData\"\n [ExportDataProvider]=\"FetchAllRowsForExport\"\n [TotalRowCount]=\"QueryTotalRowCount\"\n [PageNumber]=\"CurrentPageNumber\"\n [PageSize]=\"PageSize\"\n [SelectionMode]=\"SelectionMode\"\n [ShowToolbar]=\"ShowToolbar\"\n [VisualConfig]=\"VisualConfig\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"OnPageChange($event)\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (RowDoubleClick)=\"OnRowDoubleClick($event)\"\n (SelectionChange)=\"OnSelectionChange($event)\"\n (GridStateChange)=\"OnGridStateChange($event)\"\n (RefreshRequest)=\"OnRefreshRequest()\">\n </mj-query-data-grid>\n }\n </div>\n\n <!-- Parameter form panel -->\n <mj-query-parameter-form\n [QueryInfo]=\"QueryInfo\"\n [InitialValues]=\"SavedParams\"\n [IsOpen]=\"ShowParamsPanel\"\n (ParametersSubmit)=\"OnParametersSubmit($event)\"\n (Close)=\"OnParamsPanelClose()\">\n </mj-query-parameter-form>\n\n <!-- Query info panel -->\n <mj-query-info-panel\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowInfoPanel\"\n (Close)=\"CloseInfoPanel()\"\n (OpenRecord)=\"OnOpenQueryRecord($event)\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-query-info-panel>\n</div>\n", styles: ["/* Query Viewer Component Styles */\n\n:host {\n display: block;\n height: 100%;\n}\n\n.query-viewer-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface);\n position: relative;\n overflow: hidden;\n}\n\n/* Header */\n.query-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.query-info {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.query-name {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.query-category {\n font-size: 12px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.query-category i {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.query-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.query-actions button i {\n margin-right: 6px;\n}\n\n.execution-stats {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.execution-stats i {\n font-size: 10px;\n}\n\n/* Content area */\n.query-content {\n flex: 1;\n min-height: 0;\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n/* State displays */\n.no-query-state,\n.error-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 40px;\n text-align: center;\n}\n\n.state-icon {\n font-size: 64px;\n color: var(--mj-border-strong);\n margin-bottom: 20px;\n}\n\n.state-icon.error {\n color: var(--mj-status-error);\n}\n\n.state-message {\n font-size: 16px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* Query description */\n.query-description {\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n}\n\n.query-description i {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Execution error */\n.execution-error {\n padding: 12px 16px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.execution-error i {\n flex-shrink: 0;\n}\n\n.execution-error span {\n flex: 1;\n}\n\n/* Grid takes remaining space */\nmj-query-data-grid {\n flex: 1;\n min-height: 0;\n}\n\n/* Buttons */\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 500;\n border: 1px solid transparent;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.btn i {\n font-size: 11px;\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .query-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .query-actions {\n width: 100%;\n justify-content: flex-end;\n }\n}\n"] }]
580
620
  }], () => [{ type: i0.ChangeDetectorRef }], { QueryId: [{
581
621
  type: Input
582
622
  }], AutoRun: [{
@@ -1 +1 @@
1
- {"version":3,"file":"query-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/query-viewer/query-viewer.component.ts","../../../src/lib/query-viewer/query-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ViewChild\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { RunQuery, RunQueryParams, RunQueryResult } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MJQueryEntityExtended, QueryEngine } from '@memberjunction/core-entities';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CompositionTokenClickEvent } from '@memberjunction/ng-code-editor';\nimport { QueryDataGridComponent } from '../query-data-grid/query-data-grid.component';\nimport {\n QueryGridSelectionMode,\n QueryGridState,\n QueryGridVisualConfig,\n QueryParameterValues,\n QueryEntityLinkClickEvent,\n QueryGridStateChangedEvent,\n QuerySelectionChangedEvent,\n QueryRowClickEvent,\n getQueryGridStateKey,\n getQueryParamsKey\n} from '../query-data-grid/models/query-grid-types';\n\n/**\n * A composite component that provides a complete query viewing experience.\n * Features:\n * - Automatic parameter form display when query has parameters\n * - Grid state persistence to User Settings\n * - Parameter persistence to User Settings\n * - Entity linking for clickable record IDs\n * - Auto-run capability when all required params have saved values\n *\n * @example\n * ```html\n * <mj-query-viewer\n * [QueryId]=\"selectedQueryId\"\n * [AutoRun]=\"true\"\n * (EntityLinkClick)=\"openRecord($event)\">\n * </mj-query-viewer>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-query-viewer',\n templateUrl: './query-viewer.component.html',\n styleUrls: ['./query-viewer.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class QueryViewerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n // ========================================\n // Inputs\n // ========================================\n\n private _queryId: string | null = null;\n /**\n * The ID of the query to display\n */\n @Input()\n set QueryId(value: string | null) {\n const previous = this._queryId;\n this._queryId = value;\n if (value !== previous) {\n this.onQueryIdChanged();\n }\n }\n get QueryId(): string | null {\n return this._queryId;\n }\n\n /**\n * Whether to auto-run the query when all required params have saved values\n */\n @Input() AutoRun: boolean = true;\n\n /**\n * Selection mode for the grid\n */\n @Input() SelectionMode: QueryGridSelectionMode = 'single';\n\n /**\n * Whether to show the toolbar\n */\n @Input() ShowToolbar: boolean = true;\n\n /**\n * Visual configuration for the grid\n */\n @Input() VisualConfig: QueryGridVisualConfig = {};\n\n /**\n * Whether to persist grid state\n */\n @Input() PersistState: boolean = true;\n\n /**\n * Whether to persist parameter values\n */\n @Input() PersistParameters: boolean = true;\n\n /**\n * Number of rows per page for server-side paging.\n * Set to 0 to disable paging and load all rows at once.\n */\n @Input() PageSize: number = 100;\n\n // ========================================\n // Outputs\n // ========================================\n\n /**\n * Fired when an entity link is clicked in the grid\n */\n @Output() EntityLinkClick = new EventEmitter<QueryEntityLinkClickEvent>();\n\n /**\n * Fired when a row is double-clicked\n */\n @Output() RowDoubleClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when selection changes\n */\n @Output() SelectionChange = new EventEmitter<QuerySelectionChangedEvent>();\n\n /**\n * Fired when query execution starts\n */\n @Output() QueryStart = new EventEmitter<void>();\n\n /**\n * Fired when query execution completes\n */\n @Output() QueryComplete = new EventEmitter<RunQueryResult>();\n\n /**\n * Fired when query execution fails\n */\n @Output() QueryError = new EventEmitter<Error>();\n\n /**\n * Fired when user wants to open the full query record\n */\n @Output() OpenQueryRecord = new EventEmitter<{ queryId: string; queryName: string }>();\n\n /**\n * Fired when a composition token ({{query:\"...\"}}) is clicked in the SQL info panel\n */\n @Output() CompositionTokenClick = new EventEmitter<CompositionTokenClickEvent>();\n\n // ========================================\n // View Children\n // ========================================\n\n @ViewChild(QueryDataGridComponent) DataGrid!: QueryDataGridComponent;\n\n // ========================================\n // Internal State\n // ========================================\n\n public QueryInfo: MJQueryEntityExtended | null = null;\n public QueryData: Record<string, unknown>[] = [];\n public IsLoading: boolean = false;\n public ShowParamsPanel: boolean = false;\n public ShowInfoPanel: boolean = false;\n public HasRun: boolean = false;\n public LastError: string | null = null;\n public ExecutionTimeMs: number | null = null;\n\n public SavedGridState: QueryGridState | null = null;\n public SavedParams: QueryParameterValues = {};\n\n /** Paging state */\n public QueryTotalRowCount: number = 0;\n public CurrentPageNumber: number = 1;\n\n private destroy$ = new Subject<void>();\n private userInfoEngine = UserInfoEngine.Instance;\n\n constructor(private cdr: ChangeDetectorRef) { super(); }\n\n ngOnInit(): void {}\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Query Loading\n // ========================================\n\n private async onQueryIdChanged(): Promise<void> {\n // Reset state\n this.QueryInfo = null;\n this.QueryData = [];\n this.HasRun = false;\n this.LastError = null;\n this.ExecutionTimeMs = null;\n this.SavedGridState = null;\n this.SavedParams = {};\n this.ShowParamsPanel = false;\n this.QueryTotalRowCount = 0;\n this.CurrentPageNumber = 1;\n this.cdr.markForCheck();\n\n if (!this._queryId) {\n return;\n }\n\n // Load query info from metadata\n this.QueryInfo = QueryEngine.Instance.Queries.find(q => UUIDsEqual(q.ID, this._queryId)) || null;\n\n if (!this.QueryInfo) {\n this.LastError = `Query with ID ${this._queryId} not found`;\n this.cdr.markForCheck();\n return;\n }\n\n // Load saved state from User Settings\n await this.loadSavedState();\n\n // Determine if we should show params or auto-run\n const hasParams = this.QueryInfo.QueryParameters && this.QueryInfo.QueryParameters.length > 0;\n const hasRequiredParams = hasParams && this.QueryInfo.QueryParameters.some(p => p.IsRequired);\n\n if (hasParams) {\n // Check if all required params have saved values\n const canAutoRun = this.AutoRun && this.canAutoRunWithSavedParams();\n\n if (canAutoRun) {\n // Auto-run with saved parameters\n await this.RunQuery(this.SavedParams);\n } else {\n // Show parameter panel\n this.ShowParamsPanel = true;\n }\n } else {\n // No parameters - auto-run immediately\n await this.RunQuery({});\n }\n\n this.cdr.markForCheck();\n }\n\n private canAutoRunWithSavedParams(): boolean {\n if (!this.QueryInfo) return false;\n\n const requiredParams = this.QueryInfo.QueryParameters?.filter(p => p.IsRequired) || [];\n\n for (const param of requiredParams) {\n const savedValue = this.SavedParams[param.Name];\n if (savedValue === null || savedValue === undefined || savedValue === '') {\n return false;\n }\n if (param.Type === 'array' && Array.isArray(savedValue) && savedValue.length === 0) {\n return false;\n }\n }\n\n return true;\n }\n\n // ========================================\n // State Persistence\n // ========================================\n\n private async loadSavedState(): Promise<void> {\n if (!this._queryId) return;\n\n try {\n // Load grid state\n if (this.PersistState) {\n const gridStateKey = getQueryGridStateKey(this._queryId);\n const gridStateSetting = await this.getUserSetting(gridStateKey);\n if (gridStateSetting) {\n this.SavedGridState = JSON.parse(gridStateSetting) as QueryGridState;\n }\n }\n\n // Load saved parameters\n if (this.PersistParameters) {\n const paramsKey = getQueryParamsKey(this._queryId);\n const paramsSetting = await this.getUserSetting(paramsKey);\n if (paramsSetting) {\n this.SavedParams = JSON.parse(paramsSetting) as QueryParameterValues;\n }\n }\n } catch (error) {\n console.warn('Error loading saved query state:', error);\n }\n }\n\n private async saveGridState(state: QueryGridState): Promise<void> {\n if (!this._queryId || !this.PersistState) return;\n\n try {\n const key = getQueryGridStateKey(this._queryId);\n await this.setUserSetting(key, JSON.stringify(state));\n } catch (error) {\n console.warn('Error saving grid state:', error);\n }\n }\n\n private async saveParameters(params: QueryParameterValues): Promise<void> {\n if (!this._queryId || !this.PersistParameters) return;\n\n try {\n const key = getQueryParamsKey(this._queryId);\n await this.setUserSetting(key, JSON.stringify(params));\n } catch (error) {\n console.warn('Error saving parameters:', error);\n }\n }\n\n private async getUserSetting(key: string): Promise<string | undefined> {\n return this.userInfoEngine.GetSetting(key);\n }\n\n private async setUserSetting(key: string, value: string): Promise<void> {\n await this.userInfoEngine.SetSetting(key, value);\n }\n\n // ========================================\n // Query Execution\n // ========================================\n\n public async RunQuery(params: QueryParameterValues, pageNumber: number = 1): Promise<void> {\n if (!this.QueryInfo || !this._queryId) return;\n\n // Normalize array parameters: saved state or callers may pass arrays\n // with JSON fragment strings (e.g. ['[\"A\"', '\"B\"]']) from the old\n // comma-split bug. Re-join and re-parse to clean them up.\n const normalizedParams = this.normalizeArrayParams(params);\n\n this.IsLoading = true;\n this.LastError = null;\n this.QueryStart.emit();\n this.cdr.markForCheck();\n\n // Save normalized parameters for next time\n this.SavedParams = normalizedParams;\n await this.saveParameters(normalizedParams);\n\n const startTime = performance.now();\n\n try {\n const runQuery = new RunQuery();\n const runParams: RunQueryParams = {\n QueryID: this._queryId,\n Parameters: normalizedParams as Record<string, unknown>\n };\n\n // Add server-side paging when PageSize > 0\n if (this.PageSize > 0) {\n runParams.MaxRows = this.PageSize;\n runParams.StartRow = (pageNumber - 1) * this.PageSize;\n }\n\n const result = await runQuery.RunQuery(runParams);\n\n this.ExecutionTimeMs = Math.round(performance.now() - startTime);\n\n if (result.Success) {\n this.QueryData = result.Results || [];\n this.HasRun = true;\n this.ShowParamsPanel = false;\n\n // Update paging state from result\n this.QueryTotalRowCount = result.TotalRowCount;\n this.CurrentPageNumber = result.PageNumber ?? pageNumber;\n\n this.QueryComplete.emit(result);\n } else {\n this.LastError = result.ErrorMessage || 'Query execution failed';\n this.QueryError.emit(new Error(this.LastError));\n MJNotificationService.Instance.CreateSimpleNotification(\n this.LastError,\n 'error',\n 5000\n );\n }\n } catch (error) {\n this.ExecutionTimeMs = Math.round(performance.now() - startTime);\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.LastError = errorMessage;\n this.QueryError.emit(error instanceof Error ? error : new Error(errorMessage));\n MJNotificationService.Instance.CreateSimpleNotification(\n `Error running query: ${errorMessage}`,\n 'error',\n 5000\n );\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n // ========================================\n // Event Handlers\n // ========================================\n\n public OnParametersSubmit(params: QueryParameterValues): void {\n this.RunQuery(params);\n }\n\n public OnParamsPanelClose(): void {\n this.ShowParamsPanel = false;\n this.cdr.markForCheck();\n }\n\n public OnGridStateChange(event: QueryGridStateChangedEvent): void {\n this.saveGridState(event.state);\n }\n\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n this.EntityLinkClick.emit(event);\n }\n\n public OnRowDoubleClick(event: QueryRowClickEvent): void {\n this.RowDoubleClick.emit(event);\n }\n\n public OnSelectionChange(event: QuerySelectionChangedEvent): void {\n this.SelectionChange.emit(event);\n }\n\n public OnPageChange(event: PageChangeEvent): void {\n this.RunQuery(this.SavedParams, event.PageNumber);\n }\n\n public OnRefreshRequest(): void {\n if (this.HasRun) {\n this.RunQuery(this.SavedParams, this.CurrentPageNumber);\n } else if (this.QueryInfo?.QueryParameters?.length) {\n this.ShowParamsPanel = true;\n this.cdr.markForCheck();\n } else {\n this.RunQuery({});\n }\n }\n\n // ========================================\n // Public API\n // ========================================\n\n public OpenParametersPanel(): void {\n this.ShowParamsPanel = true;\n this.cdr.markForCheck();\n }\n\n public OpenInfoPanel(): void {\n this.ShowInfoPanel = true;\n this.cdr.markForCheck();\n }\n\n public CloseInfoPanel(): void {\n this.ShowInfoPanel = false;\n this.cdr.markForCheck();\n }\n\n public OnOpenQueryRecord(event: { queryId: string; queryName: string }): void {\n this.OpenQueryRecord.emit(event);\n }\n\n public OnCompositionTokenClick(event: CompositionTokenClickEvent): void {\n this.CompositionTokenClick.emit(event);\n }\n\n public Refresh(): void {\n this.OnRefreshRequest();\n }\n\n public get HasParameters(): boolean {\n return (this.QueryInfo?.QueryParameters?.length || 0) > 0;\n }\n\n /**\n * Normalizes array-typed parameters. Handles the case where saved state\n * contains JSON fragment arrays (e.g. `['[\"A\"', '\"B\"]']`) from the old\n * comma-split bug. Joins the fragments back into a string, detects JSON\n * array syntax, and parses cleanly.\n */\n private normalizeArrayParams(params: QueryParameterValues): QueryParameterValues {\n if (!this.QueryInfo?.QueryParameters?.length) return params;\n\n const result = { ...params };\n for (const paramDef of this.QueryInfo.QueryParameters) {\n if (paramDef.Type !== 'array' || !(paramDef.Name in result)) continue;\n\n const value = result[paramDef.Name];\n if (!Array.isArray(value) || value.length === 0) continue;\n\n // Check if the array looks like it was produced by naive comma-splitting\n // of a JSON array string (fragments contain brackets or quotes)\n const joined = value.join(', ');\n const trimmed = joined.trim();\n if (trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n result[paramDef.Name] = parsed.map((v: unknown) => String(v).trim()).filter((s: string) => s);\n continue;\n }\n } catch {\n // Not valid JSON after joining — leave as-is\n }\n }\n }\n return result;\n }\n}\n","<!-- Query Viewer Component -->\n<div class=\"query-viewer-container\">\n <!-- Header bar when query is loaded -->\n @if (QueryInfo) {\n <div class=\"query-header\">\n <div class=\"query-info\">\n <h3 class=\"query-name\">{{ QueryInfo.Name }}</h3>\n @if (QueryInfo.Category) {\n <span class=\"query-category\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ QueryInfo.Category }}\n </span>\n }\n </div>\n <div class=\"query-actions\">\n <!-- Info button -->\n <button (click)=\"OpenInfoPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Query information\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Info\n </button>\n <!-- Parameters button -->\n @if (HasParameters) {\n <button\n (click)=\"OpenParametersPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Edit parameters\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </button>\n }\n <!-- Execution stats -->\n @if (ExecutionTimeMs !== null) {\n <span class=\"execution-stats\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ ExecutionTimeMs }}ms\n </span>\n }\n </div>\n </div>\n }\n\n <!-- Main content area -->\n <div class=\"query-content\">\n <!-- No query selected state -->\n @if (!QueryId) {\n <div class=\"no-query-state\">\n <i class=\"fa-solid fa-database state-icon\"></i>\n <p class=\"state-message\">Select a query to view results</p>\n </div>\n }\n\n <!-- Query not found error -->\n @if (QueryId && !QueryInfo && LastError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle state-icon error\"></i>\n <p class=\"state-message\">{{ LastError }}</p>\n </div>\n }\n\n <!-- Query description -->\n @if (QueryInfo?.Description && !HasRun) {\n <div class=\"query-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ QueryInfo?.Description }}\n </div>\n }\n\n <!-- Query execution error -->\n @if (LastError && HasRun) {\n <div class=\"execution-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ LastError }}</span>\n <button class=\"btn btn-secondary\" (click)=\"Refresh()\">Try Again</button>\n </div>\n }\n\n <!-- Grid -->\n @if (QueryInfo) {\n <mj-query-data-grid\n [QueryInfo]=\"QueryInfo\"\n [Data]=\"QueryData\"\n [TotalRowCount]=\"QueryTotalRowCount\"\n [PageNumber]=\"CurrentPageNumber\"\n [PageSize]=\"PageSize\"\n [SelectionMode]=\"SelectionMode\"\n [ShowToolbar]=\"ShowToolbar\"\n [VisualConfig]=\"VisualConfig\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"OnPageChange($event)\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (RowDoubleClick)=\"OnRowDoubleClick($event)\"\n (SelectionChange)=\"OnSelectionChange($event)\"\n (GridStateChange)=\"OnGridStateChange($event)\"\n (RefreshRequest)=\"OnRefreshRequest()\">\n </mj-query-data-grid>\n }\n </div>\n\n <!-- Parameter form panel -->\n <mj-query-parameter-form\n [QueryInfo]=\"QueryInfo\"\n [InitialValues]=\"SavedParams\"\n [IsOpen]=\"ShowParamsPanel\"\n (ParametersSubmit)=\"OnParametersSubmit($event)\"\n (Close)=\"OnParamsPanelClose()\">\n </mj-query-parameter-form>\n\n <!-- Query info panel -->\n <mj-query-info-panel\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowInfoPanel\"\n (Close)=\"CloseInfoPanel()\"\n (OpenRecord)=\"OnOpenQueryRecord($event)\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-query-info-panel>\n</div>\n"]}
1
+ {"version":3,"file":"query-viewer.component.js","sourceRoot":"","sources":["../../../src/lib/query-viewer/query-viewer.component.ts","../../../src/lib/query-viewer/query-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n ViewChild\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { RunQuery, RunQueryParams, RunQueryResult } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MJQueryEntityExtended, QueryEngine } from '@memberjunction/core-entities';\nimport { PageChangeEvent } from '@memberjunction/ng-pagination';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { CompositionTokenClickEvent } from '@memberjunction/ng-code-editor';\nimport { QueryDataGridComponent } from '../query-data-grid/query-data-grid.component';\nimport {\n QueryGridSelectionMode,\n QueryGridState,\n QueryGridVisualConfig,\n QueryParameterValues,\n QueryEntityLinkClickEvent,\n QueryGridStateChangedEvent,\n QuerySelectionChangedEvent,\n QueryRowClickEvent,\n getQueryGridStateKey,\n getQueryParamsKey\n} from '../query-data-grid/models/query-grid-types';\n\n/**\n * A composite component that provides a complete query viewing experience.\n * Features:\n * - Automatic parameter form display when query has parameters\n * - Grid state persistence to User Settings\n * - Parameter persistence to User Settings\n * - Entity linking for clickable record IDs\n * - Auto-run capability when all required params have saved values\n *\n * @example\n * ```html\n * <mj-query-viewer\n * [QueryId]=\"selectedQueryId\"\n * [AutoRun]=\"true\"\n * (EntityLinkClick)=\"openRecord($event)\">\n * </mj-query-viewer>\n * ```\n */\n@Component({\n standalone: false,\n selector: 'mj-query-viewer',\n templateUrl: './query-viewer.component.html',\n styleUrls: ['./query-viewer.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class QueryViewerComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /**\n * Safety cap for the export path — deliberately large (exports should cover the full result set)\n * but bounded to protect the browser from an unbounded query. Kept in lockstep with the\n * entity-viewer's EXPORT_MAX_RECORDS so Export behaves the same across Queries and Data Explorer.\n */\n private static readonly EXPORT_MAX_RECORDS = 100000;\n\n // ========================================\n // Inputs\n // ========================================\n\n private _queryId: string | null = null;\n /**\n * The ID of the query to display\n */\n @Input()\n set QueryId(value: string | null) {\n const previous = this._queryId;\n this._queryId = value;\n if (value !== previous) {\n this.onQueryIdChanged();\n }\n }\n get QueryId(): string | null {\n return this._queryId;\n }\n\n /**\n * Whether to auto-run the query when all required params have saved values\n */\n @Input() AutoRun: boolean = true;\n\n /**\n * Selection mode for the grid\n */\n @Input() SelectionMode: QueryGridSelectionMode = 'single';\n\n /**\n * Whether to show the toolbar\n */\n @Input() ShowToolbar: boolean = true;\n\n /**\n * Visual configuration for the grid\n */\n @Input() VisualConfig: QueryGridVisualConfig = {};\n\n /**\n * Whether to persist grid state\n */\n @Input() PersistState: boolean = true;\n\n /**\n * Whether to persist parameter values\n */\n @Input() PersistParameters: boolean = true;\n\n /**\n * Number of rows per page for server-side paging.\n * Set to 0 to disable paging and load all rows at once.\n */\n @Input() PageSize: number = 100;\n\n // ========================================\n // Outputs\n // ========================================\n\n /**\n * Fired when an entity link is clicked in the grid\n */\n @Output() EntityLinkClick = new EventEmitter<QueryEntityLinkClickEvent>();\n\n /**\n * Fired when a row is double-clicked\n */\n @Output() RowDoubleClick = new EventEmitter<QueryRowClickEvent>();\n\n /**\n * Fired when selection changes\n */\n @Output() SelectionChange = new EventEmitter<QuerySelectionChangedEvent>();\n\n /**\n * Fired when query execution starts\n */\n @Output() QueryStart = new EventEmitter<void>();\n\n /**\n * Fired when query execution completes\n */\n @Output() QueryComplete = new EventEmitter<RunQueryResult>();\n\n /**\n * Fired when query execution fails\n */\n @Output() QueryError = new EventEmitter<Error>();\n\n /**\n * Fired when user wants to open the full query record\n */\n @Output() OpenQueryRecord = new EventEmitter<{ queryId: string; queryName: string }>();\n\n /**\n * Fired when a composition token ({{query:\"...\"}}) is clicked in the SQL info panel\n */\n @Output() CompositionTokenClick = new EventEmitter<CompositionTokenClickEvent>();\n\n // ========================================\n // View Children\n // ========================================\n\n @ViewChild(QueryDataGridComponent) DataGrid!: QueryDataGridComponent;\n\n // ========================================\n // Internal State\n // ========================================\n\n public QueryInfo: MJQueryEntityExtended | null = null;\n public QueryData: Record<string, unknown>[] = [];\n public IsLoading: boolean = false;\n public ShowParamsPanel: boolean = false;\n public ShowInfoPanel: boolean = false;\n public HasRun: boolean = false;\n public LastError: string | null = null;\n public ExecutionTimeMs: number | null = null;\n\n public SavedGridState: QueryGridState | null = null;\n public SavedParams: QueryParameterValues = {};\n\n /** Paging state */\n public QueryTotalRowCount: number = 0;\n public CurrentPageNumber: number = 1;\n\n private destroy$ = new Subject<void>();\n private userInfoEngine = UserInfoEngine.Instance;\n\n constructor(private cdr: ChangeDetectorRef) { super(); }\n\n ngOnInit(): void {}\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ========================================\n // Query Loading\n // ========================================\n\n private async onQueryIdChanged(): Promise<void> {\n // Reset state\n this.QueryInfo = null;\n this.QueryData = [];\n this.HasRun = false;\n this.LastError = null;\n this.ExecutionTimeMs = null;\n this.SavedGridState = null;\n this.SavedParams = {};\n this.ShowParamsPanel = false;\n this.QueryTotalRowCount = 0;\n this.CurrentPageNumber = 1;\n this.cdr.markForCheck();\n\n if (!this._queryId) {\n return;\n }\n\n // Load query info from metadata\n this.QueryInfo = QueryEngine.Instance.Queries.find(q => UUIDsEqual(q.ID, this._queryId)) || null;\n\n if (!this.QueryInfo) {\n this.LastError = `Query with ID ${this._queryId} not found`;\n this.cdr.markForCheck();\n return;\n }\n\n // Load saved state from User Settings\n await this.loadSavedState();\n\n // Determine if we should show params or auto-run\n const hasParams = this.QueryInfo.QueryParameters && this.QueryInfo.QueryParameters.length > 0;\n const hasRequiredParams = hasParams && this.QueryInfo.QueryParameters.some(p => p.IsRequired);\n\n if (hasParams) {\n // Check if all required params have saved values\n const canAutoRun = this.AutoRun && this.canAutoRunWithSavedParams();\n\n if (canAutoRun) {\n // Auto-run with saved parameters\n await this.RunQuery(this.SavedParams);\n } else {\n // Show parameter panel\n this.ShowParamsPanel = true;\n }\n } else {\n // No parameters - auto-run immediately\n await this.RunQuery({});\n }\n\n this.cdr.markForCheck();\n }\n\n private canAutoRunWithSavedParams(): boolean {\n if (!this.QueryInfo) return false;\n\n const requiredParams = this.QueryInfo.QueryParameters?.filter(p => p.IsRequired) || [];\n\n for (const param of requiredParams) {\n const savedValue = this.SavedParams[param.Name];\n if (savedValue === null || savedValue === undefined || savedValue === '') {\n return false;\n }\n if (param.Type === 'array' && Array.isArray(savedValue) && savedValue.length === 0) {\n return false;\n }\n }\n\n return true;\n }\n\n // ========================================\n // State Persistence\n // ========================================\n\n private async loadSavedState(): Promise<void> {\n if (!this._queryId) return;\n\n try {\n // Load grid state\n if (this.PersistState) {\n const gridStateKey = getQueryGridStateKey(this._queryId);\n const gridStateSetting = await this.getUserSetting(gridStateKey);\n if (gridStateSetting) {\n this.SavedGridState = JSON.parse(gridStateSetting) as QueryGridState;\n }\n }\n\n // Load saved parameters\n if (this.PersistParameters) {\n const paramsKey = getQueryParamsKey(this._queryId);\n const paramsSetting = await this.getUserSetting(paramsKey);\n if (paramsSetting) {\n this.SavedParams = JSON.parse(paramsSetting) as QueryParameterValues;\n }\n }\n } catch (error) {\n console.warn('Error loading saved query state:', error);\n }\n }\n\n private async saveGridState(state: QueryGridState): Promise<void> {\n if (!this._queryId || !this.PersistState) return;\n\n try {\n const key = getQueryGridStateKey(this._queryId);\n await this.setUserSetting(key, JSON.stringify(state));\n } catch (error) {\n console.warn('Error saving grid state:', error);\n }\n }\n\n private async saveParameters(params: QueryParameterValues): Promise<void> {\n if (!this._queryId || !this.PersistParameters) return;\n\n try {\n const key = getQueryParamsKey(this._queryId);\n await this.setUserSetting(key, JSON.stringify(params));\n } catch (error) {\n console.warn('Error saving parameters:', error);\n }\n }\n\n private async getUserSetting(key: string): Promise<string | undefined> {\n return this.userInfoEngine.GetSetting(key);\n }\n\n private async setUserSetting(key: string, value: string): Promise<void> {\n await this.userInfoEngine.SetSetting(key, value);\n }\n\n // ========================================\n // Query Execution\n // ========================================\n\n public async RunQuery(params: QueryParameterValues, pageNumber: number = 1): Promise<void> {\n if (!this.QueryInfo || !this._queryId) return;\n\n // Normalize array parameters: saved state or callers may pass arrays\n // with JSON fragment strings (e.g. ['[\"A\"', '\"B\"]']) from the old\n // comma-split bug. Re-join and re-parse to clean them up.\n const normalizedParams = this.normalizeArrayParams(params);\n\n this.IsLoading = true;\n this.LastError = null;\n this.QueryStart.emit();\n this.cdr.markForCheck();\n\n // Save normalized parameters for next time\n this.SavedParams = normalizedParams;\n await this.saveParameters(normalizedParams);\n\n const startTime = performance.now();\n\n try {\n const runQuery = new RunQuery();\n const runParams: RunQueryParams = {\n QueryID: this._queryId,\n Parameters: normalizedParams as Record<string, unknown>\n };\n\n // Add server-side paging when PageSize > 0\n if (this.PageSize > 0) {\n runParams.MaxRows = this.PageSize;\n runParams.StartRow = (pageNumber - 1) * this.PageSize;\n }\n\n const result = await runQuery.RunQuery(runParams);\n\n this.ExecutionTimeMs = Math.round(performance.now() - startTime);\n\n if (result.Success) {\n this.QueryData = result.Results || [];\n this.HasRun = true;\n this.ShowParamsPanel = false;\n\n // Update paging state from result\n this.QueryTotalRowCount = result.TotalRowCount;\n this.CurrentPageNumber = result.PageNumber ?? pageNumber;\n\n this.QueryComplete.emit(result);\n } else {\n this.LastError = result.ErrorMessage || 'Query execution failed';\n this.QueryError.emit(new Error(this.LastError));\n MJNotificationService.Instance.CreateSimpleNotification(\n this.LastError,\n 'error',\n 5000\n );\n }\n } catch (error) {\n this.ExecutionTimeMs = Math.round(performance.now() - startTime);\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.LastError = errorMessage;\n this.QueryError.emit(error instanceof Error ? error : new Error(errorMessage));\n MJNotificationService.Instance.CreateSimpleNotification(\n `Error running query: ${errorMessage}`,\n 'error',\n 5000\n );\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Fetches the FULL result set for the current query, used by the grid's export flow so exports\n * aren't capped at the on-screen page (bug B3). Bound as an arrow property so it can be passed to\n * the grid's ExportDataProvider input without losing `this`. Loads up to {@link EXPORT_MAX_RECORDS}\n * (kept in lockstep with the entity-viewer's export cap) and warns — rather than silently\n * truncating — when the query returns more. Uses the provider-scoped RunQuery so it targets the\n * correct server in multi-provider setups. Falls back to the currently-loaded page on failure.\n */\n public FetchAllRowsForExport = async (): Promise<Record<string, unknown>[]> => {\n if (!this._queryId) {\n return this.QueryData;\n }\n try {\n // MaxRows caps the pull to protect the browser from an unbounded query; StartRow 0 = from\n // the top. This is a much larger window than the on-screen page, so export covers the set.\n const result = await this.RunQueryToUse.RunQuery({\n QueryID: this._queryId,\n Parameters: this.SavedParams as Record<string, unknown>,\n MaxRows: QueryViewerComponent.EXPORT_MAX_RECORDS,\n StartRow: 0\n });\n if (result.Success) {\n if (result.TotalRowCount > QueryViewerComponent.EXPORT_MAX_RECORDS) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `This export is limited to the first ${QueryViewerComponent.EXPORT_MAX_RECORDS.toLocaleString()} of ` +\n `${result.TotalRowCount.toLocaleString()} rows. Refine the query to include the rest.`,\n 'warning',\n 6000\n );\n }\n return result.Results || [];\n }\n } catch {\n // Fall through to the loaded page.\n }\n return this.QueryData;\n };\n\n // ========================================\n // Event Handlers\n // ========================================\n\n public OnParametersSubmit(params: QueryParameterValues): void {\n this.RunQuery(params);\n }\n\n public OnParamsPanelClose(): void {\n this.ShowParamsPanel = false;\n this.cdr.markForCheck();\n }\n\n public OnGridStateChange(event: QueryGridStateChangedEvent): void {\n this.saveGridState(event.state);\n }\n\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n this.EntityLinkClick.emit(event);\n }\n\n public OnRowDoubleClick(event: QueryRowClickEvent): void {\n this.RowDoubleClick.emit(event);\n }\n\n public OnSelectionChange(event: QuerySelectionChangedEvent): void {\n this.SelectionChange.emit(event);\n }\n\n public OnPageChange(event: PageChangeEvent): void {\n this.RunQuery(this.SavedParams, event.PageNumber);\n }\n\n public OnRefreshRequest(): void {\n if (this.HasRun) {\n this.RunQuery(this.SavedParams, this.CurrentPageNumber);\n } else if (this.QueryInfo?.QueryParameters?.length) {\n this.ShowParamsPanel = true;\n this.cdr.markForCheck();\n } else {\n this.RunQuery({});\n }\n }\n\n // ========================================\n // Public API\n // ========================================\n\n public OpenParametersPanel(): void {\n this.ShowParamsPanel = true;\n this.cdr.markForCheck();\n }\n\n public OpenInfoPanel(): void {\n this.ShowInfoPanel = true;\n this.cdr.markForCheck();\n }\n\n public CloseInfoPanel(): void {\n this.ShowInfoPanel = false;\n this.cdr.markForCheck();\n }\n\n public OnOpenQueryRecord(event: { queryId: string; queryName: string }): void {\n this.OpenQueryRecord.emit(event);\n }\n\n public OnCompositionTokenClick(event: CompositionTokenClickEvent): void {\n this.CompositionTokenClick.emit(event);\n }\n\n public Refresh(): void {\n this.OnRefreshRequest();\n }\n\n public get HasParameters(): boolean {\n return (this.QueryInfo?.QueryParameters?.length || 0) > 0;\n }\n\n /**\n * Normalizes array-typed parameters. Handles the case where saved state\n * contains JSON fragment arrays (e.g. `['[\"A\"', '\"B\"]']`) from the old\n * comma-split bug. Joins the fragments back into a string, detects JSON\n * array syntax, and parses cleanly.\n */\n private normalizeArrayParams(params: QueryParameterValues): QueryParameterValues {\n if (!this.QueryInfo?.QueryParameters?.length) return params;\n\n const result = { ...params };\n for (const paramDef of this.QueryInfo.QueryParameters) {\n if (paramDef.Type !== 'array' || !(paramDef.Name in result)) continue;\n\n const value = result[paramDef.Name];\n if (!Array.isArray(value) || value.length === 0) continue;\n\n // Check if the array looks like it was produced by naive comma-splitting\n // of a JSON array string (fragments contain brackets or quotes)\n const joined = value.join(', ');\n const trimmed = joined.trim();\n if (trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n result[paramDef.Name] = parsed.map((v: unknown) => String(v).trim()).filter((s: string) => s);\n continue;\n }\n } catch {\n // Not valid JSON after joining — leave as-is\n }\n }\n }\n return result;\n }\n}\n","<!-- Query Viewer Component -->\n<div class=\"query-viewer-container\">\n <!-- Header bar when query is loaded -->\n @if (QueryInfo) {\n <div class=\"query-header\">\n <div class=\"query-info\">\n <h3 class=\"query-name\">{{ QueryInfo.Name }}</h3>\n @if (QueryInfo.Category) {\n <span class=\"query-category\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ QueryInfo.Category }}\n </span>\n }\n </div>\n <div class=\"query-actions\">\n <!-- Info button -->\n <button (click)=\"OpenInfoPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Query information\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Info\n </button>\n <!-- Parameters button -->\n @if (HasParameters) {\n <button\n (click)=\"OpenParametersPanel()\"\n [disabled]=\"IsLoading\"\n class=\"btn btn-secondary\"\n title=\"Edit parameters\">\n <i class=\"fa-solid fa-sliders\"></i>\n Parameters\n </button>\n }\n <!-- Execution stats -->\n @if (ExecutionTimeMs !== null) {\n <span class=\"execution-stats\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ ExecutionTimeMs }}ms\n </span>\n }\n </div>\n </div>\n }\n\n <!-- Main content area -->\n <div class=\"query-content\">\n <!-- No query selected state -->\n @if (!QueryId) {\n <div class=\"no-query-state\">\n <i class=\"fa-solid fa-database state-icon\"></i>\n <p class=\"state-message\">Select a query to view results</p>\n </div>\n }\n\n <!-- Query not found error -->\n @if (QueryId && !QueryInfo && LastError) {\n <div class=\"error-state\">\n <i class=\"fa-solid fa-exclamation-triangle state-icon error\"></i>\n <p class=\"state-message\">{{ LastError }}</p>\n </div>\n }\n\n <!-- Query description -->\n @if (QueryInfo?.Description && !HasRun) {\n <div class=\"query-description\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ QueryInfo?.Description }}\n </div>\n }\n\n <!-- Query execution error -->\n @if (LastError && HasRun) {\n <div class=\"execution-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ LastError }}</span>\n <button class=\"btn btn-secondary\" (click)=\"Refresh()\">Try Again</button>\n </div>\n }\n\n <!-- Grid -->\n @if (QueryInfo) {\n <mj-query-data-grid\n [QueryInfo]=\"QueryInfo\"\n [Data]=\"QueryData\"\n [ExportDataProvider]=\"FetchAllRowsForExport\"\n [TotalRowCount]=\"QueryTotalRowCount\"\n [PageNumber]=\"CurrentPageNumber\"\n [PageSize]=\"PageSize\"\n [SelectionMode]=\"SelectionMode\"\n [ShowToolbar]=\"ShowToolbar\"\n [VisualConfig]=\"VisualConfig\"\n [IsLoading]=\"IsLoading\"\n (PageChange)=\"OnPageChange($event)\"\n (EntityLinkClick)=\"OnEntityLinkClick($event)\"\n (RowDoubleClick)=\"OnRowDoubleClick($event)\"\n (SelectionChange)=\"OnSelectionChange($event)\"\n (GridStateChange)=\"OnGridStateChange($event)\"\n (RefreshRequest)=\"OnRefreshRequest()\">\n </mj-query-data-grid>\n }\n </div>\n\n <!-- Parameter form panel -->\n <mj-query-parameter-form\n [QueryInfo]=\"QueryInfo\"\n [InitialValues]=\"SavedParams\"\n [IsOpen]=\"ShowParamsPanel\"\n (ParametersSubmit)=\"OnParametersSubmit($event)\"\n (Close)=\"OnParamsPanelClose()\">\n </mj-query-parameter-form>\n\n <!-- Query info panel -->\n <mj-query-info-panel\n [QueryInfo]=\"QueryInfo\"\n [Visible]=\"ShowInfoPanel\"\n (Close)=\"CloseInfoPanel()\"\n (OpenRecord)=\"OnOpenQueryRecord($event)\"\n (CompositionTokenClick)=\"OnCompositionTokenClick($event)\">\n </mj-query-info-panel>\n</div>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-query-viewer",
3
- "version": "5.49.0",
3
+ "version": "5.51.0",
4
4
  "description": "MemberJunction: Angular components for viewing and executing stored queries with parameter input, interactive results grid, and entity linking",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -26,7 +26,7 @@
26
26
  "devDependencies": {
27
27
  "@angular/compiler": "21.1.3",
28
28
  "@angular/compiler-cli": "21.1.3",
29
- "@memberjunction/ng-test-utils": "5.49.0",
29
+ "@memberjunction/ng-test-utils": "5.51.0",
30
30
  "vitest": "^4.0.18"
31
31
  },
32
32
  "peerDependencies": {
@@ -38,18 +38,18 @@
38
38
  "ag-grid-community": "^35.0.1"
39
39
  },
40
40
  "dependencies": {
41
- "@memberjunction/ng-ui-components": "5.49.0",
42
- "@memberjunction/core-entities": "5.49.0",
43
- "@memberjunction/export-engine": "5.49.0",
44
- "@memberjunction/global": "5.49.0",
45
- "@memberjunction/core": "5.49.0",
46
- "@memberjunction/ng-base-types": "5.49.0",
47
- "@memberjunction/ng-pagination": "5.49.0",
48
- "@memberjunction/ng-shared-generic": "5.49.0",
49
- "@memberjunction/ng-export-service": "5.49.0",
50
- "@memberjunction/ng-markdown": "5.49.0",
51
- "@memberjunction/ng-code-editor": "5.49.0",
52
- "@memberjunction/ng-notifications": "5.49.0",
41
+ "@memberjunction/ng-ui-components": "5.51.0",
42
+ "@memberjunction/core-entities": "5.51.0",
43
+ "@memberjunction/export-engine": "5.51.0",
44
+ "@memberjunction/global": "5.51.0",
45
+ "@memberjunction/core": "5.51.0",
46
+ "@memberjunction/ng-base-types": "5.51.0",
47
+ "@memberjunction/ng-pagination": "5.51.0",
48
+ "@memberjunction/ng-shared-generic": "5.51.0",
49
+ "@memberjunction/ng-export-service": "5.51.0",
50
+ "@memberjunction/ng-markdown": "5.51.0",
51
+ "@memberjunction/ng-code-editor": "5.51.0",
52
+ "@memberjunction/ng-notifications": "5.51.0",
53
53
  "rxjs": "^7.8.2",
54
54
  "tslib": "^2.8.1"
55
55
  },