@finos/legend-query-builder 4.14.19 → 4.14.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. package/lib/components/QueryLoader.d.ts.map +1 -1
  2. package/lib/components/QueryLoader.js +85 -36
  3. package/lib/components/QueryLoader.js.map +1 -1
  4. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  5. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  6. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  7. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +3 -2
  8. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  9. package/lib/index.css +1 -17
  10. package/lib/index.css.map +1 -1
  11. package/lib/package.json +1 -1
  12. package/lib/stores/QueryBuilderResultState.d.ts +7 -4
  13. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  14. package/lib/stores/QueryBuilderResultState.js +20 -4
  15. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  16. package/lib/stores/QueryBuilderState.d.ts +4 -2
  17. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  18. package/lib/stores/QueryBuilderState.js +13 -2
  19. package/lib/stores/QueryBuilderState.js.map +1 -1
  20. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +19 -1
  21. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  22. package/lib/stores/QueryLoaderState.d.ts +14 -4
  23. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  24. package/lib/stores/QueryLoaderState.js +35 -5
  25. package/lib/stores/QueryLoaderState.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/components/QueryLoader.tsx +279 -127
  28. package/src/components/result/QueryBuilderResultPanel.tsx +0 -1
  29. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +3 -2
  30. package/src/stores/QueryBuilderResultState.ts +27 -7
  31. package/src/stores/QueryBuilderState.ts +19 -2
  32. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +30 -1
  33. package/src/stores/QueryLoaderState.ts +64 -12
@@ -99,7 +99,7 @@ const getLocalColDefs = (
99
99
  enableValue: true,
100
100
  ...getAggregationTDSColumnCustomizations(executionResult, colName),
101
101
  } as DataGridColumnDefinition;
