@finos/legend-query-builder 4.14.18 → 4.14.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/lib/components/QueryBuilder.d.ts.map +1 -1
  2. package/lib/components/QueryBuilder.js +5 -3
  3. package/lib/components/QueryBuilder.js.map +1 -1
  4. package/lib/components/QueryBuilderConstantExpressionPanel.d.ts.map +1 -1
  5. package/lib/components/QueryBuilderConstantExpressionPanel.js +71 -45
  6. package/lib/components/QueryBuilderConstantExpressionPanel.js.map +1 -1
  7. package/lib/components/QueryBuilderDiffPanel.d.ts.map +1 -1
  8. package/lib/components/QueryBuilderDiffPanel.js +2 -1
  9. package/lib/components/QueryBuilderDiffPanel.js.map +1 -1
  10. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  11. package/lib/components/QueryBuilderParametersPanel.js +25 -26
  12. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  13. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +11 -2
  14. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  15. package/lib/components/QueryBuilderPropertyExpressionEditor.js +35 -10
  16. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  17. package/lib/components/QueryBuilderSideBar.d.ts.map +1 -1
  18. package/lib/components/QueryBuilderSideBar.js +6 -1
  19. package/lib/components/QueryBuilderSideBar.js.map +1 -1
  20. package/lib/components/QueryBuilderTextEditor.d.ts.map +1 -1
  21. package/lib/components/QueryBuilderTextEditor.js +3 -3
  22. package/lib/components/QueryBuilderTextEditor.js.map +1 -1
  23. package/lib/components/QueryLoader.d.ts.map +1 -1
  24. package/lib/components/QueryLoader.js +90 -39
  25. package/lib/components/QueryLoader.js.map +1 -1
  26. package/lib/components/QueryUsageViewer.d.ts.map +1 -1
  27. package/lib/components/QueryUsageViewer.js +2 -2
  28. package/lib/components/QueryUsageViewer.js.map +1 -1
  29. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +2 -0
  30. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
  31. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +19 -2
  32. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  33. package/lib/components/data-access/DataAccessOverview.d.ts.map +1 -1
  34. package/lib/components/data-access/DataAccessOverview.js +6 -1
  35. package/lib/components/data-access/DataAccessOverview.js.map +1 -1
  36. package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
  37. package/lib/components/execution-plan/ExecutionPlanViewer.js +6 -6
  38. package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
  39. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  40. package/lib/components/explorer/QueryBuilderExplorerPanel.js +3 -2
  41. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  42. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  43. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +3 -2
  44. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  45. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
  46. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js +6 -3
  47. package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js.map +1 -1
  48. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  49. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +4 -3
  50. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  51. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  52. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +11 -22
  53. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  54. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  55. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +2 -2
  56. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  57. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  58. package/lib/components/result/QueryBuilderResultPanel.js +2 -1
  59. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  60. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  61. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +5 -1
  62. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  63. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  64. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +11 -2
  65. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  66. package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -1
  67. package/lib/components/shared/BasicValueSpecificationEditor.js +25 -22
  68. package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -1
  69. package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
  70. package/lib/components/shared/CustomDatePicker.js +8 -5
  71. package/lib/components/shared/CustomDatePicker.js.map +1 -1
  72. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  73. package/lib/components/shared/LambdaEditor.js +17 -3
  74. package/lib/components/shared/LambdaEditor.js.map +1 -1
  75. package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -1
  76. package/lib/components/shared/LambdaParameterValuesEditor.js +2 -2
  77. package/lib/components/shared/LambdaParameterValuesEditor.js.map +1 -1
  78. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts +6 -0
  79. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
  80. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +40 -3
  81. package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js.map +1 -1
  82. package/lib/components/watermark/QueryBuilderWatermark.d.ts.map +1 -1
  83. package/lib/components/watermark/QueryBuilderWatermark.js +28 -12
  84. package/lib/components/watermark/QueryBuilderWatermark.js.map +1 -1
  85. package/lib/index.css +17 -1
  86. package/lib/index.css.map +1 -1
  87. package/lib/package.json +1 -1
  88. package/lib/stores/QueryBuilderConstantsState.d.ts +1 -0
  89. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  90. package/lib/stores/QueryBuilderConstantsState.js +7 -1
  91. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  92. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +24 -1
  93. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  94. package/lib/stores/QueryLoaderState.d.ts +14 -4
  95. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  96. package/lib/stores/QueryLoaderState.js +35 -5
  97. package/lib/stores/QueryLoaderState.js.map +1 -1
  98. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts +1 -2
  99. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -1
  100. package/lib/stores/watermark/QueryBuilderWatermarkState.js +2 -12
  101. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -1
  102. package/package.json +8 -8
  103. package/src/components/QueryBuilder.tsx +14 -2
  104. package/src/components/QueryBuilderConstantExpressionPanel.tsx +145 -69
  105. package/src/components/QueryBuilderDiffPanel.tsx +10 -2
  106. package/src/components/QueryBuilderParametersPanel.tsx +42 -37
  107. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +87 -24
  108. package/src/components/QueryBuilderSideBar.tsx +20 -0
  109. package/src/components/QueryBuilderTextEditor.tsx +6 -4
  110. package/src/components/QueryLoader.tsx +291 -130
  111. package/src/components/QueryUsageViewer.tsx +7 -1
  112. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +40 -4
  113. package/src/components/data-access/DataAccessOverview.tsx +9 -1
  114. package/src/components/execution-plan/ExecutionPlanViewer.tsx +11 -8
  115. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +5 -2
  116. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +5 -2
  117. package/src/components/fetch-structure/QueryBuilderGraphFetchTreePanel.tsx +12 -5
  118. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +8 -4
  119. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +56 -72
  120. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +8 -2
  121. package/src/components/result/QueryBuilderResultPanel.tsx +8 -1
  122. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +6 -3
  123. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +14 -4
  124. package/src/components/shared/BasicValueSpecificationEditor.tsx +39 -25
  125. package/src/components/shared/CustomDatePicker.tsx +18 -5
  126. package/src/components/shared/LambdaEditor.tsx +27 -11
  127. package/src/components/shared/LambdaParameterValuesEditor.tsx +4 -1
  128. package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +115 -64
  129. package/src/components/watermark/QueryBuilderWatermark.tsx +60 -19
  130. package/src/stores/QueryBuilderConstantsState.ts +12 -0
  131. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +39 -1
  132. package/src/stores/QueryLoaderState.ts +64 -12
  133. package/src/stores/watermark/QueryBuilderWatermarkState.ts +2 -12
