@finos/legend-query-builder 4.14.30 → 4.14.32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. package/lib/components/QueryBuilder.d.ts +1 -1
  2. package/lib/components/QueryBuilder.d.ts.map +1 -1
  3. package/lib/components/QueryBuilder.js +36 -3
  4. package/lib/components/QueryBuilder.js.map +1 -1
  5. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts +3 -3
  6. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  7. package/lib/components/QueryBuilderPropertyExpressionEditor.js +23 -15
  8. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  9. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +1 -1
  10. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  11. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  12. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js +5 -10
  13. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  15. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +7 -7
  16. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  17. package/lib/graph/QueryBuilderMetaModelConst.d.ts +3 -0
  18. package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
  19. package/lib/graph/QueryBuilderMetaModelConst.js +5 -0
  20. package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
  21. package/lib/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js +4 -1
  22. package/lib/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js.map +1 -1
  23. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts +1 -0
  24. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts.map +1 -1
  25. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js +51 -3
  26. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js.map +1 -1
  27. package/lib/index.css +17 -1
  28. package/lib/index.css.map +1 -1
  29. package/lib/index.d.ts +1 -1
  30. package/lib/index.d.ts.map +1 -1
  31. package/lib/index.js +1 -1
  32. package/lib/index.js.map +1 -1
  33. package/lib/package.json +1 -1
  34. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  35. package/lib/stores/QueryBuilderResultState.js +1 -0
  36. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  37. package/lib/stores/QueryBuilderState.d.ts +4 -1
  38. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  39. package/lib/stores/QueryBuilderState.js +12 -1
  40. package/lib/stores/QueryBuilderState.js.map +1 -1
  41. package/lib/stores/QueryBuilderStateBuilder.d.ts +2 -1
  42. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  43. package/lib/stores/QueryBuilderStateBuilder.js +40 -5
  44. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  45. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts +5 -0
  46. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
  47. package/lib/stores/__test-utils__/QueryBuilderStateTestUtils.js +1 -1
  48. package/lib/stores/__test-utils__/QueryBuilderStateTestUtils.js.map +1 -1
  49. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts +1 -0
  50. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts.map +1 -1
  51. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  52. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.d.ts +2 -1
  53. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.d.ts.map +1 -1
  54. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.js +7 -0
  55. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.js.map +1 -1
  56. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +1 -0
  57. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  58. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +4 -0
  59. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  60. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.d.ts +2 -0
  61. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.d.ts.map +1 -0
  62. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.js +2 -0
  63. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.js.map +1 -0
  64. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +1 -0
  65. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  66. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +4 -0
  67. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  68. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts +3 -3
  69. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
  70. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +9 -2
  71. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
  72. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts +2 -9
  73. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
  74. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +45 -36
  75. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
  76. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.d.ts +20 -0
  77. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.d.ts.map +1 -0
  78. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.js +55 -0
  79. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.js.map +1 -0
  80. package/{src/stores/workflow/QueryBuilderWorkFlowState.ts → lib/stores/fetch-structure/tds/projection/QueryBuilderTypedProjectionStateBuilder.d.ts} +5 -12
  81. package/lib/stores/fetch-structure/tds/projection/QueryBuilderTypedProjectionStateBuilder.d.ts.map +1 -0
  82. package/lib/stores/fetch-structure/tds/projection/QueryBuilderTypedProjectionStateBuilder.js +54 -0
  83. package/lib/stores/fetch-structure/tds/projection/QueryBuilderTypedProjectionStateBuilder.js.map +1 -0
  84. package/lib/stores/{workflow → query-workflow}/QueryBuilderWorkFlowState.d.ts +12 -0
  85. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts.map +1 -0
  86. package/lib/stores/{workflow → query-workflow}/QueryBuilderWorkFlowState.js +18 -0
  87. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js.map +1 -0
  88. package/lib/stores/workflows/FunctionQueryBuilderState.d.ts +1 -1
  89. package/lib/stores/workflows/FunctionQueryBuilderState.d.ts.map +1 -1
  90. package/lib/stores/workflows/MappingQueryBuilderState.d.ts +1 -1
  91. package/lib/stores/workflows/MappingQueryBuilderState.d.ts.map +1 -1
  92. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts +1 -1
  93. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts.map +1 -1
  94. package/package.json +4 -4
  95. package/src/components/QueryBuilder.tsx +77 -2
  96. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +34 -20
  97. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +1 -1
  98. package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +29 -29
  99. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +9 -16
  100. package/src/graph/QueryBuilderMetaModelConst.ts +7 -0
  101. package/src/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.ts +3 -3
  102. package/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts +122 -1
  103. package/src/index.ts +1 -1
  104. package/src/stores/QueryBuilderResultState.ts +1 -0
  105. package/src/stores/QueryBuilderState.ts +17 -1
  106. package/src/stores/QueryBuilderStateBuilder.ts +83 -10
  107. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +5 -0
  108. package/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts +1 -1
  109. package/src/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.ts +1 -0
  110. package/src/stores/fetch-structure/QueryBuilderFetchStructureState.ts +15 -0
  111. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +5 -0
  112. package/src/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.ts +0 -0
  113. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +5 -0
  114. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +9 -2
  115. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +90 -81
  116. package/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts +108 -0
  117. package/src/stores/fetch-structure/tds/projection/QueryBuilderTypedProjectionStateBuilder.ts +103 -0
  118. package/src/stores/query-workflow/QueryBuilderWorkFlowState.ts +64 -0
  119. package/src/stores/workflows/FunctionQueryBuilderState.ts +1 -1
  120. package/src/stores/workflows/MappingQueryBuilderState.ts +1 -1
  121. package/src/stores/workflows/ServiceQueryBuilderState.ts +1 -1
  122. package/tsconfig.json +4 -1
  123. package/lib/stores/workflow/QueryBuilderWorkFlowState.d.ts.map +0 -1
  124. package/lib/stores/workflow/QueryBuilderWorkFlowState.js.map +0 -1