102
- const persistedColumn = resultState.gridConfig.columns.find(
102
+ const persistedColumn = resultState.gridConfig?.columns.find(
103
103
  (c) => c.colId === colName,
104
104
  );
105
105
  if (persistedColumn) {
@@ -240,6 +240,7 @@ export const QueryBuilderTDSGridResult = observer(
240
240
  resultState.setGridConfig({
241
241
  columns: columnAPi.getColumnState(),
242
242
  isPivotModeEnabled: columnAPi.isPivotMode(),
243
+ isLocalModeEnabled: true,
243
244
  });
244
245
  };
245
246
 
@@ -351,7 +352,7 @@ export const QueryBuilderTDSGridResult = observer(
351
352
  onGridReady={(params): void => {
352
353
  setColumnApi(params.columnApi);
353
354
  params.columnApi.setPivotMode(
354
- resultState.gridConfig.isPivotModeEnabled,
355
+ Boolean(resultState.gridConfig?.isPivotModeEnabled),
355
356
  );
356
357
  }}
357
358
  gridOptions={{
@@ -31,6 +31,7 @@ import {
31
31
  type ExecutionResult,
32
32
  type RawLambda,
33
33
  type EXECUTION_SERIALIZATION_FORMAT,
34
+ type QueryGridConfig,
34
35
  GRAPH_MANAGER_EVENT,
35
36
  buildRawLambdaFromLambdaFunction,
36
37
  reportGraphAnalytics,
@@ -79,7 +80,8 @@ export interface QueryBuilderTDSResultCellCoordinate {
79
80
 
80
81
  type QueryBuilderDataGridConfig = {
81
82
  columns: DataGridColumnState[];
82
- isPivotModeEnabled: boolean;
83
+ isPivotModeEnabled: boolean | undefined;
84
+ isLocalModeEnabled: boolean | undefined;
83
85
  };
84
86
 
85
87
  export class QueryBuilderResultState {
@@ -101,7 +103,7 @@ export class QueryBuilderResultState {
101
103
  mousedOverCell: QueryBuilderTDSResultCellData | null = null;
102
104
  isSelectingCells: boolean;
103
105
 
104
- gridConfig!: QueryBuilderDataGridConfig;
106
+ gridConfig: QueryBuilderDataGridConfig | undefined;
105
107
 
106
108
  constructor(queryBuilderState: QueryBuilderState) {
107
109
  makeObservable(this, {
@@ -128,6 +130,7 @@ export class QueryBuilderResultState {
128
130
  setMouseOverCell: action,
129
131
  setQueryRunPromise: action,
130
132
  setIsQueryUsageViewerOpened: action,
133
+ handlePreConfiguredGridConfig: action,
131
134
  exportData: flow,
132
135
  runQuery: flow,
133
136
  cancelQuery: flow,
@@ -136,10 +139,7 @@ export class QueryBuilderResultState {
136
139
  this.isSelectingCells = false;
137
140
 
138
141
  this.selectedCells = [];
139
- this.gridConfig = {
140
- columns: [],
141
- isPivotModeEnabled: false,
142
- };
142
+ this.gridConfig = undefined;
143
143
  this.queryBuilderState = queryBuilderState;
144
144
  this.executionPlanState = new ExecutionPlanState(
145
145
  this.queryBuilderState.applicationStore,
@@ -147,7 +147,7 @@ export class QueryBuilderResultState {
147
147
  );
148
148
  }
149
149
 
150
- setGridConfig(val: QueryBuilderDataGridConfig): void {
150
+ setGridConfig(val: QueryBuilderDataGridConfig | undefined): void {
151
151
  this.gridConfig = val;
152
152
  }
153
153
 
@@ -191,6 +191,26 @@ export class QueryBuilderResultState {
191
191
  this.isQueryUsageViewerOpened = val;
192
192
  }
193
193
 
194
+ handlePreConfiguredGridConfig(config: QueryGridConfig): void {
195
+ const newConfig = {
196
+ columns: config.columns as DataGridColumnState[],
197
+ isPivotModeEnabled: Boolean(config.isPivotModeEnabled),
198
+ isLocalModeEnabled: Boolean(config.isLocalModeEnabled),
199
+ };
200
+ this.setGridConfig(newConfig);
201
+ }
202
+
203
+ getQueryGridConfig(): QueryGridConfig | undefined {
204
+ if (this.gridConfig) {
205
+ return {
206
+ columns: this.gridConfig.columns as object[],
207
+ isPivotModeEnabled: Boolean(this.gridConfig.isPivotModeEnabled),
208
+ isLocalModeEnabled: Boolean(this.gridConfig.isLocalModeEnabled),
209
+ };
210
+ }
211
+ return undefined;
212
+ }
213
+
194
214
  get checkForStaleResults(): boolean {
195
215
  if (this.latestRunHashCode !== this.queryBuilderState.hashCode) {
196
216
  return true;
@@ -53,6 +53,7 @@ import {
53
53
  type GraphManagerState,
54
54
  type ValueSpecification,
55
55
  type Type,
56
+ type QueryGridConfig,
56
57
  GRAPH_MANAGER_EVENT,
57
58
  CompilationError,
58
59
  extractSourceInformationCoordinates,
@@ -393,7 +394,10 @@ export abstract class QueryBuilderState implements CommandRegistrar {
393
394
  );
394
395
  }
395
396
 
396
- resetQueryResult(options?: { preserveResult?: boolean | undefined }): void {
397
+ resetQueryResult(options?: {
398
+ preserveResult?: boolean | undefined;
399
+ gridConfig?: QueryGridConfig | undefined;
400
+ }): void {
397
401
  const resultState = new QueryBuilderResultState(this);
398
402
  resultState.setPreviewLimit(this.resultState.previewLimit);
399
403
  if (options?.preserveResult) {
@@ -401,6 +405,10 @@ export abstract class QueryBuilderState implements CommandRegistrar {
401
405
  resultState.setExecutionDuration(this.resultState.executionDuration);
402
406
  resultState.latestRunHashCode = this.resultState.latestRunHashCode;
403
407
  }
408
+ if (options?.gridConfig) {
409
+ this.isLocalModeEnabled = true;
410
+ resultState.handlePreConfiguredGridConfig(options.gridConfig);
411
+ }
404
412
  this.resultState = resultState;
405
413
  }
406
414
 
@@ -476,6 +484,14 @@ export abstract class QueryBuilderState implements CommandRegistrar {
476
484
  return undefined;
477
485
  }
478
486
 
487
+ getGridConfig(): QueryGridConfig | undefined {
488
+ // for now we will only save in local mode
489
+ if (this.isLocalModeEnabled && this.resultState.gridConfig) {
490
+ return this.resultState.getQueryGridConfig();
491
+ }
492
+ return undefined;
493
+ }
494
+
479
495
  buildQuery(options?: { keepSourceInformation: boolean }): RawLambda {
480
496
  if (!this.isQuerySupported) {
481
497
  const parameters = this.parametersState.parameterStates.map((e) =>
@@ -552,11 +568,12 @@ export abstract class QueryBuilderState implements CommandRegistrar {
552
568
  initializeWithQuery(
553
569
  query: RawLambda,
554
570
  defaultParameterValues?: Map<string, ValueSpecification>,
571
+ gridConfig?: QueryGridConfig,
555
572
  ): void {
556
573
  this.rebuildWithQuery(query, {
557
574
  defaultParameterValues,
558
575
  });
559
- this.resetQueryResult();
576
+ this.resetQueryResult({ gridConfig });
560
577
  this.changeDetectionState.initialize(query);
561
578
  this.changeHistoryState.initialize(query);
562
579
  }
@@ -16,12 +16,29 @@
16
16
 
17
17
  import type { LegendApplicationPlugin } from '@finos/legend-application';
18
18
  import type { QueryBuilderState } from './QueryBuilderState.js';
19
- import type { QuerySearchSpecification } from '@finos/legend-graph';
19
+ import type { QuerySearchSpecification, RawLambda } from '@finos/legend-graph';
20
20
  import type {
21
21
  DataAccessState,
22
22
  DatasetAccessInfo,
23
23
  } from './data-access/DataAccessState.js';
24
24
 
25
+ export type CuratedTemplateQuery = {
26
+ title: string;
27
+ description: string | undefined;
28
+ query: RawLambda;
29
+ executionContextKey: string;
30
+ };
31
+
32
+ export type CuratedTemplateQuerySpecification = {
33
+ getCuratedTemplateQueries(
34
+ queryBuilderState: QueryBuilderState,
35
+ ): CuratedTemplateQuery[];
36
+ loadCuratedTemplateQuery(
37
+ templateQuery: CuratedTemplateQuery,
38
+ queryBuilderState: QueryBuilderState,
39
+ ): void;
40
+ };
41
+
25
42
  export type LoadQueryFilterOption = {
26
43
  key: string;
27
44
  label: (queryBuilderState: QueryBuilderState) => string | undefined;
@@ -59,11 +76,23 @@ export type TemplateQueryPanelContentRenderer = (
59
76
 
60
77
  export interface QueryBuilder_LegendApplicationPlugin_Extension
61
78
  extends LegendApplicationPlugin {
79
+ /**
80
+ * Get the list of template query specifications
81
+ */
82
+ getCuratedTemplateQuerySpecifications?(): CuratedTemplateQuerySpecification[];
83
+
62
84
  /**
63
85
  * Get the list of filter options for query loader.
64
86
  */
65
87
  getExtraLoadQueryFilterOptions?(): LoadQueryFilterOption[];
66
88
 
89
+ /**
90
+ * Get the list of filter options related to template query
91
+ */
92
+ getQueryFilterOptionsRelatedToTemplateQuery?(): (
93
+ queryBuilderState: QueryBuilderState,
94
+ ) => string[];
95
+
67
96
  /**
68
97
  * Get the list of warehouse entitlement configurations
69
98
  */
@@ -19,12 +19,13 @@ import {
19
19
  type GenericLegendApplicationStore,
20
20
  } from '@finos/legend-application';
21
21
  import {
22
- type LightQuery,
23
22
  QuerySearchSpecification,
23
+ GRAPH_MANAGER_EVENT,
24
24
  type QueryInfo,
25
+ type LightQuery,
25
26
  type BasicGraphManagerState,
26
27
  type Query,
27
- GRAPH_MANAGER_EVENT,
28
+ type RawLambda,
28
29
  } from '@finos/legend-graph';
29
30
  import {
30
31
  ActionState,
@@ -36,6 +37,7 @@ import {
36
37
  import { makeObservable, observable, action, flow } from 'mobx';
37
38
  import type { QueryBuilderState } from './QueryBuilderState.js';
38
39
  import type {
40
+ CuratedTemplateQuerySpecification,
39
41
  LoadQueryFilterOption,
40
42
  QueryBuilder_LegendApplicationPlugin_Extension,
41
43
  } from './QueryBuilder_LegendApplicationPlugin_Extension.js';
@@ -72,12 +74,15 @@ export class QueryLoaderState {
72
74
  showCurrentUserQueriesOnly = false; // TODO: if we start having more native filters, we should make them part of `extraFilters`
73
75
  extraFilters = new Map<string, boolean>();
74
76
  extraFilterOptions: LoadQueryFilterOption[] = [];
77
+ extraQueryFilterOptionsRelatedToTemplateQuery: string[] = [];
75
78
  queries: LightQuery[] = [];
79
+ curatedTemplateQuerySepcifications: CuratedTemplateQuerySpecification[] = [];
76
80
 
77
81
  isQueryLoaderDialogOpen = false;
82
+ isCuratedTemplateToggled = false;
78
83
  showingDefaultQueries = true;
79
84
  showPreviewViewer = false;
80
- queryPreviewContent?: QueryInfo;
85
+ queryPreviewContent?: QueryInfo | { name: string; content: string };
81
86
 
82
87
  constructor(
83
88
  applicationStore: GenericLegendApplicationStore,
@@ -107,11 +112,14 @@ export class QueryLoaderState {
107
112
  showCurrentUserQueriesOnly: observable,
108
113
  showPreviewViewer: observable,
109
114
  searchText: observable,
115
+ isCuratedTemplateToggled: observable,
116
+ curatedTemplateQuerySepcifications: observable,
110
117
  setSearchText: action,
111
118
  setQueryLoaderDialogOpen: action,
112
119
  setQueries: action,
113
120
  setShowCurrentUserQueriesOnly: action,
114
121
  setShowPreviewViewer: action,
122
+ setIsCuratedTemplateToggled: action,
115
123
  searchQueries: flow,
116
124
  getPreviewQueryContent: flow,
117
125
  deleteQuery: flow,
@@ -134,6 +142,10 @@ export class QueryLoaderState {
134
142
  options.handleFetchDefaultQueriesFailure;
135
143
  }
136
144
 
145
+ setIsCuratedTemplateToggled(val: boolean): void {
146
+ this.isCuratedTemplateToggled = val;
147
+ }
148
+
137
149
  setSearchText(val: string): void {
138
150
  this.searchText = val;
139
151
  }
@@ -156,6 +168,7 @@ export class QueryLoaderState {
156
168
 
157
169
  reset(): void {
158
170
  this.setShowCurrentUserQueriesOnly(false);
171
+ this.setIsCuratedTemplateToggled(false);
159
172
  }
160
173
 
161
174
  *initialize(queryBuilderState: QueryBuilderState): GeneratorFn<void> {
@@ -168,12 +181,32 @@ export class QueryLoaderState {
168
181
  plugin as QueryBuilder_LegendApplicationPlugin_Extension
169
182
  ).getExtraLoadQueryFilterOptions?.() ?? [],
170
183
  );
184
+ this.extraQueryFilterOptionsRelatedToTemplateQuery =
185
+ this.applicationStore.pluginManager
186
+ .getApplicationPlugins()
187
+ .flatMap(
188
+ (plugin) =>
189
+ (plugin as QueryBuilder_LegendApplicationPlugin_Extension)
190
+ .getQueryFilterOptionsRelatedToTemplateQuery?.()(
191
+ guaranteeNonNullable(this.queryBuilderState),
192
+ )
193
+ .flat() ?? [],
194
+ );
171
195
  const extraFilters = this.extraFilterOptions.map((filterOption) =>
172
196
  filterOption.label(guaranteeNonNullable(this.queryBuilderState)),
173
197
  );
174
198
  extraFilters.forEach(
175
199
  (filter) => filter && this.extraFilters.set(filter, false),
176
200
  );
201
+ this.curatedTemplateQuerySepcifications =
202
+ this.applicationStore.pluginManager
203
+ .getApplicationPlugins()
204
+ .flatMap(
205
+ (plugin) =>
206
+ (
207
+ plugin as QueryBuilder_LegendApplicationPlugin_Extension
208
+ ).getCuratedTemplateQuerySpecifications?.() ?? [],
209
+ );
177
210
  }
178
211
 
179
212
  *searchQueries(searchText: string): GeneratorFn<void> {
@@ -287,17 +320,36 @@ export class QueryLoaderState {
287
320
  }
288
321
  }
289
322
 
290
- *getPreviewQueryContent(queryId: string): GeneratorFn<void> {
323
+ *getPreviewQueryContent(
324
+ queryId: string | undefined,
325
+ template?: {
326
+ queryName: string;
327
+ queryContent: RawLambda;
328
+ },
329
+ ): GeneratorFn<void> {
291
330
  this.previewQueryState.inProgress();
292
331
  try {
293
- const queryInfo = (yield this.graphManagerState.graphManager.getQueryInfo(
294
- queryId,
295
- )) as QueryInfo;
296
- this.queryPreviewContent = queryInfo;
297
- this.queryPreviewContent.content =
298
- (yield this.graphManagerState.graphManager.prettyLambdaContent(
299
- queryInfo.content,
300
- )) as string;
332
+ if (queryId) {
333
+ const queryInfo =
334
+ (yield this.graphManagerState.graphManager.getQueryInfo(
335
+ queryId,
336
+ )) as QueryInfo;
337
+ this.queryPreviewContent = queryInfo;
338
+ this.queryPreviewContent.content =
339
+ (yield this.graphManagerState.graphManager.prettyLambdaContent(
340
+ queryInfo.content,
341
+ )) as string;
342
+ } else if (template) {
343
+ this.queryPreviewContent = {
344
+ name: template.queryName,
345
+ content: '',
346
+ } as QueryInfo;
347
+ this.queryPreviewContent.content =
348
+ (yield this.graphManagerState.graphManager.lambdaToPureCode(
349
+ template.queryContent,
350
+ true,
351
+ )) as string;
352
+ }
301
353
  this.previewQueryState.pass();
302
354
  } catch (error) {
303
355
  assertErrorThrown(error);