@finos/legend-query-builder 4.19.22 → 4.19.24

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 (47) hide show
  1. package/lib/components/QueryBuilder.d.ts.map +1 -1
  2. package/lib/components/QueryBuilder.js +65 -50
  3. package/lib/components/QueryBuilder.js.map +1 -1
  4. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +2 -1
  5. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
  6. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +2 -2
  7. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +11 -7
  10. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  11. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  12. package/lib/components/filter/QueryBuilderFilterPanel.js +18 -7
  13. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  14. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  15. package/lib/components/shared/LambdaEditor.js +4 -13
  16. package/lib/components/shared/LambdaEditor.js.map +1 -1
  17. package/lib/components/sql-playground/SQLPlaygroundEditor.d.ts.map +1 -1
  18. package/lib/components/sql-playground/SQLPlaygroundEditor.js +4 -4
  19. package/lib/components/sql-playground/SQLPlaygroundEditor.js.map +1 -1
  20. package/lib/data-access-overview.css +1 -1
  21. package/lib/index.css +1 -1
  22. package/lib/index.d.ts +1 -0
  23. package/lib/index.d.ts.map +1 -1
  24. package/lib/index.js +1 -0
  25. package/lib/index.js.map +1 -1
  26. package/lib/package.json +1 -1
  27. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
  28. package/lib/stores/QueryBuilderValueSpecificationHelper.js +2 -1
  29. package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
  30. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts.map +1 -1
  31. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +7 -2
  32. package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
  33. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts +10 -0
  34. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts.map +1 -1
  35. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js +16 -0
  36. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js.map +1 -1
  37. package/package.json +8 -8
  38. package/src/components/QueryBuilder.tsx +392 -365
  39. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +3 -1
  40. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +383 -371
  41. package/src/components/filter/QueryBuilderFilterPanel.tsx +25 -10
  42. package/src/components/shared/LambdaEditor.tsx +10 -13
  43. package/src/components/sql-playground/SQLPlaygroundEditor.tsx +6 -5
  44. package/src/index.ts +1 -0
  45. package/src/stores/QueryBuilderValueSpecificationHelper.ts +2 -1
  46. package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +7 -1
  47. package/src/stores/query-workflow/QueryBuilderWorkFlowState.ts +19 -0
@@ -101,7 +101,6 @@ import {
101
101
  useApplicationStore,
102
102
  } from '@finos/legend-application';