@@ -37,6 +37,7 @@ import {
37
37
  import { observer } from 'mobx-react-lite';
38
38
  import {
39
39
  generateValueSpecificationForParameter,
40
+ getPropertyChainName,
40
41
  type QueryBuilderDerivedPropertyExpressionState,
41
42
  type QueryBuilderPropertyExpressionState,
42
43
  } from '../stores/QueryBuilderPropertyEditorState.js';
@@ -382,15 +383,16 @@ export const QueryBuilderPropertyExpressionEditor = observer(
382
383
  export const QueryBuilderEditablePropertyName = observer(
383
384
  (props: {
384
385
  columnName: string;
385
- changeColumnName?:
386
- | ((event: ChangeEvent<HTMLInputElement>) => void)
387
- | undefined;
386
+ setColumnName?: ((columnName: string) => void) | undefined;
388
387
  error: string | undefined;
389
388
  title: string;
389
+ defaultColumnName: string;
390
390
  }) => {
391
- const { columnName, changeColumnName, error, title } = props;
391
+ const { columnName, setColumnName, error, title, defaultColumnName } =
392
+ props;
392
393
 
393
394
  const [isEditingColumnName, setIsEditingColumnName] = useState(false);
395
+ const [selectedColumnName, setSelectedColumnName] = useState(columnName);
394
396
  const columnNameInputRef = useRef<HTMLInputElement>(null);
395
397
 
396
398
  useEffect(() => {
@@ -399,26 +401,33 @@ export const QueryBuilderEditablePropertyName = observer(
399
401
  }
400
402
  }, [isEditingColumnName, columnNameInputRef]);
401
403
 
404
+ const handleFinishEditing = (): void => {
405
+ const trimmedSelectedColumnName = selectedColumnName.trim();
406
+ if (trimmedSelectedColumnName.length > 0) {
407
+ setColumnName?.(trimmedSelectedColumnName);
408
+ setSelectedColumnName(trimmedSelectedColumnName);
409
+ } else {
410
+ setColumnName?.(defaultColumnName);
411
+ setSelectedColumnName(defaultColumnName);
412
+ }
413
+ setIsEditingColumnName(false);
414
+ };
415
+
402
416
  return isEditingColumnName ? (
403
417
  <div className="query-builder__property__name__editor">
404
418
  <InputWithInlineValidation
405
419
  className="query-builder__property__name__editor__input input-group__input"
406
420
  spellCheck={false}
407
- value={columnName}
408
- onChange={changeColumnName}
421
+ value={selectedColumnName}
422
+ onChange={(event: ChangeEvent<HTMLInputElement>) =>
423
+ setSelectedColumnName(event.target.value)
424
+ }
409
425
  onKeyDown={(event: React.KeyboardEvent<HTMLInputElement>) => {
410
426
  if (event.key === 'Enter') {
411
- if (columnName.length > 0) {
412
- setIsEditingColumnName(false);
413
- }
414
- }
415
- }}
416
- onBlur={() => {
417
- if (columnName.length > 0) {
418
- setIsEditingColumnName(false);
427
+ handleFinishEditing();
419
428
  }
420
429
  }}
421
- error={error}
430
+ onBlur={handleFinishEditing}
422
431
  ref={columnNameInputRef}
423
432
  draggable={true}
424
433
  onDragStart={(e: React.DragEvent<HTMLInputElement>) => {
@@ -434,10 +443,10 @@ export const QueryBuilderEditablePropertyName = observer(
434
443
  <span
435
444
  className={clsx('query-builder__property__name__display__content', {
436
445
  'query-builder__property__name__display__content--error': error,
437
- 'editable-value': changeColumnName,
446
+ 'editable-value': setColumnName,
438
447
  })}
439
448
  onClick={() => {
440
- if (changeColumnName) {
449
+ if (setColumnName) {
441
450
  setIsEditingColumnName(true);
442
451
  }
443
452
  }}
@@ -456,14 +465,14 @@ export const QueryBuilderPropertyExpressionBadge = observer(
456
465
  onPropertyExpressionChange: (
457
466
  node: QueryBuilderExplorerTreePropertyNodeData,
458
467
  ) => void;
459
- changeColumnName?: (event: ChangeEvent<HTMLInputElement>) => void;
468
+ setColumnName?: (columnName: string) => void;
460
469
  error?: string | undefined;
461
470
  }) => {
462
471
  const {
463
472
  columnName,
464
473
  propertyExpressionState,
465
474
  onPropertyExpressionChange,
466
- changeColumnName,
475
+ setColumnName,
467
476
  error,
468
477
  } = props;
469
478
  const type =
@@ -529,9 +538,14 @@ export const QueryBuilderPropertyExpressionBadge = observer(
529
538
  >
530
539
  <QueryBuilderEditablePropertyName
531
540
  columnName={columnName ?? propertyExpressionState.title}
532
- changeColumnName={changeColumnName}
541
+ setColumnName={setColumnName}
533
542
  error={error}
534
543
  title={`${propertyExpressionState.title} - ${propertyExpressionState.path}`}
544
+ defaultColumnName={getPropertyChainName(
545
+ propertyExpressionState.propertyExpression,
546
+ propertyExpressionState.queryBuilderState.explorerState
547
+ .humanizePropertyName,
548
+ )}
535
549
  />
536
550
  {hasDerivedPropertyInExpression && (
537
551
  <button
@@ -51,7 +51,7 @@ import {
51
51
  } from '../../stores/__test-utils__/QueryBuilderStateTestUtils.js';
52
52
  import { STYLE_PREFIX, STYLE_PREFIX__DARK } from '@finos/legend-art';
53
53
  import { expect } from '@jest/globals';
54
- import { QueryBuilderAdvancedWorkflowState } from '../../stores/workflow/QueryBuilderWorkFlowState.js';
54
+ import { QueryBuilderAdvancedWorkflowState } from '../../stores/query-workflow/QueryBuilderWorkFlowState.js';
55
55
 
56
56
  const getSelectorContainerClassName = (lightMode?: boolean): string =>
57
57
  '.' + `${lightMode ? STYLE_PREFIX : STYLE_PREFIX__DARK}__value-container`;
@@ -32,6 +32,7 @@ import { QueryBuilderGraphFetchTreeState } from '../../stores/fetch-structure/gr
32
32
  import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
33
33
  import { FETCH_STRUCTURE_IMPLEMENTATION } from '../../stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js';
34
34
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
35
+ import { onChangeFetchStructureImplementation } from '../../stores/fetch-structure/QueryBuilderFetchStructureState.js';
35
36
 
36
37
  const QueryBuilderFetchStructureEditor = observer(
37
38
  (props: { queryBuilderState: QueryBuilderState }) => {
@@ -68,24 +69,18 @@ export const QueryBuilderFetchStructurePanel = observer(
68
69
  (props: { queryBuilderState: QueryBuilderState }) => {
69
70
  const { queryBuilderState } = props;
70
71
  const fetchStructureState = queryBuilderState.fetchStructureState;
71
-
72
- const onChangeFetchStructureImplementation =
73
- (implementationType: FETCH_STRUCTURE_IMPLEMENTATION): (() => void) =>
74
- (): void => {
75
- if (fetchStructureState.implementation.type !== implementationType) {
76
- fetchStructureState.implementation.checkBeforeChangingImplementation(
77
- () => {
78
- fetchStructureState.changeImplementation(implementationType);
79
- },
80
- );
81
- }
82
- };
72
+ const fetchConfig =
73
+ queryBuilderState.workflowState.getFetchStructureLayoutConfig(
74
+ queryBuilderState,
75
+ );
83
76
 
84
77
  return (
85
78
  <Panel data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FETCH_STRUCTURE}>
86
79
  <PanelHeader>
87
80
  <div className="panel__header__title">
88
- <div className="panel__header__title__label">fetch structure</div>
81
+ <div className="panel__header__title__label">
82
+ {fetchConfig.label}
83
+ </div>
89
84
  {fetchStructureState.implementation.fetchStructureValidationIssues
90
85
  .length !== 0 && (
91
86
  <QueryBuilderPanelIssueCountBadge
@@ -96,22 +91,27 @@ export const QueryBuilderFetchStructurePanel = observer(
96
91
  />
97
92
  )}
98
93
  </div>
99
- <PanelHeaderActions>
100
- <div className="query-builder__fetch__structure__modes">
101
- {Object.values(FETCH_STRUCTURE_IMPLEMENTATION).map((type) => (
102
- <button
103
- onClick={onChangeFetchStructureImplementation(type)}
104
- className={clsx('query-builder__fetch__structure__mode', {
105
- 'query-builder__fetch__structure__mode--selected':
106
- type === fetchStructureState.implementation.type,
107
- })}
108
- key={type}
109
- >
110
- {prettyCONSTName(type)}
111
- </button>
112
- ))}
113
- </div>
114
- </PanelHeaderActions>
94
+ {fetchConfig.showInFetchPanel ? (
95
+ <PanelHeaderActions>
96
+ <div className="query-builder__fetch__structure__modes">
97
+ {Object.values(FETCH_STRUCTURE_IMPLEMENTATION).map((type) => (
98
+ <button
99
+ onClick={onChangeFetchStructureImplementation(
100
+ type,
101
+ fetchStructureState,
102
+ )}
103
+ className={clsx('query-builder__fetch__structure__mode', {
104
+ 'query-builder__fetch__structure__mode--selected':
105
+ type === fetchStructureState.implementation.type,
106
+ })}
107
+ key={type}
108
+ >
109
+ {prettyCONSTName(type)}
110
+ </button>
111
+ ))}
112
+ </div>
113
+ </PanelHeaderActions>
114
+ ) : null}
115
115
  </PanelHeader>
116
116
  <QueryBuilderFetchStructureEditor
117
117
  queryBuilderState={queryBuilderState}
@@ -14,14 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import {
18
- useEffect,
19
- useRef,
20
- useCallback,
21
- useState,
22
- forwardRef,
23
- type ChangeEvent,
24
- } from 'react';
17
+ import { useEffect, useRef, useCallback, useState, forwardRef } from 'react';
25
18
  import { observer } from 'mobx-react-lite';
26
19
  import {
27
20
  clsx,
@@ -161,10 +154,10 @@ const QueryBuilderProjectionColumnContextMenu = observer(
161
154
  const QueryBuilderSimpleProjectionColumnEditor = observer(
162
155
  (props: {
163
156
  projectionColumnState: QueryBuilderSimpleProjectionColumnState;
164
- changeColumnName: (event: ChangeEvent<HTMLInputElement>) => void;
157
+ setColumnName: (columnName: string) => void;
165
158
  error?: string | undefined;
166
159
  }) => {
167
- const { projectionColumnState, changeColumnName, error } = props;
160
+ const { projectionColumnState, setColumnName, error } = props;
168
161
  const onPropertyExpressionChange = (
169
162
  node: QueryBuilderExplorerTreePropertyNodeData,
170
163
  ): void =>
@@ -179,7 +172,7 @@ const QueryBuilderSimpleProjectionColumnEditor = observer(
179
172
  columnName={projectionColumnState.columnName}
180
173
  propertyExpressionState={projectionColumnState.propertyExpressionState}
181
174
  onPropertyExpressionChange={onPropertyExpressionChange}
182
- changeColumnName={changeColumnName}
175
+ setColumnName={setColumnName}
183
176
  error={error}
184
177
  />
185
178
  );
@@ -391,9 +384,8 @@ const QueryBuilderProjectionColumnEditor = observer(
391
384
  tdsState.removeColumn(projectionColumnState);
392
385
 
393
386
  // name
394
- const changeColumnName: React.ChangeEventHandler<HTMLInputElement> = (
395
- event,
396
- ) => projectionColumnState.setColumnName(event.target.value);
387
+ const setColumnName = (columnName: string): void =>
388
+ projectionColumnState.setColumnName(columnName);
397
389
  const isDuplicatedColumnName =
398
390
  projectionColumnState.tdsState.isDuplicateColumn(projectionColumnState);
399
391
 
@@ -787,7 +779,7 @@ const QueryBuilderProjectionColumnEditor = observer(
787
779
  <div className="query-builder__projection__column__value">
788
780
  <QueryBuilderSimpleProjectionColumnEditor
789
781
  projectionColumnState={projectionColumnState}
790
- changeColumnName={changeColumnName}
782
+ setColumnName={setColumnName}
791
783
  error={
792
784
  isDuplicatedColumnName
793
785
  ? 'Duplicated column'
@@ -814,7 +806,7 @@ const QueryBuilderProjectionColumnEditor = observer(
814
806
  <div className="query-builder__projection__column__value">
815
807
  <QueryBuilderEditablePropertyName
816
808
  columnName={projectionColumnState.columnName}
817
- changeColumnName={changeColumnName}
809
+ setColumnName={setColumnName}
818
810
  error={
819
811
  isDuplicatedColumnName
820
812
  ? 'Duplicated column'
@@ -823,6 +815,7 @@ const QueryBuilderProjectionColumnEditor = observer(
823
815
  : undefined
824
816
  }
825
817
  title={projectionColumnState.columnName}
818
+ defaultColumnName="(derivation)"
826
819
  />
827
820
  <QueryBuilderDerivationProjectionColumnEditor
828
821
  projectionColumnState={projectionColumnState}
@@ -24,6 +24,8 @@ export enum QUERY_BUILDER_PURE_PATH {
24
24
  DURATION_UNIT = 'meta::pure::functions::date::DurationUnit',
25
25
  DAY_OF_WEEK = 'meta::pure::functions::date::DayOfWeek',
26
26
 
27
+ // RELATION
28
+ RELATION = 'meta::pure::metamodel::relation::Relation',
27
29
  // serialization
28
30
  SERIALIZE_CONFIG = 'meta::pure::graphFetch::execution::AlloySerializationConfig',
29
31
  }
@@ -31,6 +33,7 @@ export enum QUERY_BUILDER_PURE_PATH {
31
33
  export enum QUERY_BUILDER_SUPPORTED_CALENDAR_AGGREGATION_FUNCTIONS {
32
34
  CALENDAR_ANNUALIZED = 'meta::pure::functions::date::calendar::annualized',
33
35
  CALENDAR_CME = ' meta::pure::functions::date::calendar::cme',
36
+
34
37
  CALENDAR_CW = 'meta::pure::functions::date::calendar::cw',
35
38
  CALENDAR_CW_FM = 'meta::pure::functions::date::calendar::cw_fm',
36
39
  CALENDAR_CY_MINUS2 = 'meta::pure::functions::date::calendar::CYMinus2',
@@ -114,6 +117,10 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
114
117
  TDS_RESTRICT = 'meta::pure::tds::restrict',
115
118
  TDS_FUNC = 'meta::pure::tds::func',
116
119
 
120
+ // Relation
121
+ RELATION_PROJECT = 'meta::pure::functions::relation::project',
122
+ RELATION_LIMIT = 'meta::pure::functions::relation::limit',
123
+
117
124
  // filter
118
125
  CONTAINS = 'meta::pure::functions::string::contains',
119
126
  ENDS_WITH = 'meta::pure::functions::string::endsWith',
@@ -146,10 +146,10 @@ export class QueryBuilder_PureProtocolProcessorPlugin extends PureProtocolProces
146
146
  processingContext,
147
147
  );
148
148
  } else if (
149
- matchFunctionName(
150
- functionName,
149
+ matchFunctionName(functionName, [
151
150
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
152
- )
151
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_PROJECT,
152
+ ])
153
153
  ) {
154
154
  return V1_buildProjectFunctionExpression(
155
155
  functionName,
@@ -21,6 +21,7 @@ import {
21
21
  filterByType,
22
22
  guaranteeNonNullable,
23
23
  guaranteeType,
24
+ isNonNullable,
24
25
  returnUndefOnError,
25
26
  } from '@finos/legend-shared';
26
27
  import {
@@ -56,6 +57,11 @@ import {
56
57
  LambdaFunction,
57
58
  LambdaFunctionInstanceValue,
58
59
  PackageableElementExplicitReference,
60
+ V1_ClassInstance,
61
+ V1_ColSpecArray,
62
+ ColSpecArrayInstance,
63
+ ColSpecArray,
64
+ ColSpec,
59
65
  } from '@finos/legend-graph';
60
66
  import {
61
67
  QUERY_BUILDER_PURE_PATH,
@@ -574,6 +580,110 @@ export const V1_buildFilterFunctionExpression = (
574
580
  return expression;
575
581
  };
576
582
 
583
+ export const V1_buildTypedProjectFunctionExpression = (
584
+ functionName: string,
585
+ parameters: V1_ValueSpecification[],
586
+ openVariables: string[],
587
+ compileContext: V1_GraphBuilderContext,
588
+ processingContext: V1_ProcessingContext,
589
+ ): SimpleFunctionExpression => {
590
+ assertTrue(
591
+ parameters.length === 2,
592
+ `Can't build relation project() expression: project() expects 2 arguments`,
593
+ );
594
+
595
+ let topLevelLambdaParameters: V1_Variable[] = [];
596
+ const precedingExperession = (
597
+ parameters[0] as V1_ValueSpecification
598
+ ).accept_ValueSpecificationVisitor(
599
+ new V1_ValueSpecificationBuilder(
600
+ compileContext,
601
+ processingContext,
602
+ openVariables,
603
+ ),
604
+ );
605
+ assertNonNullable(
606
+ precedingExperession.genericType,
607
+ `Can't build relation project() expression: preceding expression return type is missing`,
608
+ );
609
+
610
+ const classInstance = parameters[1];
611
+ assertType(
612
+ classInstance,
613
+ V1_ClassInstance,
614
+ `Can't build relation project() expression: project() expects argument #1 to be a ClassInstance`,
615
+ );
616
+ const specArray = guaranteeType(
617
+ classInstance.value,
618
+ V1_ColSpecArray,
619
+ `Can't build relation project() expression: project() expects argument #1 to hold spec array instances value`,
620
+ );
621
+
622
+ topLevelLambdaParameters = specArray.colSpecs
623
+ .map((e) => e.function1)
624
+ .filter(isNonNullable)
625
+ .filter(filterByType(V1_Lambda))
626
+ .map((lambda) => lambda.parameters)
627
+ .flat();
628
+
629
+ const variables = new Set<string>();
630
+ // Make sure top-level lambdas have their lambda parameter types set properly
631
+ topLevelLambdaParameters.forEach((variable) => {
632
+ if (!variables.has(variable.name) && !variable.class) {
633
+ const variableExpression = new VariableExpression(
634
+ variable.name,
635
+ precedingExperession.multiplicity,
636
+ );
637
+ variableExpression.genericType = precedingExperession.genericType;
638
+ processingContext.addInferredVariables(variable.name, variableExpression);
639
+ }
640
+ });
641
+ const processedExpression = new ColSpecArrayInstance(Multiplicity.ONE);
642
+ const processedColSpecArray = new ColSpecArray();
643
+ processedExpression.values = [processedColSpecArray];
644
+
645
+ processedColSpecArray.colSpecs = specArray.colSpecs.map((colSpec) => {
646
+ const pColSpec = new ColSpec();
647
+ let lambda: ValueSpecification;
648
+ const _funct = guaranteeType(
649
+ colSpec.function1,
650
+ V1_ValueSpecification,
651
+ `Can't build relation col spec() expression: expects function1 to be a lambda`,
652
+ );
653
+ try {
654
+ lambda = buildProjectionColumnLambda(
655
+ _funct,
656
+ openVariables,
657
+ compileContext,
658
+ processingContext,
659
+ );
660
+ } catch {
661
+ lambda = new INTERNAL__UnknownValueSpecification(
662
+ V1_serializeValueSpecification(
663
+ _funct,
664
+ compileContext.extensions.plugins,
665
+ ),
666
+ );
667
+ }
668
+ pColSpec.function1 = lambda;
669
+ pColSpec.name = colSpec.name;
670
+ return pColSpec;
671
+ });
672
+
673
+ const expression = V1_buildBaseSimpleFunctionExpression(
674
+ [precedingExperession, processedExpression],
675
+ functionName,
676
+ compileContext,
677
+ );
678
+ expression.genericType = GenericTypeExplicitReference.create(
679
+ new GenericType(
680
+ compileContext.resolveType(QUERY_BUILDER_PURE_PATH.RELATION).value,
681
+ ),
682
+ );
683
+
684
+ return expression;
685
+ };
686
+
577
687
  export const V1_buildProjectFunctionExpression = (
578
688
  functionName: string,
579
689
  parameters: V1_ValueSpecification[],
@@ -581,8 +691,19 @@ export const V1_buildProjectFunctionExpression = (
581
691
  compileContext: V1_GraphBuilderContext,
582
692
  processingContext: V1_ProcessingContext,
583
693
  ): SimpleFunctionExpression => {
694
+ if (parameters.length === 2) {
695
+ return V1_buildTypedProjectFunctionExpression(
696
+ functionName,
697
+ parameters,
698
+ openVariables,
699
+ compileContext,
700
+ processingContext,
701
+ );
702
+ }
703
+
704
+ const length = parameters.length;
584
705
  assertTrue(
585
- parameters.length === 3,
706
+ length === 3 || length === 2,
586
707
  `Can't build project() expression: project() expects 2 arguments`,
587
708
  );
588
709
 
package/src/index.ts CHANGED
@@ -93,4 +93,4 @@ export * from './stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
93
93
 
94
94
  export * from './stores/data-access/DataAccessState.js';
95
95
  export * from './components/data-access/DataAccessOverview.js';
96
- export * from './stores/workflow/QueryBuilderWorkFlowState.js';
96
+ export * from './stores/query-workflow/QueryBuilderWorkFlowState.js';
@@ -312,6 +312,7 @@ export class QueryBuilderResultState {
312
312
  if (this.queryBuilderState.isQuerySupported) {
313
313
  const lambdaFunction = buildLambdaFunction(this.queryBuilderState, {
314
314
  isBuildingExecutionQuery: true,
315
+ useTypedRelationFunctions: this.queryBuilderState.isFetchStructureTyped,
315
316
  ...executionOptions,
316
317
  });
317
318
  query = buildRawLambdaFromLambdaFunction(
@@ -109,7 +109,7 @@ import {
109
109
  import type { QueryBuilderConfig } from '../graph-manager/QueryBuilderConfig.js';
110
110
  import { QUERY_BUILDER_EVENT } from '../__lib__/QueryBuilderEvent.js';
111
111
  import { QueryBuilderChangeHistoryState } from './QueryBuilderChangeHistoryState.js';
112
- import { type QueryBuilderWorkflowState } from './workflow/QueryBuilderWorkFlowState.js';
112
+ import { type QueryBuilderWorkflowState } from './query-workflow/QueryBuilderWorkFlowState.js';
113
113
 
114
114
  export interface QuerySDLC {}
115
115
 
@@ -157,6 +157,8 @@ export abstract class QueryBuilderState implements CommandRegistrar {
157
157
  isQueryChatOpened = false;
158
158
  isLocalModeEnabled = false;
159
159
 
160
+ lambdaWriteMode = QUERY_BUILDER_LAMBDA_WRITER_MODE.STANDARD;
161
+
160
162
  class?: Class | undefined;
161
163
  getAllFunction: QUERY_BUILDER_SUPPORTED_GET_ALL_FUNCTIONS =
162
164
  QUERY_BUILDER_SUPPORTED_GET_ALL_FUNCTIONS.GET_ALL;
@@ -204,6 +206,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
204
206
  isQueryChatOpened: observable,
205
207
  isLocalModeEnabled: observable,
206
208
  getAllFunction: observable,
209
+ lambdaWriteMode: observable,
207
210
 
208
211
  sideBarClassName: computed,
209
212
  isQuerySupported: computed,
@@ -218,6 +221,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
218
221
  setIsQueryChatOpened: action,
219
222
  setIsLocalModeEnabled: action,
220
223
  setGetAllFunction: action,
224
+ setLambdaWriteMode: action,
221
225
 
222
226
  resetQueryResult: action,
223
227
  resetQueryContent: action,
@@ -300,6 +304,17 @@ export abstract class QueryBuilderState implements CommandRegistrar {
300
304
  return this.allVariables.map((e) => e.name);
301
305
  }
302
306
 
307
+ get isFetchStructureTyped(): boolean {
308
+ return (
309
+ this.lambdaWriteMode ===
310
+ QUERY_BUILDER_LAMBDA_WRITER_MODE.TYPED_FETCH_STRUCTURE
311
+ );
312
+ }
313
+
314
+ setLambdaWriteMode(val: QUERY_BUILDER_LAMBDA_WRITER_MODE): void {
315
+ this.lambdaWriteMode = val;
316
+ }
317
+
303
318
  getQueryExecutionContext(): QueryExecutionContext {
304
319
  const queryExeContext = new QueryExplicitExecutionContext();
305
320
  const runtimeValue = guaranteeType(
@@ -538,6 +553,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
538
553
  return buildRawLambdaFromLambdaFunction(
539
554
  buildLambdaFunction(this, {
540
555
  keepSourceInformation: Boolean(options?.keepSourceInformation),
556
+ useTypedRelationFunctions: this.isFetchStructureTyped,
541
557
  }),
542
558
  this.graphManagerState,
543
559
  );