@finos/legend-query-builder 4.14.18 → 4.14.20

Sign up to get free protection for your applications and to get access to all the features.
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={{