103
103
  import {
104
- type Type,
105
104
  type ValueSpecification,
106
105
  AbstractPropertyExpression,
107
106
  extractElementNameFromPath,
@@ -881,16 +880,30 @@ export const QueryBuilderFilterRelationColumnBadge = observer(
881
880
  );
882
881
 
883
882
  const canDropTypeOntoNodeValue = (
884
- type: Type | undefined,
883
+ item: QueryBuilderFilterValueDropTarget,
884
+ type: string,
885
885
  condition: FilterConditionState,
886
886
  ): boolean => {
887
887
  const conditionOperator = condition.operator;
888
888
  const conditionValueType = condition.leftConditionType;
889
- return (
890
- !(conditionOperator instanceof QueryBuilderFilterOperator_In) &&
891
- !(conditionOperator instanceof QueryBuilderFilterOperator_NotIn) &&
892
- isTypeCompatibleForAssignment(type, conditionValueType)
893
- );
889
+ const itemType = getDNDItemType(item, type);
890
+ if (
891
+ conditionOperator instanceof QueryBuilderFilterOperator_In ||
892
+ conditionOperator instanceof QueryBuilderFilterOperator_NotIn
893
+ ) {
894
+ // `in` / `not in` filter conditions take a collection value, so only a
895
+ // collection-multiplicity (`[*]`) parameter can be dropped onto them;
896
+ // scalar properties/columns can never satisfy a collection operator
897
+ if (type !== QUERY_BUILDER_VARIABLE_DND_TYPE) {
898
+ return false;
899
+ }
900
+ const variable = (item as QueryBuilderVariableDragSource).variable;
901
+ return (
902
+ variable.multiplicity.upperBound !== 1 &&
903
+ isTypeCompatibleForAssignment(itemType, conditionValueType)
904
+ );
905
+ }
906
+ return isTypeCompatibleForAssignment(itemType, conditionValueType);
894
907
  };
895
908
 
896
909
  const QueryBuilderFilterConditionEditor = observer(
@@ -912,7 +925,7 @@ const QueryBuilderFilterConditionEditor = observer(
912
925
  const itemType = getDNDItemType(item, type);
913
926
  if (
914
927
  itemType !== undefined &&
915
- canDropTypeOntoNodeValue(itemType, node.condition)
928
+ canDropTypeOntoNodeValue(item, type, node.condition)
916
929
  ) {
917
930
  try {
918
931
  if (
@@ -1047,7 +1060,8 @@ const QueryBuilderFilterConditionEditor = observer(
1047
1060
  accept: CAN_DROP_FILTER_VALUE_DND_TYPES,
1048
1061
  canDrop: (item, monitor): boolean =>
1049
1062
  canDropTypeOntoNodeValue(
1050
- getDNDItemType(item, monitor.getItemType() as string),
1063
+ item,
1064
+ monitor.getItemType() as string,
1051
1065
  node.condition,
1052
1066
  ),
1053
1067
  drop: (item, monitor): void => {
@@ -1072,7 +1086,8 @@ const QueryBuilderFilterConditionEditor = observer(
1072
1086
  monitor.getItemType()?.toString() ?? '',
1073
1087
  ) &&
1074
1088
  canDropTypeOntoNodeValue(
1075
- getDNDItemType(monitor.getItem(), monitor.getItemType() as string),
1089
+ monitor.getItem(),
1090
+ monitor.getItemType() as string,
1076
1091
  node.condition,
1077
1092
  ),
1078
1093
  }));
@@ -42,8 +42,8 @@ import {
42
42
  clearMarkers,
43
43
  setErrorMarkers,
44
44
  CODE_EDITOR_LANGUAGE,
45
- CODE_EDITOR_THEME,
46
45
  PURE_CODE_EDITOR_WORD_SEPARATORS,
46
+ getCodeEditorThemeForAppTheme,
47
47
  type CompletionItem,
48
48
  } from '@finos/legend-code-editor';
49
49
  import { disposeCodeEditor } from '@finos/legend-lego/code-editor';
@@ -273,10 +273,9 @@ const LambdaEditor_Inner = observer(
273
273
  const _editor = monacoEditorAPI.create(element, {
274
274
  ...getBaseCodeEditorOptions(),
275
275
  language: CODE_EDITOR_LANGUAGE.PURE,
276
- theme: applicationStore.layoutService
277
- .TEMPORARY__isLightColorThemeEnabled
278
- ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
279
- : CODE_EDITOR_THEME.DEFAULT_DARK,
276
+ theme: getCodeEditorThemeForAppTheme(
277
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
278
+ ),
280
279
  ...lambdaEditorOptions,
281
280
  });
282
281
  setEditor(_editor);
@@ -311,10 +310,9 @@ const LambdaEditor_Inner = observer(
311
310
  useEffect(() => {
312
311
  if (editor) {
313
312
  editor.updateOptions({
314
- theme: applicationStore.layoutService
315
- .TEMPORARY__isLightColorThemeEnabled
316
- ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
317
- : CODE_EDITOR_THEME.DEFAULT_DARK,
313
+ theme: getCodeEditorThemeForAppTheme(
314
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
315
+ ),
318
316
  });
319
317
  }
320
318
  }, [
@@ -608,10 +606,9 @@ const LambdaEditor_PopUp = observer(
608
606
  const _editor = monacoEditorAPI.create(element, {
609
607
  ...getBaseCodeEditorOptions(),
610
608
  language: CODE_EDITOR_LANGUAGE.PURE,
611
- theme: applicationStore.layoutService
612
- .TEMPORARY__isLightColorThemeEnabled
613
- ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
614
- : CODE_EDITOR_THEME.DEFAULT_DARK,
609
+ theme: getCodeEditorThemeForAppTheme(
610
+ applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled,
611
+ ),
615
612
  });
616
613
  setEditor(_editor);
617
614
  }
@@ -20,8 +20,8 @@ import { useCallback, useEffect, useRef, useState } from 'react';
20
20
  import { useCommands } from '@finos/legend-application';
21
21
  import {
22
22
  CODE_EDITOR_LANGUAGE,
23
- CODE_EDITOR_THEME,
24
23
  getBaseCodeEditorOptions,
24
+ getCodeEditorThemeForAppTheme,
25
25
  } from '@finos/legend-code-editor';
26
26
  import {
27
27
  editor as monacoEditorAPI,
@@ -79,10 +79,11 @@ export const PlaygroundSQLCodeEditor = observer(
79
79
  playgroundState.setTheme(enableDarkMode ? 'dark' : 'light');
80
80
  const newEditor = monacoEditorAPI.create(element, {
81
81
  ...getBaseCodeEditorOptions(),
82
- theme:
83
- playgroundState.theme === 'light'
84
- ? CODE_EDITOR_THEME.GITHUB_LIGHT
85
- : CODE_EDITOR_THEME.DEFAULT_DARK,
82
+ // NOTE: Monaco themes are global, so this theme applies to every
83
+ // editor on the page and must match the application's theme
84
+ theme: getCodeEditorThemeForAppTheme(
85
+ playgroundState.theme === 'light',
86
+ ),
86
87
  language: CODE_EDITOR_LANGUAGE.SQL,
87
88
  padding: {
88
89
  top: 10,
package/src/index.ts CHANGED
@@ -53,6 +53,7 @@ export {
53
53
  getTDSColumnDerivedProperyFromType,
54
54
  buildTDSSortTypeExpression,
55
55
  } from './stores/fetch-structure/tds/QueryBuilderTDSHelper.js';
56
+ export { QueryBuilderTDSState } from './stores/fetch-structure/tds/QueryBuilderTDSState.js';
56
57
  export { type ExportDataInfo } from './stores/QueryBuilderResultState.js';
57
58
  export { QueryBuilderPropertySearchState } from './stores/explorer/QueryBuilderPropertySearchState.js';
58
59
  export {
@@ -264,7 +264,8 @@ export const isTypeCompatibleForAssignment = (
264
264
  // This is because we would simulate auto-boxing for date by altering the
265
265
  // Pure function used for the operation
266
266
  // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is()
267
- DATE_PRIMITIVE_TYPES.includes(normalizedTypePath) ||
267
+ (DATE_PRIMITIVE_TYPES.includes(normalizedTypePath) &&
268
+ DATE_PRIMITIVE_TYPES.includes(normalizedAssignmentTypePath)) ||
268
269
  normalizedTypePath === normalizedAssignmentTypePath ||
269
270
  isSuperType(assignmentType, type)
270
271
  );
@@ -41,6 +41,7 @@ import {
41
41
  buildNotExpression,
42
42
  getCollectionValueSpecificationType,
43
43
  getStandardPrimitiveTypeEquivalent,
44
+ isTypeCompatibleForAssignment,
44
45
  unwrapNotExpression,
45
46
  } from '../../QueryBuilderValueSpecificationHelper.js';
46
47
  import { type Hashable, hashArray } from '@finos/legend-shared';
@@ -141,7 +142,12 @@ export class QueryBuilderFilterOperator_In
141
142
  if (valueSpec.multiplicity.upperBound === 1) {
142
143
  return false;
143
144
  }
144
- return propertyType === valueSpec.genericType?.value.rawType;
145
+ const variableType = valueSpec.genericType?.value.rawType;
146
+ // NOTE: use the same loose, numeric/date-family aware check as value assignment,
147
+ // so e.g. an `Integer[*]` parameter is still recognized as compatible with
148
+ // an `Integer` property even when the two don't resolve to the exact same
149
+ // `Type` instance (this can happen when the parameter is parsed from PURE text)
150
+ return isTypeCompatibleForAssignment(variableType, propertyType);
145
151
  }
146
152
  }
147
153
  return false;
@@ -34,6 +34,25 @@ export abstract class QueryBuilderWorkflowState {
34
34
  state: QueryBuilderState,
35
35
  ): FetchStructureLayoutConfig;
36
36
 
37
+ /**
38
+ * Whether the header shows its Advanced and Help menus; a workflow that
39
+ * embeds the query builder for a part of a query, e.g. a Legend Cube data
40
+ * space source, hides them
41
+ */
42
+ get showHeaderMenus(): boolean {
43
+ return true;
44
+ }
45
+
46
+ /** Whether a projection column can be given an aggregate operator */
47
+ get showProjectionAggregation(): boolean {
48
+ return true;
49
+ }
50
+
51
+ /** Whether the projection shows its query options: sort, distinct, limit and dates */
52
+ get showQueryOptions(): boolean {
53
+ return true;
54
+ }
55
+
37
56
  updateActionConfig(actionConfig: QueryBuilderActionConfig): void {
38
57
  this.actionConfig = actionConfig;
39
58
  }