@finos/legend-query-builder 4.14.30 → 4.14.32

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 (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
  );