@finos/legend-application-query 5.1.0 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/lib/application/LegendQueryApplicationConfig.d.ts +17 -1
  2. package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
  3. package/lib/application/LegendQueryApplicationConfig.js +23 -1
  4. package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
  5. package/lib/components/QueryBuilder.d.ts.map +1 -1
  6. package/lib/components/QueryBuilder.js +3 -1
  7. package/lib/components/QueryBuilder.js.map +1 -1
  8. package/lib/components/QueryBuilderExplorerPanel.d.ts.map +1 -1
  9. package/lib/components/QueryBuilderExplorerPanel.js +7 -34
  10. package/lib/components/QueryBuilderExplorerPanel.js.map +1 -1
  11. package/lib/components/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  12. package/lib/components/QueryBuilderFetchStructurePanel.js +77 -66
  13. package/lib/components/QueryBuilderFetchStructurePanel.js.map +1 -1
  14. package/lib/components/QueryBuilderFilterPanel.d.ts.map +1 -1
  15. package/lib/components/QueryBuilderFilterPanel.js +28 -58
  16. package/lib/components/QueryBuilderFilterPanel.js.map +1 -1
  17. package/lib/components/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
  18. package/lib/components/QueryBuilderFunctionsExplorerPanel.js +9 -39
  19. package/lib/components/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
  20. package/lib/components/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
  21. package/lib/components/QueryBuilderGraphFetchTreePanel.js +5 -5
  22. package/lib/components/QueryBuilderGraphFetchTreePanel.js.map +1 -1
  23. package/lib/components/QueryBuilderLambdaEditor.d.ts +1 -0
  24. package/lib/components/QueryBuilderLambdaEditor.d.ts.map +1 -1
  25. package/lib/components/QueryBuilderLambdaEditor.js +2 -2
  26. package/lib/components/QueryBuilderLambdaEditor.js.map +1 -1
  27. package/lib/components/QueryBuilderMilestoneEditor.js +5 -5
  28. package/lib/components/QueryBuilderMilestoneEditor.js.map +1 -1
  29. package/lib/components/QueryBuilderPanelIssueCountBadge.d.ts +20 -0
  30. package/lib/components/QueryBuilderPanelIssueCountBadge.d.ts.map +1 -0
  31. package/lib/components/QueryBuilderPanelIssueCountBadge.js +28 -0
  32. package/lib/components/QueryBuilderPanelIssueCountBadge.js.map +1 -0
  33. package/lib/components/QueryBuilderParameterPanel.d.ts.map +1 -1
  34. package/lib/components/QueryBuilderParameterPanel.js +13 -34
  35. package/lib/components/QueryBuilderParameterPanel.js.map +1 -1
  36. package/lib/components/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  37. package/lib/components/QueryBuilderPostFilterPanel.js +33 -58
  38. package/lib/components/QueryBuilderPostFilterPanel.js.map +1 -1
  39. package/lib/components/QueryBuilderProjectionPanel.d.ts.map +1 -1
  40. package/lib/components/QueryBuilderProjectionPanel.js +47 -67
  41. package/lib/components/QueryBuilderProjectionPanel.js.map +1 -1
  42. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  43. package/lib/components/QueryBuilderPropertyExpressionEditor.js +11 -11
  44. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  45. package/lib/components/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
  46. package/lib/components/QueryBuilderPropertySearchPanel.js +3 -6
  47. package/lib/components/QueryBuilderPropertySearchPanel.js.map +1 -1
  48. package/lib/components/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  49. package/lib/components/QueryBuilderResultModifierPanel.js +3 -1
  50. package/lib/components/QueryBuilderResultModifierPanel.js.map +1 -1
  51. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  52. package/lib/components/QueryBuilderResultPanel.js +28 -20
  53. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  54. package/lib/components/QueryBuilderSetupPanel.d.ts.map +1 -1
  55. package/lib/components/QueryBuilderSetupPanel.js +10 -11
  56. package/lib/components/QueryBuilderSetupPanel.js.map +1 -1
  57. package/lib/components/QueryBuilderUnsupportedQueryEditor.d.ts.map +1 -1
  58. package/lib/components/QueryBuilderUnsupportedQueryEditor.js +4 -2
  59. package/lib/components/QueryBuilderUnsupportedQueryEditor.js.map +1 -1
  60. package/lib/components/QueryEditor.d.ts.map +1 -1
  61. package/lib/components/QueryEditor.js +16 -4
  62. package/lib/components/QueryEditor.js.map +1 -1
  63. package/lib/index.css +2 -2
  64. package/lib/index.css.map +1 -1
  65. package/lib/package.json +10 -9
  66. package/lib/stores/QueryBuilderExplorerState.d.ts.map +1 -1
  67. package/lib/stores/QueryBuilderExplorerState.js +5 -0
  68. package/lib/stores/QueryBuilderExplorerState.js.map +1 -1
  69. package/lib/stores/QueryBuilderFetchStructureState.d.ts +6 -0
  70. package/lib/stores/QueryBuilderFetchStructureState.d.ts.map +1 -1
  71. package/lib/stores/QueryBuilderFetchStructureState.js +8 -0
  72. package/lib/stores/QueryBuilderFetchStructureState.js.map +1 -1
  73. package/lib/stores/QueryBuilderFilterState.d.ts +4 -9
  74. package/lib/stores/QueryBuilderFilterState.d.ts.map +1 -1
  75. package/lib/stores/QueryBuilderFilterState.js +6 -11
  76. package/lib/stores/QueryBuilderFilterState.js.map +1 -1
  77. package/lib/stores/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  78. package/lib/stores/QueryBuilderGraphFetchTreeState.js +6 -3
  79. package/lib/stores/QueryBuilderGraphFetchTreeState.js.map +1 -1
  80. package/lib/stores/QueryBuilderLambdaProcessor.d.ts.map +1 -1
  81. package/lib/stores/QueryBuilderLambdaProcessor.js +2 -0
  82. package/lib/stores/QueryBuilderLambdaProcessor.js.map +1 -1
  83. package/lib/stores/QueryBuilderPostFilterState.d.ts +4 -4
  84. package/lib/stores/QueryBuilderPostFilterState.d.ts.map +1 -1
  85. package/lib/stores/QueryBuilderPostFilterState.js +6 -6
  86. package/lib/stores/QueryBuilderPostFilterState.js.map +1 -1
  87. package/lib/stores/QueryBuilderProjectionState.d.ts +2 -7
  88. package/lib/stores/QueryBuilderProjectionState.d.ts.map +1 -1
  89. package/lib/stores/QueryBuilderProjectionState.js +5 -17
  90. package/lib/stores/QueryBuilderProjectionState.js.map +1 -1
  91. package/lib/stores/QueryBuilderSetupState.js +1 -1
  92. package/lib/stores/QueryBuilderSetupState.js.map +1 -1
  93. package/lib/stores/QueryBuilderState.d.ts +6 -1
  94. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  95. package/lib/stores/QueryBuilderState.js +9 -2
  96. package/lib/stores/QueryBuilderState.js.map +1 -1
  97. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
  98. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js +7 -7
  99. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js.map +1 -1
  100. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  101. package/lib/stores/QueryEditorStore.js +14 -3
  102. package/lib/stores/QueryEditorStore.js.map +1 -1
  103. package/lib/stores/QueryFunctionsExplorerState.d.ts +2 -6
  104. package/lib/stores/QueryFunctionsExplorerState.d.ts.map +1 -1
  105. package/lib/stores/QueryFunctionsExplorerState.js +2 -11
  106. package/lib/stores/QueryFunctionsExplorerState.js.map +1 -1
  107. package/lib/stores/QueryParametersState.d.ts +1 -3
  108. package/lib/stores/QueryParametersState.d.ts.map +1 -1
  109. package/lib/stores/QueryParametersState.js +1 -4
  110. package/lib/stores/QueryParametersState.js.map +1 -1
  111. package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
  112. package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js +4 -1
  113. package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js.map +1 -1
  114. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
  115. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js +4 -1
  116. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
  117. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  118. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js +4 -1
  119. package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
  120. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
  121. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js +4 -1
  122. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
  123. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
  124. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js +4 -1
  125. package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
  126. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
  127. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js +4 -1
  128. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
  129. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
  130. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js +4 -1
  131. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
  132. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
  133. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js +4 -1
  134. package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
  135. package/package.json +17 -16
  136. package/src/application/LegendQueryApplicationConfig.ts +35 -1
  137. package/src/components/QueryBuilder.tsx +13 -2
  138. package/src/components/QueryBuilderExplorerPanel.tsx +17 -56
  139. package/src/components/QueryBuilderFetchStructurePanel.tsx +93 -80
  140. package/src/components/QueryBuilderFilterPanel.tsx +184 -225
  141. package/src/components/QueryBuilderFunctionsExplorerPanel.tsx +23 -68
  142. package/src/components/QueryBuilderGraphFetchTreePanel.tsx +34 -25
  143. package/src/components/QueryBuilderLambdaEditor.tsx +3 -0
  144. package/src/components/QueryBuilderMilestoneEditor.tsx +34 -34
  145. package/src/components/QueryBuilderPanelIssueCountBadge.tsx +38 -0
  146. package/src/components/QueryBuilderParameterPanel.tsx +21 -54
  147. package/src/components/QueryBuilderPostFilterPanel.tsx +202 -236
  148. package/src/components/QueryBuilderProjectionPanel.tsx +126 -170
  149. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +61 -57
  150. package/src/components/QueryBuilderPropertySearchPanel.tsx +8 -9
  151. package/src/components/QueryBuilderResultModifierPanel.tsx +4 -2
  152. package/src/components/QueryBuilderResultPanel.tsx +71 -52
  153. package/src/components/QueryBuilderSetupPanel.tsx +10 -11
  154. package/src/components/QueryBuilderUnsupportedQueryEditor.tsx +4 -2
  155. package/src/components/QueryEditor.tsx +39 -1
  156. package/src/stores/QueryBuilderExplorerState.ts +5 -0
  157. package/src/stores/QueryBuilderFetchStructureState.ts +9 -0
  158. package/src/stores/QueryBuilderFilterState.ts +7 -12
  159. package/src/stores/QueryBuilderGraphFetchTreeState.ts +14 -8
  160. package/src/stores/QueryBuilderLambdaProcessor.ts +8 -0
  161. package/src/stores/QueryBuilderPostFilterState.ts +7 -7
  162. package/src/stores/QueryBuilderProjectionState.ts +7 -18
  163. package/src/stores/QueryBuilderSetupState.ts +1 -1
  164. package/src/stores/QueryBuilderState.ts +10 -2
  165. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +9 -7
  166. package/src/stores/QueryEditorStore.ts +19 -3
  167. package/src/stores/QueryFunctionsExplorerState.ts +1 -11
  168. package/src/stores/QueryParametersState.ts +1 -3
  169. package/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts +8 -1
  170. package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts +8 -1
  171. package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts +8 -1
  172. package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts +8 -1
  173. package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts +8 -1
  174. package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts +8 -1
  175. package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts +8 -1
  176. package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts +8 -1
  177. package/tsconfig.json +1 -0
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { useRef, useState } from 'react';
17
18
  import {
18
19
  clsx,
19
20
  CheckSquareIcon,
@@ -28,6 +29,7 @@ import {
28
29
  SearchIcon,
29
30
  ChevronDownIcon,
30
31
  ChevronRightIcon,
32
+ useDragPreviewLayer,
31
33
  } from '@finos/legend-art';
32
34
  import {
33
35
  Class,
@@ -37,9 +39,7 @@ import {
37
39
  } from '@finos/legend-graph';
38
40
  import { guaranteeNonNullable } from '@finos/legend-shared';
39
41
  import { observer } from 'mobx-react-lite';
40
- import { useEffect, useRef, useState } from 'react';
41
42
  import { useDrag } from 'react-dnd';
42
- import { getEmptyImage } from 'react-dnd-html5-backend';
43
43
  import { QUERY_BUILDER_PROPERTY_SEARCH_TYPE } from '../QueryBuilder_Const.js';
44
44
  import {
45
45
  type QueryBuilderExplorerTreeNodeData,
@@ -116,7 +116,9 @@ const QueryBuilderTreeNodeViewer = observer(
116
116
  props;
117
117
  const [isExpandable, setIsExpandable] = useState(false);
118
118
  const propertySearchPanelState = explorerState.propertySearchPanelState;
119
- const [, dragConnector, dragPreviewConnector] = useDrag(
119
+ const [, dragConnector, dragPreviewConnector] = useDrag<{
120
+ node?: QueryBuilderExplorerTreePropertyNodeData;
121
+ }>(
120
122
  () => ({
121
123
  type:
122
124
  node instanceof QueryBuilderExplorerTreePropertyNodeData
@@ -126,16 +128,17 @@ const QueryBuilderTreeNodeViewer = observer(
126
128
  ? QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.CLASS_PROPERTY
127
129
  : QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY
128
130
  : QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ROOT,
129
- item: (): { node?: QueryBuilderExplorerTreePropertyNodeData } =>
131
+ item: () =>
130
132
  node instanceof QueryBuilderExplorerTreePropertyNodeData
131
133
  ? { node }
132
134
  : {},
133
- collect: (monitor): { isDragging: boolean } => ({
135
+ collect: (monitor) => ({
134
136
  isDragging: monitor.isDragging(),
135
137
  }),
136
138
  }),
137
139
  [node],
138
140
  );
141
+ useDragPreviewLayer(dragPreviewConnector);
139
142
  const isMultiple =
140
143
  (node instanceof QueryBuilderExplorerTreePropertyNodeData &&
141
144
  (node.property.multiplicity.upperBound === undefined ||
@@ -186,10 +189,6 @@ const QueryBuilderTreeNodeViewer = observer(
186
189
  node.parentId === pn.id,
187
190
  );
188
191
 
189
- useEffect(() => {
190
- dragPreviewConnector(getEmptyImage(), { captureDraggingState: true });
191
- }, [dragPreviewConnector]);
192
-
193
192
  return (
194
193
  <div>
195
194
  <div
@@ -32,6 +32,7 @@ import {
32
32
  import type { QueryBuilderState } from '../stores/QueryBuilderState.js';
33
33
  import type { QueryBuilderProjectionColumnState } from '../stores/QueryBuilderProjectionState.js';
34
34
  import { guaranteeNonNullable } from '@finos/legend-shared';
35
+ import { useApplicationStore } from '@finos/legend-application';
35
36
 
36
37
  const ColumnSortEditor = observer(
37
38
  (props: {
@@ -39,6 +40,7 @@ const ColumnSortEditor = observer(
39
40
  columnSort: SortColumnState;
40
41
  }) => {
41
42
  const { queryBuilderState, columnSort } = props;
43
+ const applicationStore = useApplicationStore();
42
44
  const projectionState =
43
45
  queryBuilderState.fetchStructureState.projectionState;
44
46
  const sortColumns = queryBuilderState.resultSetModifierState.sortColumns;
@@ -81,7 +83,7 @@ const ColumnSortEditor = observer(
81
83
  disabled={projectionOptions.length <= 1}
82
84
  onChange={onChange}
83
85
  value={value}
84
- darkMode={true}
86
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
85
87
  />
86
88
  <button
87
89
  className="btn--dark btn--sm query-builder__projection__options__sort__type-btn"
@@ -95,7 +97,7 @@ const ColumnSortEditor = observer(
95
97
  )}
96
98
  </button>
97
99
  <button
98
- className="query-builder__projection__options__sort__remove-btn"
100
+ className="query-builder__projection__options__sort__remove-btn btn--dark btn--caution"
99
101
  onClick={deleteColumnSort}
100
102
  tabIndex={-1}
101
103
  title={'Remove'}
@@ -288,6 +288,61 @@ const QueryBuilderResultContextMenu = observer(
288
288
  }),
289
289
  );
290
290
 
291
+ const QueryBuilderGridResult = observer(
292
+ (props: {
293
+ executionResult: TdsExecutionResult;
294
+ queryBuilderState: QueryBuilderState;
295
+ }) => {
296
+ const { executionResult, queryBuilderState } = props;
297
+ const [cellDoubleClickedEvent, setCellDoubleClickedEvent] =
298
+ useState<CellMouseOverEvent | null>(null);
299
+ const columns = executionResult.result.columns;
300
+ const rowData = executionResult.result.rows.map((_row) => {
301
+ const row: Record<PropertyKey, unknown> = {};
302
+ const cols = executionResult.result.columns;
303
+ _row.values.forEach((value, idx) => {
304
+ // `ag-grid` shows `false` value as empty string so we have
305
+ // call `.toString()` to avoid this behavior.
306
+ // See https://github.com/finos/legend-studio/issues/1008
307
+ row[cols[idx] as string] = isBoolean(value) ? String(value) : value;
308
+ });
309
+ return row;
310
+ });
311
+
312
+ return (
313
+ <ContextMenu
314
+ content={
315
+ <QueryBuilderResultContextMenu
316
+ event={cellDoubleClickedEvent}
317
+ queryBuilderState={queryBuilderState}
318
+ />
319
+ }
320
+ menuProps={{ elevation: 7 }}
321
+ key={executionResult._UUID}
322
+ className={clsx('ag-theme-balham-dark query-builder__result__tds-grid')}
323
+ >
324
+ <AgGridReact
325
+ rowData={rowData}
326
+ onCellMouseOver={(event): void => {
327
+ setCellDoubleClickedEvent(event);
328
+ }}
329
+ >
330
+ {columns.map((colName) => (
331
+ <AgGridColumn
332
+ minWidth={50}
333
+ sortable={true}
334
+ resizable={true}
335
+ field={colName}
336
+ key={colName}
337
+ flex={1}
338
+ />
339
+ ))}
340
+ </AgGridReact>
341
+ </ContextMenu>
342
+ );
343
+ },
344
+ );
345
+
291
346
  const QueryBuilderResultValues = observer(
292
347
  (props: {
293
348
  executionResult: ExecutionResult;
@@ -295,52 +350,11 @@ const QueryBuilderResultValues = observer(
295
350
  }) => {
296
351
  const { executionResult, queryBuilderState } = props;
297
352
  if (executionResult instanceof TdsExecutionResult) {
298
- const [cellDoubleClickedEvent, setCellDoubleClickedEvent] =
299
- useState<CellMouseOverEvent | null>(null);
300
- const columns = executionResult.result.columns;
301
- const rowData = executionResult.result.rows.map((_row) => {
302
- const row: Record<PropertyKey, unknown> = {};
303
- const cols = executionResult.result.columns;
304
- _row.values.forEach((value, idx) => {
305
- // `ag-grid` shows `false` value as empty string so we have
306
- // call `.toString()` to avoid this behavior.
307
- // See https://github.com/finos/legend-studio/issues/1008
308
- row[cols[idx] as string] = isBoolean(value) ? String(value) : value;
309
- });
310
- return row;
311
- });
312
353
  return (
313
- <ContextMenu
314
- content={
315
- <QueryBuilderResultContextMenu
316
- event={cellDoubleClickedEvent}
317
- queryBuilderState={queryBuilderState}
318
- />
319
- }
320
- menuProps={{ elevation: 7 }}
321
- key={executionResult._UUID}
322
- className={clsx(
323
- 'ag-theme-balham-dark query-builder__result__tds-grid',
324
- )}
325
- >
326
- <AgGridReact
327
- rowData={rowData}
328
- onCellMouseOver={(event): void => {
329
- setCellDoubleClickedEvent(event);
330
- }}
331
- >
332
- {columns.map((colName) => (
333
- <AgGridColumn
334
- minWidth={50}
335
- sortable={true}
336
- resizable={true}
337
- field={colName}
338
- key={colName}
339
- flex={1}
340
- />
341
- ))}
342
- </AgGridReact>
343
- </ContextMenu>
354
+ <QueryBuilderGridResult
355
+ queryBuilderState={queryBuilderState}
356
+ executionResult={executionResult}
357
+ />
344
358
  );
345
359
  } else if (executionResult instanceof RawExecutionResult) {
346
360
  return (
@@ -414,6 +428,9 @@ export const QueryBuilderResultPanel = observer(
414
428
  ],
415
429
  });
416
430
  };
431
+ const queryValidationIssues = queryBuilderState.validationIssues;
432
+ const isQueryValid =
433
+ !queryBuilderState.isQuerySupported() || !queryValidationIssues;
417
434
  const runQuery = (): void => {
418
435
  if (queryParametersState.parameterStates.length) {
419
436
  queryParametersState.parameterValuesEditorState.open(
@@ -475,7 +492,7 @@ export const QueryBuilderResultPanel = observer(
475
492
  type="number"
476
493
  value={resultState.previewLimit}
477
494
  onChange={changeLimit}
478
- disabled={!queryBuilderState.isValidQueryBuilderState()}
495
+ disabled={!isQueryValid}
479
496
  />
480
497
  </div>
481
498
  )}
@@ -484,7 +501,7 @@ export const QueryBuilderResultPanel = observer(
484
501
  className="query-builder__result__stop-btn"
485
502
  onClick={cancelQuery}
486
503
  tabIndex={-1}
487
- disabled={!queryBuilderState.isValidQueryBuilderState()}
504
+ disabled={!isQueryValid}
488
505
  >
489
506
  <div className="btn--dark btn--caution query-builder__result__stop-btn__label">
490
507
  <PauseCircleIcon className="query-builder__result__stop-btn__label__icon" />
@@ -499,11 +516,13 @@ export const QueryBuilderResultPanel = observer(
499
516
  onClick={runQuery}
500
517
  tabIndex={-1}
501
518
  title={
502
- !queryBuilderState.isValidQueryBuilderState()
503
- ? 'Query is not valid'
519
+ queryValidationIssues
520
+ ? `Query is not valid:\n${queryValidationIssues
521
+ .map((issue) => `\u2022 ${issue}`)
522
+ .join('\n')}`
504
523
  : undefined
505
524
  }
506
- disabled={!queryBuilderState.isValidQueryBuilderState()}
525
+ disabled={!isQueryValid}
507
526
  >
508
527
  <div className="query-builder__result__execute-btn__label">
509
528
  <PlayIcon className="query-builder__result__execute-btn__label__icon" />
@@ -566,14 +585,14 @@ export const QueryBuilderResultPanel = observer(
566
585
  className="query-builder__result__export__dropdown__label"
567
586
  tabIndex={-1}
568
587
  title="Export"
569
- disabled={!queryBuilderState.isValidQueryBuilderState()}
588
+ disabled={!isQueryValid}
570
589
  >
571
590
  Export
572
591
  </button>
573
592
  <button
574
593
  className="query-builder__result__export__dropdown__trigger"
575
594
  tabIndex={-1}
576
- disabled={!queryBuilderState.isValidQueryBuilderState()}
595
+ disabled={!isQueryValid}
577
596
  >
578
597
  <CaretDownIcon />
579
598
  </button>
@@ -21,7 +21,6 @@ import {
21
21
  PURE_ClassIcon,
22
22
  PURE_MappingIcon,
23
23
  PURE_RuntimeIcon,
24
- EyeIcon,
25
24
  ClockIcon,
26
25
  clsx,
27
26
  } from '@finos/legend-art';
@@ -48,6 +47,7 @@ import {
48
47
  type PackageableElementOption,
49
48
  getPackageableElementOptionFormatter,
50
49
  buildElementOption,
50
+ useApplicationStore,
51
51
  } from '@finos/legend-application';
52
52
  import { MilestoningParametersEditor } from './QueryBuilderMilestoneEditor.js';
53
53
  import { useState } from 'react';
@@ -124,8 +124,8 @@ const generateClassLabel = (
124
124
  >
125
125
  {val.name}
126
126
  </div>
127
- <EyeIcon
128
- className="query-builder__setup__config__item__class-label__btn"
127
+ <ClockIcon
128
+ className="query-builder__setup__config__item__class-label__milestoning"
129
129
  title={milestoningParameterValues}
130
130
  />
131
131
  </div>
@@ -151,6 +151,7 @@ const generateClassLabel = (
151
151
  export const QueryBuilderSetupPanel = observer(
152
152
  (props: { queryBuilderState: QueryBuilderState }) => {
153
153
  const { queryBuilderState } = props;
154
+ const applicationStore = useApplicationStore();
154
155
  const querySetupState = queryBuilderState.querySetupState;
155
156
  const [isMilestoneEditorOpened, setIsMilestoneEditorOpened] =
156
157
  useState<boolean>(false);
@@ -266,16 +267,15 @@ export const QueryBuilderSetupPanel = observer(
266
267
  options={classOptions}
267
268
  onChange={changeClass}
268
269
  value={selectedClassOption}
269
- darkMode={true}
270
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
270
271
  disabled={!isQuerySupported || querySetupState.classIsReadOnly}
271
272
  filterOption={elementFilterOption}
272
273
  formatOptionLabel={getPackageableElementOptionFormatter({
273
- darkMode: true,
274
- graphManagerState: queryBuilderState.graphManagerState,
274
+ darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
275
275
  })}
276
276
  />
277
277
  <button
278
- className="btn--dark btn__icon--dark"
278
+ className="btn--dark btn__icon--dark query-builder__setup__milestoning"
279
279
  tabIndex={-1}
280
280
  onClick={(): void => setIsMilestoneEditorOpened(true)}
281
281
  disabled={!isMilestonedQuery}
@@ -303,11 +303,10 @@ export const QueryBuilderSetupPanel = observer(
303
303
  options={mappingOptions}
304
304
  onChange={changeMapping}
305
305
  value={selectedMappingOption}
306
- darkMode={true}
306
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
307
307
  filterOption={elementFilterOption}
308
308
  formatOptionLabel={getPackageableElementOptionFormatter({
309
- darkMode: true,
310
- graphManagerState: queryBuilderState.graphManagerState,
309
+ darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
311
310
  })}
312
311
  />
313
312
  </div>
@@ -332,7 +331,7 @@ export const QueryBuilderSetupPanel = observer(
332
331
  options={runtimeOptions}
333
332
  onChange={changeRuntime}
334
333
  value={selectedRuntimeOption}
335
- darkMode={true}
334
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
336
335
  filterOption={runtimeFilterOption}
337
336
  />
338
337
  </div>
@@ -48,7 +48,9 @@ const QueryBuilderUnsupportedQueryEditPanel = observer(
48
48
  const { queryBuilderState } = props;
49
49
  const queryUnsupportedState = queryBuilderState.queryUnsupportedState;
50
50
  const lambdaError = queryUnsupportedState.lambdaError;
51
- const errorMessage = lambdaError ? `due to: ${lambdaError.message}` : '';
51
+ const errorMessage = lambdaError?.message
52
+ ? ` due to: ${lambdaError.message}`
53
+ : '';
52
54
  const openLambdaModal = (): void =>
53
55
  queryBuilderState.queryTextEditorState.openModal(
54
56
  QueryTextEditorMode.TEXT,
@@ -63,7 +65,7 @@ const QueryBuilderUnsupportedQueryEditPanel = observer(
63
65
  <div className="panel__content">
64
66
  <BlankPanelContent>
65
67
  <div className="query-builder__unsupported-view__main">
66
- <div className="query-builder__unsupported-view__summary">{`Can't display query in form mode ${errorMessage}`}</div>
68
+ <div className="query-builder__unsupported-view__summary">{`Can't display query in form mode${errorMessage}`}</div>
67
69
  <button
68
70
  className="btn--dark query-builder__unsupported-view__to-text-mode__btn"
69
71
  onClick={openLambdaModal}
@@ -22,6 +22,9 @@ import {
22
22
  RobotIcon,
23
23
  SaveIcon,
24
24
  BlankPanelContent,
25
+ clsx,
26
+ EmptyLightBulbIcon,
27
+ LightBulbIcon,
25
28
  } from '@finos/legend-art';
26
29
  import { getQueryParameters } from '@finos/legend-shared';
27
30
  import { observer } from 'mobx-react-lite';
@@ -108,6 +111,8 @@ const QueryExportDialogContent = observer(
108
111
  )}
109
112
  <button
110
113
  className="btn modal__footer__close-btn btn--dark"
114
+ // TODO?: we should probably annotate here why,
115
+ // when we disable this action
111
116
  disabled={!allowCreate}
112
117
  onClick={create}
113
118
  >
@@ -199,6 +204,10 @@ const QueryEditorHeaderContent = observer(() => {
199
204
  ),
200
205
  );
201
206
  };
207
+ const toggleLightDarkTheme = (): void =>
208
+ applicationStore.TEMPORARY__setIsLightThemeEnabled(
209
+ !applicationStore.TEMPORARY__isLightThemeEnabled,
210
+ );
202
211
  const saveQuery = (): void => {
203
212
  editorStore.queryBuilderState
204
213
  .saveQuery(async (lambda: RawLambda) => {
@@ -227,6 +236,20 @@ const QueryEditorHeaderContent = observer(() => {
227
236
  >
228
237
  <ExternalLinkSquareIcon />
229
238
  </button>
239
+ {applicationStore.config.options.TEMPORARY__enableThemeSwitcher && (
240
+ <button
241
+ className="query-editor__header__action query-editor__header__action--simple btn--dark"
242
+ tabIndex={-1}
243
+ title="Toggle Light/Dark Theme"
244
+ onClick={toggleLightDarkTheme}
245
+ >
246
+ {applicationStore.TEMPORARY__isLightThemeEnabled ? (
247
+ <EmptyLightBulbIcon />
248
+ ) : (
249
+ <LightBulbIcon />
250
+ )}
251
+ </button>
252
+ )}
230
253
  <button
231
254
  className="query-editor__header__action btn--dark"
232
255
  tabIndex={-1}
@@ -256,9 +279,24 @@ export const QueryEditor = observer(() => {
256
279
  );
257
280
  }, [editorStore, applicationStore]);
258
281
 
282
+ useEffect(() => {
283
+ document.body.classList.toggle(
284
+ 'light-theme',
285
+ applicationStore.TEMPORARY__isLightThemeEnabled,
286
+ );
287
+ }, [applicationStore.TEMPORARY__isLightThemeEnabled]);
288
+
259
289
  return (
260
290
  <DndProvider backend={HTML5Backend}>
261
- <div className="query-editor">
291
+ <div
292
+ className={clsx([
293
+ 'query-editor ',
294
+ {
295
+ 'query-editor--light':
296
+ applicationStore.TEMPORARY__isLightThemeEnabled,
297
+ },
298
+ ])}
299
+ >
262
300
  <div className="query-editor__header">
263
301
  <button
264
302
  className="query-editor__header__back-btn btn--dark"
@@ -355,6 +355,11 @@ export const getQueryBuilderPropertyNodeData = (
355
355
  parentNode.isPartOfDerivedPropertyBranch ||
356
356
  (parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
357
357
  parentNode.property instanceof DerivedProperty);
358
+ // NOTE: in case of association, to avoid infinite exploration path
359
+ // we will prune it, on the other hand, in circular composition case
360
+ // A has property of type B and B has property of type A
361
+ // we will allow users to explore as deeply as they wish
362
+ // See https://github.com/finos/legend-studio/issues/1172
358
363
  if (
359
364
  property instanceof Property &&
360
365
  parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
@@ -27,6 +27,11 @@ export enum FETCH_STRUCTURE_MODE {
27
27
 
28
28
  export class QueryBuilderFetchStructureState {
29
29
  queryBuilderState: QueryBuilderState;
30
+ /**
31
+ * TODO?: perhaps it would eventually make sense to default to
32
+ * graph-fetch since `getAll()` naturally works for graph-fetch case
33
+ * and graph-fetch allows somewhat an empty tree
34
+ */
30
35
  fetchStructureMode = FETCH_STRUCTURE_MODE.PROJECTION;
31
36
  projectionState: QueryBuilderProjectionState;
32
37
  graphFetchTreeState: QueryBuilderGraphFetchTreeState;
@@ -63,4 +68,8 @@ export class QueryBuilderFetchStructureState {
63
68
  isProjectionMode(): boolean {
64
69
  return this.fetchStructureMode === FETCH_STRUCTURE_MODE.PROJECTION;
65
70
  }
71
+
72
+ get validationIssues(): string[] | undefined {
73
+ return this.projectionState.validationIssues;
74
+ }
66
75
  }
@@ -264,7 +264,7 @@ export abstract class QueryBuilderFilterTreeNodeData implements TreeNodeData {
264
264
  });
265
265
  }
266
266
 
267
- abstract get dragLayerLabel(): string;
267
+ abstract get dragPreviewLabel(): string;
268
268
  setIsOpen(val: boolean): void {
269
269
  this.isOpen = val;
270
270
  }
@@ -289,14 +289,14 @@ export class QueryBuilderFilterTreeGroupNodeData extends QueryBuilderFilterTreeN
289
289
  setGroupOperation: action,
290
290
  addChildNode: action,
291
291
  removeChildNode: action,
292
- dragLayerLabel: computed,
292
+ dragPreviewLabel: computed,
293
293
  });
294
294
 
295
295
  this.groupOperation = groupOperation;
296
296
  this.isOpen = true;
297
297
  }
298
298
 
299
- get dragLayerLabel(): string {
299
+ get dragPreviewLabel(): string {
300
300
  return `${this.groupOperation.toUpperCase()} group`;
301
301
  }
302
302
 
@@ -328,13 +328,13 @@ export class QueryBuilderFilterTreeConditionNodeData extends QueryBuilderFilterT
328
328
 
329
329
  makeObservable(this, {
330
330
  condition: observable,
331
- dragLayerLabel: computed,
331
+ dragPreviewLabel: computed,
332
332
  });
333
333
 
334
334
  this.condition = condition;
335
335
  }
336
336
 
337
- get dragLayerLabel(): string {
337
+ get dragPreviewLabel(): string {
338
338
  return this.condition.propertyExpressionState.title;
339
339
  }
340
340
  }
@@ -344,11 +344,11 @@ export class QueryBuilderFilterTreeBlankConditionNodeData extends QueryBuilderFi
344
344
  super(parentId);
345
345
 
346
346
  makeObservable(this, {
347
- dragLayerLabel: computed,
347
+ dragPreviewLabel: computed,
348
348
  });
349
349
  }
350
350
 
351
- get dragLayerLabel(): string {
351
+ get dragPreviewLabel(): string {
352
352
  return '<blank>';
353
353
  }
354
354
  }
@@ -452,11 +452,6 @@ export class QueryBuilderFilterState
452
452
  isRearrangingConditions = false;
453
453
  operators: QueryBuilderFilterOperator[] = [];
454
454
  private _suppressClickawayEventListener = false;
455
- /**
456
- * This flag is for turning on/off dnd from projection panel to filter panel,
457
- * and will be leveraged when the concepts of workflows are introduced into query builder.
458
- */
459
- allowDnDProjectionToFilter = true;
460
455
 
461
456
  constructor(
462
457
  queryBuilderState: QueryBuilderState,
@@ -26,6 +26,7 @@ import {
26
26
  buildGraphFetchTreeData,
27
27
  } from './QueryBuilderGraphFetchTreeUtil.js';
28
28
  import type { QueryBuilderExplorerTreePropertyNodeData } from './QueryBuilderExplorerState.js';
29
+ import { assertNonNullable } from '@finos/legend-shared';
29
30
 
30
31
  export class QueryBuilderGraphFetchTreeState {
31
32
  queryBuilderState: QueryBuilderState;
@@ -77,14 +78,19 @@ export class QueryBuilderGraphFetchTreeState {
77
78
  }
78
79
 
79
80
  addProperty(node: QueryBuilderExplorerTreePropertyNodeData): void {
80
- if (this.treeData) {
81
- addQueryBuilderPropertyNode(
82
- this.treeData,
83
- this.queryBuilderState.explorerState.nonNullableTreeData,
84
- node,
85
- this.queryBuilderState,
86
- );
87
- this.setGraphFetchTree({ ...this.treeData });
81
+ if (!this.treeData) {
82
+ this.initialize();
88
83
  }
84
+ assertNonNullable(
85
+ this.treeData,
86
+ `Graph-fetch tree has not been properly initialized`,
87
+ );
88
+ addQueryBuilderPropertyNode(
89
+ this.treeData,
90
+ this.queryBuilderState.explorerState.nonNullableTreeData,
91
+ node,
92
+ this.queryBuilderState,
93
+ );
94
+ this.setGraphFetchTree({ ...this.treeData });
89
95
  }
90
96
  }
@@ -693,6 +693,10 @@ export class QueryBuilderLambdaProcessor
693
693
  (e, idx) => e.setColumnName(aliases[idx] as string),
694
694
  );
695
695
 
696
+ this.queryBuilderState.fetchStructureState.setFetchStructureMode(
697
+ FETCH_STRUCTURE_MODE.PROJECTION,
698
+ );
699
+
696
700
  return;
697
701
  } else if (
698
702
  matchFunctionName(
@@ -943,6 +947,10 @@ export class QueryBuilderLambdaProcessor
943
947
  (e, idx) => e.setColumnName(aliases[idx] as string),
944
948
  );
945
949
 
950
+ this.queryBuilderState.fetchStructureState.setFetchStructureMode(
951
+ FETCH_STRUCTURE_MODE.PROJECTION,
952
+ );
953
+
946
954
  return;
947
955
  } else if (
948
956
  matchFunctionName(functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_AGG)
@@ -165,7 +165,7 @@ export abstract class QueryBuilderPostFilterTreeNodeData
165
165
  });
166
166
  }
167
167
 
168
- abstract get dragLayerLabel(): string;
168
+ abstract get dragPreviewLabel(): string;
169
169
  setIsOpen(val: boolean): void {
170
170
  this.isOpen = val;
171
171
  }
@@ -197,13 +197,13 @@ export class QueryBuilderPostFilterTreeGroupNodeData extends QueryBuilderPostFil
197
197
  setGroupOperation: action,
198
198
  addChildNode: action,
199
199
  removeChildNode: action,
200
- dragLayerLabel: computed,
200
+ dragPreviewLabel: computed,
201
201
  });
202
202
  this.groupOperation = groupOperation;
203
203
  this.isOpen = true;
204
204
  }
205
205
 
206
- get dragLayerLabel(): string {
206
+ get dragPreviewLabel(): string {
207
207
  return `${this.groupOperation.toUpperCase()} group`;
208
208
  }
209
209
 
@@ -238,13 +238,13 @@ export class QueryBuilderPostFilterTreeConditionNodeData extends QueryBuilderPos
238
238
 
239
239
  makeObservable(this, {
240
240
  condition: observable,
241
- dragLayerLabel: computed,
241
+ dragPreviewLabel: computed,
242
242
  });
243
243
 
244
244
  this.condition = condition;
245
245
  }
246
246
 
247
- get dragLayerLabel(): string {
247
+ get dragPreviewLabel(): string {
248
248
  return this.condition.columnName;
249
249
  }
250
250
  }
@@ -254,11 +254,11 @@ export class QueryBuilderPostFilterTreeBlankConditionNodeData extends QueryBuild
254
254
  super(parentId);
255
255
 
256
256
  makeObservable(this, {
257
- dragLayerLabel: computed,
257
+ dragPreviewLabel: computed,
258
258
  });
259
259
  }
260
260
 
261
- get dragLayerLabel(): string {
261
+ get dragPreviewLabel(): string {
262
262
  return '<blank>';
263
263
  }
264
264
  }