@@ -41,11 +41,12 @@ import {
41
41
  ThinChevronRightIcon,
42
42
  InfoCircleIcon,
43
43
  } from '@finos/legend-art';
44
- import type { LightQuery } from '@finos/legend-graph';
44
+ import type { LightQuery, RawLambda } from '@finos/legend-graph';
45
45
  import {
46
46
  debounce,
47
47
  formatDistanceToNow,
48
48
  guaranteeNonNullable,
49
+ isNonNullable,
49
50
  quantifyList,
50
51
  } from '@finos/legend-shared';
51
52
  import { flowResult } from 'mobx';
@@ -59,6 +60,7 @@ import {
59
60
  const QueryPreviewViewer = observer(
60
61
  (props: { queryLoaderState: QueryLoaderState }) => {
61
62
  const { queryLoaderState } = props;
63
+ const applicationStore = queryLoaderState.applicationStore;
62
64
  const close = (): void => {
63
65
  queryLoaderState.setShowPreviewViewer(false);
64
66
  };
@@ -72,7 +74,12 @@ const QueryPreviewViewer = observer(
72
74
  paper: 'editor-modal__content',
73
75
  }}
74
76
  >
75
- <Modal className="editor-modal" darkMode={true}>
77
+ <Modal
78
+ className="editor-modal"
79
+ darkMode={
80
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
81
+ }
82
+ >
76
83
  <ModalHeader
77
84
  title={
78
85
  guaranteeNonNullable(queryLoaderState.queryPreviewContent).name
@@ -89,7 +96,7 @@ const QueryPreviewViewer = observer(
89
96
  />
90
97
  </ModalBody>
91
98
  <ModalFooter>
92
- <ModalFooterButton onClick={close} text="Close" />
99
+ <ModalFooterButton onClick={close} text="Close" type="secondary" />
93
100
  </ModalFooter>
94
101
  </Modal>
95
102
  </Dialog>
@@ -104,6 +111,21 @@ export const QueryLoader = observer(
104
111
  const searchInputRef = useRef<HTMLInputElement>(null);
105
112
  const queryRenameInputRef = useRef<HTMLInputElement>(null);
106
113
  const results = queryLoaderState.queries;
114
+ const curatedTemplateQueries =
115
+ queryLoaderState.curatedTemplateQuerySepcifications
116
+ .map((s) =>
117
+ queryLoaderState.queryBuilderState
118
+ ? s.getCuratedTemplateQueries(queryLoaderState.queryBuilderState)
119
+ : [],
120
+ )
121
+ .flat();
122
+ const loadCuratedTemplateQuery =
123
+ queryLoaderState.curatedTemplateQuerySepcifications
124
+ // already using an arrow function suggested by @typescript-eslint/unbound-method
125
+ // eslint-disable-next-line
126
+ .map((s) => () => s.loadCuratedTemplateQuery)
127
+ .filter(isNonNullable)[0];
128
+
107
129
  const [isMineOnly, setIsMineOnly] = useState(false);
108
130
  const [showQueryNameEditInput, setShowQueryNameEditInput] = useState<
109
131
  number | undefined
@@ -167,7 +189,25 @@ export const QueryLoader = observer(
167
189
  debouncedLoadQueries.cancel();
168
190
  debouncedLoadQueries(queryLoaderState.searchText);
169
191
  };
170
-
192
+ const toggleCuratedTemplate = (): void => {
193
+ Array.from(queryLoaderState.extraFilters).map(([key, value]) =>
194
+ queryLoaderState.extraFilters.set(key, false),
195
+ );
196
+ queryLoaderState.setShowCurrentUserQueriesOnly(false);
197
+ setIsMineOnly(false);
198
+ queryLoaderState.extraQueryFilterOptionsRelatedToTemplateQuery.forEach(
199
+ (op) =>
200
+ queryLoaderState.extraFilters.set(
201
+ op,
202
+ !queryLoaderState.isCuratedTemplateToggled,
203
+ ),
204
+ );
205
+ queryLoaderState.showingDefaultQueries =
206
+ queryLoaderState.isCuratedTemplateToggled;
207
+ queryLoaderState.setIsCuratedTemplateToggled(
208
+ !queryLoaderState.isCuratedTemplateToggled,
209
+ );
210
+ };
171
211
  useEffect(() => {
172
212
  flowResult(queryLoaderState.searchQueries('')).catch(
173
213
  applicationStore.alertUnhandledError,
@@ -201,10 +241,16 @@ export const QueryLoader = observer(
201
241
  }
202
242
  };
203
243
 
204
- const showPreview = (queryId: string): void => {
205
- flowResult(queryLoaderState.getPreviewQueryContent(queryId)).catch(
206
- applicationStore.alertUnhandledError,
207
- );
244
+ const showPreview = (
245
+ queryId: string | undefined,
246
+ template?: {
247
+ queryName: string;
248
+ queryContent: RawLambda;
249
+ },
250
+ ): void => {
251
+ flowResult(
252
+ queryLoaderState.getPreviewQueryContent(queryId, template),
253
+ ).catch(applicationStore.alertUnhandledError);
208
254
  queryLoaderState.setShowPreviewViewer(true);
209
255
  };
210
256
 
@@ -248,6 +294,12 @@ export const QueryLoader = observer(
248
294
  'query-loader__filter__toggler__btn--toggled': isMineOnly,
249
295
  })}
250
296
  onClick={toggleShowCurrentUserQueriesOnly}
297
+ disabled={queryLoaderState.isCuratedTemplateToggled}
298
+ title={
299
+ queryLoaderState.isCuratedTemplateToggled
300
+ ? 'current fitler is disabled when `Curated Template Query` is on'
301
+ : 'click to add filter'
302
+ }
251
303
  tabIndex={-1}
252
304
  >
253
305
  Mine Only
@@ -261,6 +313,12 @@ export const QueryLoader = observer(
261
313
  className={clsx('query-loader__filter__toggler__btn', {
262
314
  'query-loader__filter__toggler__btn--toggled': value,
263
315
  })}
316
+ disabled={queryLoaderState.isCuratedTemplateToggled}
317
+ title={
318
+ queryLoaderState.isCuratedTemplateToggled
319
+ ? 'current fitler is disabled when `Curated Template Query` is on'
320
+ : 'click to add filter'
321
+ }
264
322
  onClick={(): void => toggleExtraFilters(key)}
265
323
  tabIndex={-1}
266
324
  >
@@ -270,6 +328,21 @@ export const QueryLoader = observer(
270
328
  )}
271
329
  </div>
272
330
  )}
331
+ {queryLoaderState.extraQueryFilterOptionsRelatedToTemplateQuery
332
+ .length > 0 && (
333
+ <div className="query-loader__filter__extra__filters">
334
+ <button
335
+ className={clsx('query-loader__filter__toggler__btn', {
336
+ 'query-loader__filter__toggler__btn--toggled':
337
+ queryLoaderState.isCuratedTemplateToggled,
338
+ })}
339
+ onClick={toggleCuratedTemplate}
340
+ tabIndex={-1}
341
+ >
342
+ Curated Template Query
343
+ </button>
344
+ </div>
345
+ )}
273
346
  </div>
274
347
  </div>
275
348
  </div>
@@ -291,7 +364,20 @@ export const QueryLoader = observer(
291
364
  queryLoaderState.generateDefaultQueriesSummaryText?.(
292
365
  results,
293
366
  ) ?? 'Refine your search to get better matches'
294
- ) : results.length >= QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (
367
+ ) : !queryLoaderState.isCuratedTemplateToggled ? (
368
+ results.length >= QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (
369
+ <>
370
+ {`Found ${QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`}{' '}
371
+ <InfoCircleIcon
372
+ title="Some queries are not listed, refine your search to get better matches"
373
+ className="query-loader__results__summary__info"
374
+ />
375
+ </>
376
+ ) : (
377
+ `Found ${quantifyList(results, 'match', 'matches')}`
378
+ )
379
+ ) : curatedTemplateQueries.length >=
380
+ QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (
295
381
  <>
296
382
  {`Found ${QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`}{' '}
297
383
  <InfoCircleIcon
@@ -300,139 +386,211 @@ export const QueryLoader = observer(
300
386
  />
301
387
  </>
302
388
  ) : (
303
- `Found ${quantifyList(results, 'match', 'matches')}`
389
+ `Found ${quantifyList(
390
+ curatedTemplateQueries,
391
+ 'match',
392
+ 'matches',
393
+ )}`
304
394
  )}
305
395
  </div>
306
- {results
307
- .slice(0, QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
308
- .map((query, idx) => (
309
- <div
310
- className="query-loader__result"
311
- title={`Click to ${loadActionLabel}...`}
312
- key={query.id}
313
- onClick={() => queryLoaderState.loadQuery(query)}
314
- >
315
- <div className="query-loader__result__content">
316
- {showQueryNameEditInput === idx ? (
317
- <div className="query-loader__result__title__editor">
318
- <input
319
- className="query-loader__result__title__editor__input input--dark"
320
- spellCheck={false}
321
- ref={queryRenameInputRef}
322
- value={queryNameInputValue}
323
- onChange={changeQueryNameInputValue}
324
- onKeyDown={(event) => {
325
- if (event.code === 'Enter') {
326
- event.stopPropagation();
327
- renameQuery(query)();
328
- } else if (event.code === 'Escape') {
329
- event.stopPropagation();
330
- hideEditQueryNameInput();
331
- }
332
- }}
333
- onBlur={() => hideEditQueryNameInput()}
334
- // avoid clicking on the input causing the call to load query
335
- onClick={(event) => event.stopPropagation()}
336
- />
396
+ {!queryLoaderState.isCuratedTemplateToggled &&
397
+ results
398
+ .slice(0, QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
399
+ .map((query, idx) => (
400
+ <div
401
+ className="query-loader__result"
402
+ title={`Click to ${loadActionLabel}...`}
403
+ key={query.id}
404
+ onClick={() => queryLoaderState.loadQuery(query)}
405
+ >
406
+ <div className="query-loader__result__content">
407
+ {showQueryNameEditInput === idx ? (
408
+ <div className="query-loader__result__title__editor">
409
+ <input
410
+ className="query-loader__result__title__editor__input input--dark"
411
+ spellCheck={false}
412
+ ref={queryRenameInputRef}
413
+ value={queryNameInputValue}
414
+ onChange={changeQueryNameInputValue}
415
+ onKeyDown={(event) => {
416
+ if (event.code === 'Enter') {
417
+ event.stopPropagation();
418
+ renameQuery(query)();
419
+ } else if (event.code === 'Escape') {
420
+ event.stopPropagation();
421
+ hideEditQueryNameInput();
422
+ }
423
+ }}
424
+ onBlur={() => hideEditQueryNameInput()}
425
+ // avoid clicking on the input causing the call to load query
426
+ onClick={(event) => event.stopPropagation()}
427
+ />
428
+ </div>
429
+ ) : (
430
+ <div
431
+ className="query-loader__result__title"
432
+ title={query.name}
433
+ >
434
+ {query.name}
435
+ </div>
436
+ )}
437
+ <div className="query-loader__result__description">
438
+ <div className="query-loader__result__description__date__icon">
439
+ <LastModifiedIcon />
440
+ </div>
441
+ <div className="query-loader__result__description__date">
442
+ {query.lastUpdatedAt
443
+ ? formatDistanceToNow(
444
+ new Date(query.lastUpdatedAt),
445
+ {
446
+ includeSeconds: true,
447
+ addSuffix: true,
448
+ },
449
+ )
450
+ : '(unknown)'}
451
+ </div>
452
+ <div
453
+ className={clsx(
454
+ 'query-loader__result__description__author__icon',
455
+ {
456
+ 'query-loader__result__description__author__icon--owner':
457
+ query.isCurrentUserQuery,
458
+ },
459
+ )}
460
+ >
461
+ <UserIcon />
462
+ </div>
463
+ <div className="query-loader__result__description__author__name">
464
+ {query.isCurrentUserQuery ? (
465
+ <div
466
+ title={query.owner}
467
+ className="query-loader__result__description__owner"
468
+ >
469
+ Me
470
+ </div>
471
+ ) : (
472
+ query.owner
473
+ )}
474
+ </div>
337
475
  </div>
338
- ) : (
476
+ </div>
477
+ <DropdownMenu
478
+ className="query-loader__result__actions-menu"
479
+ title="More Actions..."
480
+ content={
481
+ <MenuContent>
482
+ <MenuContentItem
483
+ onClick={(): void => showPreview(query.id)}
484
+ >
485
+ Show Query Preview
486
+ </MenuContentItem>
487
+ {!queryLoaderState.isReadOnly && (
488
+ <MenuContentItem
489
+ disabled={!query.isCurrentUserQuery}
490
+ onClick={deleteQuery(query)}
491
+ >
492
+ Delete
493
+ </MenuContentItem>
494
+ )}
495
+ {!queryLoaderState.isReadOnly && (
496
+ <MenuContentItem
497
+ disabled={!query.isCurrentUserQuery}
498
+ onClick={showEditQueryNameInput(
499
+ query.name,
500
+ idx,
501
+ )}
502
+ >
503
+ Rename
504
+ </MenuContentItem>
505
+ )}
506
+ </MenuContent>
507
+ }
508
+ menuProps={{
509
+ anchorOrigin: {
510
+ vertical: 'bottom',
511
+ horizontal: 'left',
512
+ },
513
+ transformOrigin: {
514
+ vertical: 'top',
515
+ horizontal: 'left',
516
+ },
517
+ elevation: 7,
518
+ }}
519
+ >
520
+ <MoreVerticalIcon />
521
+ </DropdownMenu>
522
+ <div className="query-loader__result__arrow">
523
+ <ThinChevronRightIcon />
524
+ </div>
525
+ </div>
526
+ ))}
527
+ {queryLoaderState.queryBuilderState &&
528
+ queryLoaderState.isCuratedTemplateToggled &&
529
+ loadCuratedTemplateQuery &&
530
+ curatedTemplateQueries
531
+ .slice(0, QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
532
+ .map((templateQuery, idx) => (
533
+ <div
534
+ className="query-loader__result"
535
+ title={`Click to ${loadActionLabel}...`}
536
+ key={templateQuery.title}
537
+ onClick={() => {
538
+ loadCuratedTemplateQuery()(
539
+ templateQuery,
540
+ guaranteeNonNullable(
541
+ queryLoaderState.queryBuilderState,
542
+ ),
543
+ );
544
+ queryLoaderState.setQueryLoaderDialogOpen(false);
545
+ }}
546
+ >
547
+ <div className="query-loader__result__content">
339
548
  <div
340
549
  className="query-loader__result__title"
341
- title={query.name}
550
+ title={templateQuery.title}
342
551
  >
343
- {query.name}
344
- </div>
345
- )}
346
- <div className="query-loader__result__description">
347
- <div className="query-loader__result__description__date__icon">
348
- <LastModifiedIcon />
349
- </div>
350
- <div className="query-loader__result__description__date">
351
- {query.lastUpdatedAt
352
- ? formatDistanceToNow(
353
- new Date(query.lastUpdatedAt),
354
- {
355
- includeSeconds: true,
356
- addSuffix: true,
357
- },
358
- )
359
- : '(unknown)'}
552
+ {templateQuery.title}
360
553
  </div>
361
- <div
362
- className={clsx(
363
- 'query-loader__result__description__author__icon',
364
- {
365
- 'query-loader__result__description__author__icon--owner':
366
- query.isCurrentUserQuery,
367
- },
368
- )}
369
- >
370
- <UserIcon />
371
- </div>
372
- <div className="query-loader__result__description__author__name">
373
- {query.isCurrentUserQuery ? (
374
- <div
375
- title={query.owner}
376
- className="query-loader__result__description__owner"
377
- >
378
- Me
379
- </div>
380
- ) : (
381
- query.owner
382
- )}
554
+ <div className="query-loader__result__description">
555
+ {templateQuery.description}
383
556
  </div>
384
557
  </div>
385
- </div>
386
- <DropdownMenu
387
- className="query-loader__result__actions-menu"
388
- title="More Actions..."
389
- content={
390
- <MenuContent>
391
- <MenuContentItem
392
- onClick={(): void => showPreview(query.id)}
393
- >
394
- Show Query Preview
395
- </MenuContentItem>
396
- {!queryLoaderState.isReadOnly && (
397
- <MenuContentItem
398
- disabled={!query.isCurrentUserQuery}
399
- onClick={deleteQuery(query)}
400
- >
401
- Delete
402
- </MenuContentItem>
403
- )}
404
- {!queryLoaderState.isReadOnly && (
558
+ <DropdownMenu
559
+ className="query-loader__result__actions-menu"
560
+ title="More Actions..."
561
+ content={
562
+ <MenuContent>
405
563
  <MenuContentItem
406
- disabled={!query.isCurrentUserQuery}
407
- onClick={showEditQueryNameInput(
408
- query.name,
409
- idx,
410
- )}
564
+ onClick={(): void =>
565
+ showPreview(undefined, {
566
+ queryContent: templateQuery.query,
567
+ queryName: templateQuery.title,
568
+ })
569
+ }
411
570
  >
412
- Rename
571
+ Show Query Preview
413
572
  </MenuContentItem>
414
- )}
415
- </MenuContent>
416
- }
417
- menuProps={{
418
- anchorOrigin: {
419
- vertical: 'bottom',
420
- horizontal: 'left',
421
- },
422
- transformOrigin: {
423
- vertical: 'top',
424
- horizontal: 'left',
425
- },
426
- elevation: 7,
427
- }}
428
- >
429
- <MoreVerticalIcon />
430
- </DropdownMenu>
431
- <div className="query-loader__result__arrow">
432
- <ThinChevronRightIcon />
573
+ </MenuContent>
574
+ }
575
+ menuProps={{
576
+ anchorOrigin: {
577
+ vertical: 'bottom',
578
+ horizontal: 'left',
579
+ },
580
+ transformOrigin: {
581
+ vertical: 'top',
582
+ horizontal: 'left',
583
+ },
584
+ elevation: 7,
585
+ }}
586
+ >
587
+ <MoreVerticalIcon />
588
+ </DropdownMenu>
589
+ <div className="query-loader__result__arrow">
590
+ <ThinChevronRightIcon />
591
+ </div>
433
592
  </div>
434
- </div>
435
- ))}
593
+ ))}
436
594
  </>
437
595
  )}
438
596
  {!queryLoaderState.searchQueriesState.hasCompleted && (
@@ -456,6 +614,7 @@ export const QueryLoaderDialog = observer(
456
614
  loadActionLabel?: string | undefined;
457
615
  }) => {
458
616
  const { queryLoaderState, title, loadActionLabel } = props;
617
+ const applicationStore = queryLoaderState.applicationStore;
459
618
 
460
619
  const close = (): void => {
461
620
  queryLoaderState.setQueryLoaderDialogOpen(false);
@@ -475,7 +634,9 @@ export const QueryLoaderDialog = observer(
475
634
  }}
476
635
  >
477
636
  <Modal
478
- darkMode={true}
637
+ darkMode={
638
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
639
+ }
479
640
  className="modal query-loader__dialog__body__content"
480
641
  >
481
642
  <div className="modal query-loader__dialog__header">
@@ -56,7 +56,12 @@ export const QueryUsageViewer = observer(
56
56
  open={resultState.isQueryUsageViewerOpened}
57
57
  onClose={() => resultState.setIsQueryUsageViewerOpened(false)}
58
58
  >
59
- <Modal className="query-builder__usage-viewer__modal" darkMode={true}>
59
+ <Modal
60
+ className="query-builder__usage-viewer__modal"
61
+ darkMode={
62
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
63
+ }
64
+ >
60
65
  <ModalHeader title="Query Usage" />
61
66
  <ModalBody className="query-builder__usage-viewer__body">
62
67
  <>
@@ -102,6 +107,7 @@ export const QueryUsageViewer = observer(
102
107
  <ModalFooterButton
103
108
  onClick={() => resultState.setIsQueryUsageViewerOpened(false)}
104
109
  text="Close"
110
+ type="secondary"
105
111
  />
106
112
  </ModalFooter>
107
113
  </Modal>
@@ -52,15 +52,19 @@ import {
52
52
  import { STYLE_PREFIX, STYLE_PREFIX__DARK } from '@finos/legend-art';
53
53
  import { expect } from '@jest/globals';
54
54
 
55
+ const getSelectorContainerClassName = (lightMode?: boolean): string =>
56
+ '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__value-container`;
57
+
58
+ const getSelectorInputClassName = (lightMode?: boolean): string =>
59
+ '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__single-value`;
60
+
55
61
  export const selectFromCustomSelectorInput = (
56
62
  selectorContainer: HTMLElement,
57
63
  optionText: string,
58
64
  lightMode?: boolean,
59
65
  ): void => {
60
- const selectorContainerClassName =
61
- '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__value-container`;
62
- const selectorInputValue =
63
- '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__single-value`;
66
+ const selectorContainerClassName = getSelectorContainerClassName(lightMode);
67
+ const selectorInputValue = getSelectorInputClassName(lightMode);
64
68
 
65
69
  let foundOptionText = false;
66
70
  const selector = selectorContainer.querySelector(
@@ -106,6 +110,38 @@ export const selectFromCustomSelectorInput = (
106
110
  }
107
111
  };
108
112
 
113
+ export const selectFirstOptionFromCustomSelectorInput = (
114
+ selectorContainer: HTMLElement,
115
+ lightMode?: boolean,
116
+ ): void => {
117
+ const selectorContainerClassName = getSelectorContainerClassName(lightMode);
118
+ const selectorInputValue = getSelectorInputClassName(lightMode);
119
+
120
+ const selector = selectorContainer.querySelector(
121
+ selectorContainerClassName,
122
+ ) as HTMLSelectElement;
123
+
124
+ fireEvent.keyDown(selector, { key: 'ArrowDown' });
125
+ fireEvent.keyDown(selector, { key: 'Enter' });
126
+ expect(selector.querySelector(selectorInputValue)).not.toBeNull();
127
+ };
128
+
129
+ export const getCustomSelectorInputValue = (
130
+ selectorContainer: HTMLElement,
131
+ lightMode?: boolean,
132
+ ): string | null => {
133
+ const selectorContainerClassName = getSelectorContainerClassName(lightMode);
134
+ const selectorInputValue = getSelectorInputClassName(lightMode);
135
+
136
+ const selector = guaranteeNonNullable(
137
+ selectorContainer.querySelector(selectorContainerClassName),
138
+ ) as HTMLSelectElement;
139
+ const selectorInput = guaranteeNonNullable(
140
+ selector.querySelector(selectorInputValue),
141
+ );
142
+ return selectorInput.textContent;
143
+ };
144
+
109
145
  export const dragAndDrop = async (
110
146
  source: HTMLElement,
111
147
  drop: HTMLElement,
@@ -217,9 +217,17 @@ const AccessStatusCellRenderer = observer(
217
217
  const DataAccessOverviewGrid = observer(
218
218
  (props: { dataAccessState: DataAccessState }) => {
219
219
  const { dataAccessState } = props;
220
+ const darkMode =
221
+ !dataAccessState.applicationStore.layoutService
222
+ .TEMPORARY__isLightColorThemeEnabled;
220
223
 
221
224
  return (
222
- <div className="data-access-overview__grid ag-theme-balham-dark">
225
+ <div
226
+ className={clsx('data-access-overview__grid', {
227
+ 'ag-theme-balham': !darkMode,
228
+ 'ag-theme-balham-dark': darkMode,
229
+ })}
230
+ >
223
231
  <DataGrid
224
232
  rowData={dataAccessState.datasets}
225
233
  gridOptions={{