@finos/legend-query-builder 4.1.2 → 4.1.3

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 (98) hide show
  1. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  2. package/lib/components/QueryBuilderPropertyExpressionEditor.js +1 -1
  3. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  4. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  5. package/lib/components/QueryBuilderResultPanel.js +91 -24
  6. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  7. package/lib/components/execution-plan/AllocationExecutionNodeViewer.d.ts +23 -0
  8. package/lib/components/execution-plan/AllocationExecutionNodeViewer.d.ts.map +1 -0
  9. package/lib/components/execution-plan/AllocationExecutionNodeViewer.js +32 -0
  10. package/lib/components/execution-plan/AllocationExecutionNodeViewer.js.map +1 -0
  11. package/lib/components/execution-plan/ConstantExecutionNodeViewer.d.ts +23 -0
  12. package/lib/components/execution-plan/ConstantExecutionNodeViewer.d.ts.map +1 -0
  13. package/lib/components/execution-plan/ConstantExecutionNodeViewer.js +35 -0
  14. package/lib/components/execution-plan/ConstantExecutionNodeViewer.js.map +1 -0
  15. package/lib/components/execution-plan/DataTypeResultTypeViewer.d.ts +21 -0
  16. package/lib/components/execution-plan/DataTypeResultTypeViewer.d.ts.map +1 -0
  17. package/lib/components/execution-plan/DataTypeResultTypeViewer.js +31 -0
  18. package/lib/components/execution-plan/DataTypeResultTypeViewer.js.map +1 -0
  19. package/lib/components/execution-plan/ExecutionPlanViewer.d.ts +10 -4
  20. package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
  21. package/lib/components/execution-plan/ExecutionPlanViewer.js +74 -62
  22. package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
  23. package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.d.ts +25 -0
  24. package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.d.ts.map +1 -0
  25. package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.js +47 -0
  26. package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.js.map +1 -0
  27. package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.d.ts +23 -0
  28. package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.d.ts.map +1 -0
  29. package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.js +31 -0
  30. package/lib/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.js.map +1 -0
  31. package/lib/components/execution-plan/ResultTypeViewer.d.ts +21 -0
  32. package/lib/components/execution-plan/ResultTypeViewer.d.ts.map +1 -0
  33. package/lib/components/execution-plan/ResultTypeViewer.js +33 -0
  34. package/lib/components/execution-plan/ResultTypeViewer.js.map +1 -0
  35. package/lib/components/execution-plan/SQLExecutionNodeViewer.d.ts +9 -1
  36. package/lib/components/execution-plan/SQLExecutionNodeViewer.d.ts.map +1 -1
  37. package/lib/components/execution-plan/SQLExecutionNodeViewer.js +12 -6
  38. package/lib/components/execution-plan/SQLExecutionNodeViewer.js.map +1 -1
  39. package/lib/components/execution-plan/SequenceExecutionNodeViewer.d.ts +23 -0
  40. package/lib/components/execution-plan/SequenceExecutionNodeViewer.d.ts.map +1 -0
  41. package/lib/components/execution-plan/SequenceExecutionNodeViewer.js +38 -0
  42. package/lib/components/execution-plan/SequenceExecutionNodeViewer.js.map +1 -0
  43. package/lib/components/execution-plan/TDSResultTypeViewer.d.ts +21 -0
  44. package/lib/components/execution-plan/TDSResultTypeViewer.d.ts.map +1 -0
  45. package/lib/components/execution-plan/TDSResultTypeViewer.js +25 -0
  46. package/lib/components/execution-plan/TDSResultTypeViewer.js.map +1 -0
  47. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  48. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +3 -3
  49. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  50. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  51. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +24 -34
  52. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  53. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  54. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +44 -11
  55. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  56. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  57. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +4 -4
  58. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  59. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  60. package/lib/components/filter/QueryBuilderFilterPanel.js +20 -32
  61. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  62. package/lib/index.css +2 -2
  63. package/lib/index.css.map +1 -1
  64. package/lib/package.json +1 -1
  65. package/lib/stores/QueryBuilderResultState.d.ts +0 -3
  66. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  67. package/lib/stores/QueryBuilderResultState.js +2 -25
  68. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  69. package/lib/stores/execution-plan/ExecutionPlanState.d.ts +14 -1
  70. package/lib/stores/execution-plan/ExecutionPlanState.d.ts.map +1 -1
  71. package/lib/stores/execution-plan/ExecutionPlanState.js +86 -3
  72. package/lib/stores/execution-plan/ExecutionPlanState.js.map +1 -1
  73. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +3 -0
  74. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  75. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +11 -0
  76. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  77. package/package.json +5 -5
  78. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +1 -2
  79. package/src/components/QueryBuilderResultPanel.tsx +146 -30
  80. package/src/components/execution-plan/AllocationExecutionNodeViewer.tsx +77 -0
  81. package/src/components/execution-plan/ConstantExecutionNodeViewer.tsx +82 -0
  82. package/src/components/execution-plan/DataTypeResultTypeViewer.tsx +52 -0
  83. package/src/components/execution-plan/ExecutionPlanViewer.tsx +205 -195
  84. package/src/components/execution-plan/FunctionParametersValidationNodeViewer.tsx +118 -0
  85. package/src/components/execution-plan/RelationalTDSInstantiationExecutionNodeViewer.tsx +68 -0
  86. package/src/components/execution-plan/ResultTypeViewer.tsx +37 -0
  87. package/src/components/execution-plan/SQLExecutionNodeViewer.tsx +50 -19
  88. package/src/components/execution-plan/SequenceExecutionNodeViewer.tsx +95 -0
  89. package/src/components/execution-plan/TDSResultTypeViewer.tsx +59 -0
  90. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +5 -8
  91. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +32 -61
  92. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +77 -14
  93. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +6 -8
  94. package/src/components/filter/QueryBuilderFilterPanel.tsx +45 -73
  95. package/src/stores/QueryBuilderResultState.ts +1 -42
  96. package/src/stores/execution-plan/ExecutionPlanState.ts +142 -4
  97. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +16 -0
  98. package/tsconfig.json +8 -0
@@ -14,10 +14,9 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { useState } from 'react';
17
+ import { useEffect } from 'react';
18
18
  import {
19
19
  type TreeNodeContainerProps,
20
- type TreeData,
21
20
  Dialog,
22
21
  ResizablePanelGroup,
23
22
  ResizablePanelSplitter,
@@ -41,16 +40,13 @@ import {
41
40
  PanelHeader,
42
41
  Panel,
43
42
  } from '@finos/legend-art';
44
- import {
45
- addUniqueEntry,
46
- filterByType,
47
- isNonNullable,
48
- } from '@finos/legend-shared';
43
+ import { isNonNullable } from '@finos/legend-shared';
49
44
  import {
50
45
  ExecutionNodeTreeNodeData,
51
46
  ExecutionPlanViewTreeNodeData,
52
47
  EXECUTION_PLAN_VIEW_MODE,
53
48
  type ExecutionPlanState,
49
+ generateExecutionNodeTreeNodeData,
54
50
  } from '../../stores/execution-plan/ExecutionPlanState.js';
55
51
  import { observer } from 'mobx-react-lite';
56
52
  import {
@@ -58,225 +54,182 @@ import {
58
54
  ExecutionNode,
59
55
  SQLExecutionNode,
60
56
  RelationalTDSInstantiationExecutionNode,
57
+ FunctionParametersValidationNode,
58
+ AllocationExecutionNode,
59
+ ConstantExecutionNode,
60
+ SequenceExecutionNode,
61
61
  type RawExecutionPlan,
62
62
  } from '@finos/legend-graph';
63
63
  import { SQLExecutionNodeViewer } from './SQLExecutionNodeViewer.js';
64
+ import { FunctionParametersValidationNodeViewer } from './FunctionParametersValidationNodeViewer.js';
65
+ import { AllocationExecutionNodeViewer } from './AllocationExecutionNodeViewer.js';
66
+ import { ConstantExecutionNodeViewer } from './ConstantExecutionNodeViewer.js';
67
+ import { SequenceExecutionNodeViewer } from './SequenceExecutionNodeViewer.js';
68
+ import { RelationalTDSInstantiationExecutionNodeViewer } from './RelationalTDSInstantiationExecutionNodeViewer.js';
64
69
  import {
65
70
  CODE_EDITOR_LANGUAGE,
66
71
  CodeEditor,
67
72
  } from '@finos/legend-lego/code-editor';
68
73
  import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
69
74
 
75
+ const EXECUTION_PLAN = 'Execution Plan';
70
76
  /**
71
77
  * @modularize
72
78
  * See https://github.com/finos/legend-studio/issues/65
73
79
  */
74
- const generateExecutionNodeLabel = (type: ExecutionNode): string => {
80
+ export const generateExecutionNodeLabel = (type: ExecutionNode): string => {
75
81
  if (type instanceof SQLExecutionNode) {
76
82
  return `SQL Execution Node`;
77
83
  } else if (type instanceof RelationalTDSInstantiationExecutionNode) {
78
84
  return `Relational TDS Instantiation Execution Node`;
85
+ } else if (type instanceof FunctionParametersValidationNode) {
86
+ return `Function Parameters Validation Node`;
87
+ } else if (type instanceof AllocationExecutionNode) {
88
+ return `Allocation Execution Node (${type.varName})`;
89
+ } else if (type instanceof ConstantExecutionNode) {
90
+ return `Constant Execution Node`;
91
+ } else if (type instanceof SequenceExecutionNode) {
92
+ return `Sequence Execution Node`;
79
93
  } else {
80
94
  return 'Other';
81
95
  }
82
96
  };
83
97
 
84
- const generateExecutionNodeTreeNodeData = (
85
- executionNode: ExecutionNode,
86
- label: string,
87
- parentNode:
88
- | ExecutionNodeTreeNodeData
89
- | ExecutionPlanViewTreeNodeData
90
- | undefined,
91
- ): ExecutionNodeTreeNodeData => {
92
- const executionNodeTreeNode = new ExecutionNodeTreeNodeData(
93
- executionNode._UUID,
94
- label,
95
- executionNode,
96
- );
97
-
98
- const childrenIds: string[] = [];
99
-
100
- executionNode.executionNodes
101
- .slice()
102
- .filter(filterByType(ExecutionNode))
103
- .forEach((childExecutionNode) => {
104
- addUniqueEntry(childrenIds, childExecutionNode._UUID);
105
- });
106
-
107
- executionNodeTreeNode.childrenIds = childrenIds;
108
-
109
- return executionNodeTreeNode;
110
- };
111
-
112
- const generateExecutionPlanTreeNodeData = (
113
- executionPlan: ExecutionPlan,
114
- ): ExecutionPlanViewTreeNodeData => {
115
- const executionPlanNode = new ExecutionPlanViewTreeNodeData(
116
- `Execution Plan`,
117
- `Execution Plan`,
118
- executionPlan,
119
- );
120
-
121
- const childrenIds: string[] = [];
122
-
123
- const rootNodeId = executionPlan.rootExecutionNode._UUID;
124
- addUniqueEntry(childrenIds, rootNodeId);
125
- executionPlanNode.childrenIds = childrenIds;
126
- return executionPlanNode;
127
- };
128
-
129
- const getExecutionPlanTreeData = (
130
- executionPlan: ExecutionPlan,
131
- ): TreeData<ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData> => {
132
- const rootIds: string[] = [];
133
- const nodes = new Map<
134
- string,
135
- ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData
136
- >();
137
- const executionPlanTreeNode =
138
- generateExecutionPlanTreeNodeData(executionPlan);
139
- addUniqueEntry(rootIds, executionPlanTreeNode.id);
140
- nodes.set(executionPlanTreeNode.id, executionPlanTreeNode);
141
- return { rootIds, nodes };
142
- };
143
-
144
- const ExecutionNodeElementTreeNodeContainer: React.FC<
145
- TreeNodeContainerProps<
146
- ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
147
- {
148
- onNodeExpand: (
149
- node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
150
- ) => void;
151
- }
152
- >
153
- > = (props) => {
154
- const { node, level, stepPaddingInRem, onNodeSelect, innerProps } = props;
155
- const { onNodeExpand } = innerProps;
156
- const isExpandable = Boolean(node.childrenIds?.length);
157
- const selectNode = (): void => onNodeSelect?.(node);
158
- const expandNode = (): void => onNodeExpand(node);
159
- const nodeExpandIcon = isExpandable ? (
160
- node.isOpen ? (
161
- <ChevronDownIcon />
98
+ const ExecutionNodeElementTreeNodeContainer = observer(
99
+ (
100
+ props: TreeNodeContainerProps<
101
+ ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
102
+ {
103
+ onNodeExpand: (
104
+ node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
105
+ ) => void;
106
+ }
107
+ >,
108
+ ) => {
109
+ const { node, level, stepPaddingInRem, onNodeSelect } = props;
110
+ const isExpandable = Boolean(node.childrenIds?.length);
111
+ const selectNode = (): void => onNodeSelect?.(node);
112
+ const nodeExpandIcon = isExpandable ? (
113
+ node.isOpen ? (
114
+ <ChevronDownIcon />
115
+ ) : (
116
+ <ChevronRightIcon />
117
+ )
162
118
  ) : (
163
- <ChevronRightIcon />
164
- )
165
- ) : (
166
- <div />
167
- );
168
-
169
- return (
170
- <div
171
- className={clsx(
172
- 'tree-view__node__container execution-plan-viewer__explorer-tree__node__container',
173
- {
174
- 'menu__trigger--on-menu-open': !node.isSelected,
175
- },
176
- {
177
- 'execution-plan-viewer__explorer-tree__node__container--selected':
178
- node.isSelected,
179
- },
180
- )}
181
- style={{
182
- paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1)}rem`,
183
- }}
184
- onClick={selectNode}
185
- >
186
- <div className="tree-view__node__icon">
187
- <div className="tree-view__node__expand-icon" onClick={expandNode}>
188
- {nodeExpandIcon}
119
+ <div />
120
+ );
121
+ return (
122
+ <div
123
+ className={clsx(
124
+ 'tree-view__node__container execution-plan-viewer__explorer-tree__node__container',
125
+ {
126
+ 'menu__trigger--on-menu-open': !node.isSelected,
127
+ },
128
+ {
129
+ 'execution-plan-viewer__explorer-tree__node__container--selected':
130
+ node.isSelected,
131
+ },
132
+ )}
133
+ style={{
134
+ paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1)}rem`,
135
+ }}
136
+ onClick={selectNode}
137
+ >
138
+ <div className="tree-view__node__icon">
139
+ <div className="tree-view__node__expand-icon">{nodeExpandIcon}</div>
189
140
  </div>
141
+ <button
142
+ className="tree-view__node__label execution-plan-viewer__explorer-tree__node__label"
143
+ tabIndex={-1}
144
+ title={node.id}
145
+ >
146
+ {node.label}
147
+ </button>
190
148
  </div>
191
- <button
192
- className="tree-view__node__label execution-plan-viewer__explorer-tree__node__label"
193
- tabIndex={-1}
194
- title={node.id}
195
- >
196
- {node.label}
197
- </button>
198
- </div>
199
- );
200
- };
201
-
202
- export const ExecutionPlanTree: React.FC<{
203
- executionPlanState: ExecutionPlanState;
204
- executionPlan: ExecutionPlan;
205
- }> = (props) => {
206
- const { executionPlanState, executionPlan } = props;
207
- // NOTE: We only need to compute this once so we use lazy initial state syntax
208
- // See https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
209
- const [treeData, setTreeData] = useState<
210
- TreeData<ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData>
211
- >(() => getExecutionPlanTreeData(executionPlan));
212
- const onNodeSelect = (
213
- node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
214
- ): void => {
215
- if (node instanceof ExecutionPlanViewTreeNodeData) {
216
- executionPlanState.transformMetadataToProtocolJson(node.executionPlan);
217
- } else if (node instanceof ExecutionNodeTreeNodeData) {
218
- executionPlanState.transformMetadataToProtocolJson(node.executionNode);
219
- }
220
- executionPlanState.setSelectedNode(node);
221
- };
149
+ );
150
+ },
151
+ );
222
152
 
223
- const onNodeExpand = (
224
- node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
225
- ): void => {
226
- if (node.childrenIds?.length) {
227
- node.isOpen = !node.isOpen;
228
- if (node instanceof ExecutionPlanViewTreeNodeData) {
229
- const rootNode = node.executionPlan.rootExecutionNode;
230
- const rootNodeTreeNode = generateExecutionNodeTreeNodeData(
231
- rootNode,
232
- generateExecutionNodeLabel(rootNode),
233
- node,
234
- );
235
- treeData.nodes.set(rootNodeTreeNode.id, rootNodeTreeNode);
236
- } else if (node instanceof ExecutionNodeTreeNodeData) {
237
- if (node.executionNode.executionNodes.length > 0) {
238
- node.executionNode.executionNodes.forEach((exen) => {
239
- const executionNodeTreeNode = generateExecutionNodeTreeNodeData(
240
- exen,
241
- generateExecutionNodeLabel(exen),
242
- node,
243
- );
153
+ export const ExecutionPlanTree = observer(
154
+ (props: {
155
+ executionPlanState: ExecutionPlanState;
156
+ executionPlan: ExecutionPlan;
157
+ }) => {
158
+ const { executionPlanState } = props;
244
159
 
245
- treeData.nodes.set(executionNodeTreeNode.id, executionNodeTreeNode);
246
- });
160
+ const onNodeExpand = (
161
+ node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
162
+ ): void => {
163
+ if (node.childrenIds?.length) {
164
+ node.setIsOpen(!node.isOpen);
165
+ if (node instanceof ExecutionPlanViewTreeNodeData) {
166
+ const rootNode = node.executionPlan.rootExecutionNode;
167
+ const rootNodeTreeNode = generateExecutionNodeTreeNodeData(
168
+ rootNode,
169
+ generateExecutionNodeLabel(rootNode),
170
+ node,
171
+ );
172
+ executionPlanState.setTreeNode(rootNodeTreeNode.id, rootNodeTreeNode);
173
+ } else if (node instanceof ExecutionNodeTreeNodeData) {
174
+ if (node.executionNode.executionNodes.length > 0) {
175
+ node.executionNode.executionNodes.forEach((exen) => {
176
+ const executionNodeTreeNode = generateExecutionNodeTreeNodeData(
177
+ exen,
178
+ generateExecutionNodeLabel(exen),
179
+ node,
180
+ );
181
+ executionPlanState.setTreeNode(
182
+ executionNodeTreeNode.id,
183
+ executionNodeTreeNode,
184
+ );
185
+ });
186
+ }
247
187
  }
248
188
  }
249
- }
250
189
 
251
- setTreeData({ ...treeData });
252
- };
190
+ executionPlanState.refreshTreeData();
191
+ };
253
192
 
254
- const getChildNodes = (
255
- node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
256
- ): (ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData)[] => {
257
- if (!node.childrenIds || node.childrenIds.length === 0) {
258
- return [];
259
- }
260
- const childrenNodes = node.childrenIds
261
- .map((id) => treeData.nodes.get(id))
262
- .filter(isNonNullable);
193
+ const onNodeSelect = (
194
+ node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
195
+ ): void => {
196
+ if (node instanceof ExecutionPlanViewTreeNodeData) {
197
+ executionPlanState.transformMetadataToProtocolJson(node.executionPlan);
198
+ } else if (node instanceof ExecutionNodeTreeNodeData) {
199
+ executionPlanState.transformMetadataToProtocolJson(node.executionNode);
200
+ }
201
+ if (!(node.isOpen === true && node.isSelected === false)) {
202
+ onNodeExpand(node);
203
+ }
204
+ executionPlanState.setSelectedNode(node);
205
+ };
263
206
 
264
- return childrenNodes;
265
- };
266
- return (
267
- <TreeView
268
- components={{
269
- TreeNodeContainer: ExecutionNodeElementTreeNodeContainer,
270
- }}
271
- treeData={treeData}
272
- getChildNodes={getChildNodes}
273
- onNodeSelect={onNodeSelect}
274
- innerProps={{
275
- onNodeExpand,
276
- }}
277
- />
278
- );
279
- };
207
+ const getChildNodes = (
208
+ node: ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData,
209
+ ): (ExecutionPlanViewTreeNodeData | ExecutionNodeTreeNodeData)[] => {
210
+ if (!node.childrenIds || node.childrenIds.length === 0) {
211
+ return [];
212
+ }
213
+ const childrenNodes = node.childrenIds
214
+ .map((id) => executionPlanState.nonNullableTreeData.nodes.get(id))
215
+ .filter(isNonNullable);
216
+ return childrenNodes;
217
+ };
218
+ return (
219
+ <TreeView
220
+ components={{
221
+ TreeNodeContainer: ExecutionNodeElementTreeNodeContainer,
222
+ }}
223
+ treeData={executionPlanState.nonNullableTreeData}
224
+ getChildNodes={getChildNodes}
225
+ onNodeSelect={onNodeSelect}
226
+ innerProps={{
227
+ onNodeExpand,
228
+ }}
229
+ />
230
+ );
231
+ },
232
+ );
280
233
 
281
234
  const ExecutionNodeViewer = observer(
282
235
  (props: {
@@ -289,6 +242,50 @@ const ExecutionNodeViewer = observer(
289
242
  <SQLExecutionNodeViewer
290
243
  query={executionNode.sqlQuery}
291
244
  resultColumns={executionNode.resultColumns}
245
+ resultType={executionNode.resultType}
246
+ executionPlanState={executionPlanState}
247
+ viewJson={true}
248
+ />
249
+ );
250
+ }
251
+ if (executionNode instanceof RelationalTDSInstantiationExecutionNode) {
252
+ return (
253
+ <RelationalTDSInstantiationExecutionNodeViewer
254
+ node={executionNode}
255
+ executionPlanState={executionPlanState}
256
+ />
257
+ );
258
+ }
259
+ if (executionNode instanceof FunctionParametersValidationNode) {
260
+ return (
261
+ <FunctionParametersValidationNodeViewer
262
+ functionParameters={executionNode.functionParameters}
263
+ parameterValidationContext={executionNode.parameterValidationContext}
264
+ executionPlanState={executionPlanState}
265
+ resultType={executionNode.resultType}
266
+ />
267
+ );
268
+ }
269
+ if (executionNode instanceof AllocationExecutionNode) {
270
+ return (
271
+ <AllocationExecutionNodeViewer
272
+ node={executionNode}
273
+ executionPlanState={executionPlanState}
274
+ />
275
+ );
276
+ }
277
+ if (executionNode instanceof ConstantExecutionNode) {
278
+ return (
279
+ <ConstantExecutionNodeViewer
280
+ cnode={executionNode}
281
+ executionPlanState={executionPlanState}
282
+ />
283
+ );
284
+ }
285
+ if (executionNode instanceof SequenceExecutionNode) {
286
+ return (
287
+ <SequenceExecutionNodeViewer
288
+ node={executionNode}
292
289
  executionPlanState={executionPlanState}
293
290
  />
294
291
  );
@@ -328,6 +325,19 @@ const ExecutionPlanViewPanel = observer(
328
325
  currentElement = executionPlanState.selectedNode.executionNode;
329
326
  }
330
327
  }
328
+
329
+ useEffect(() => {
330
+ if (executionPlanState.selectedNode === undefined) {
331
+ const firstNode =
332
+ executionPlanState.treeData?.nodes.get(EXECUTION_PLAN);
333
+ if (firstNode instanceof ExecutionPlanViewTreeNodeData) {
334
+ executionPlanState.transformMetadataToProtocolJson(
335
+ firstNode.executionPlan,
336
+ );
337
+ executionPlanState.setSelectedNode(firstNode);
338
+ }
339
+ }
340
+ }, [executionPlanState]);
331
341
  const nativeViewModes = Object.values(EXECUTION_PLAN_VIEW_MODE);
332
342
 
333
343
  return (
@@ -485,7 +495,7 @@ export const ExecutionPlanViewer = observer(
485
495
  const { executionPlanState } = props;
486
496
  const closePlanViewer = (): void => {
487
497
  executionPlanState.setRawPlan(undefined);
488
- executionPlanState.setPlan(undefined);
498
+ executionPlanState.initialize(undefined);
489
499
  executionPlanState.setExecutionPlanDisplayData('');
490
500
  executionPlanState.setSelectedNode(undefined);
491
501
  executionPlanState.setDebugText(undefined);
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { observer } from 'mobx-react-lite';
18
+ import React from 'react';
19
+ import {
20
+ type ExecutionPlanState,
21
+ EXECUTION_PLAN_VIEW_MODE,
22
+ } from '../../stores/execution-plan/ExecutionPlanState.js';
23
+ import {
24
+ type VariableExpression,
25
+ type ParameterValidationContext,
26
+ Multiplicity,
27
+ type ResultType,
28
+ } from '@finos/legend-graph';
29
+
30
+ import {
31
+ PanelListItem,
32
+ PanelDivider,
33
+ Button,
34
+ PanelContent,
35
+ } from '@finos/legend-art';
36
+ import { ResultTypeViewer } from './ResultTypeViewer.js';
37
+
38
+ export const FunctionParametersValidationNodeViewer: React.FC<{
39
+ functionParameters: VariableExpression[];
40
+ parameterValidationContext: ParameterValidationContext[];
41
+ resultType: ResultType;
42
+ executionPlanState: ExecutionPlanState;
43
+ }> = observer((props) => {
44
+ const { functionParameters, resultType, executionPlanState } = props;
45
+ const applicationStore = executionPlanState.applicationStore;
46
+
47
+ const showMultiplicity = (multiplicity: Multiplicity): string => {
48
+ if (multiplicity === Multiplicity.ZERO) {
49
+ return '[0]';
50
+ }
51
+ if (multiplicity === Multiplicity.ONE) {
52
+ return '[1]';
53
+ }
54
+ if (multiplicity === Multiplicity.ZERO_ONE) {
55
+ return '[0..1]';
56
+ }
57
+ if (
58
+ multiplicity === Multiplicity.ZERO_MANY ||
59
+ multiplicity === Multiplicity.ONE_MANY
60
+ ) {
61
+ return '[*]';
62
+ }
63
+ if (multiplicity.upperBound === undefined) {
64
+ return `[${multiplicity.lowerBound.toString()}.. *]`;
65
+ }
66
+ return `[${multiplicity.lowerBound.toString()}..${multiplicity.upperBound.toString()}]`;
67
+ };
68
+ return (
69
+ <PanelContent
70
+ darkMode={
71
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
72
+ }
73
+ >
74
+ <div className="query-builder__function-parameters-validation__container">
75
+ <div>
76
+ <PanelListItem className="query-builder__function-parameters-validation__container__item__label">
77
+ Variables Details
78
+ </PanelListItem>
79
+ <PanelDivider />
80
+ <table className="table query-builder__function-parameters-validation__container__table">
81
+ <thead>
82
+ <tr>
83
+ <th className="table__cell--left">Name</th>
84
+ <th className="table__cell--left">Type</th>
85
+ </tr>
86
+ </thead>
87
+ <tbody>
88
+ {functionParameters.map((parameter) => (
89
+ <React.Fragment key={parameter.name}>
90
+ <tr>
91
+ <td className="table__cell--left">{parameter.name}</td>
92
+ <td className="table__cell--left">
93
+ {`${
94
+ parameter.genericType?.value.rawType.name
95
+ } ${showMultiplicity(parameter.multiplicity)}`}
96
+ </td>
97
+ </tr>
98
+ </React.Fragment>
99
+ ))}
100
+ </tbody>
101
+ </table>
102
+ </div>
103
+ </div>
104
+ <PanelDivider />
105
+ <ResultTypeViewer resultType={resultType} />
106
+ <div className="query-builder__function-parameters-validation__container">
107
+ <Button
108
+ className="btn--dark execution-node-viewer__unsupported-view__to-text-mode__btn"
109
+ onClick={(): void =>
110
+ executionPlanState.setViewMode(EXECUTION_PLAN_VIEW_MODE.JSON)
111
+ }
112
+ text="View JSON"
113
+ />
114
+ </div>
115
+ <PanelDivider />
116
+ </PanelContent>
117
+ );
118
+ });
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { observer } from 'mobx-react-lite';
18
+ import {
19
+ type ExecutionPlanState,
20
+ EXECUTION_PLAN_VIEW_MODE,
21
+ } from '../../stores/execution-plan/ExecutionPlanState.js';
22
+ import {
23
+ SQLExecutionNode,
24
+ type RelationalTDSInstantiationExecutionNode,
25
+ } from '@finos/legend-graph';
26
+ import { PanelDivider, Button, PanelContent } from '@finos/legend-art';
27
+ import { SQLExecutionNodeViewerHelper } from './SQLExecutionNodeViewer.js';
28
+ import { ResultTypeViewer } from './ResultTypeViewer.js';
29
+
30
+ export const RelationalTDSInstantiationExecutionNodeViewer: React.FC<{
31
+ node: RelationalTDSInstantiationExecutionNode;
32
+ executionPlanState: ExecutionPlanState;
33
+ }> = observer((props) => {
34
+ const { node, executionPlanState } = props;
35
+ const resultType = node.resultType;
36
+ const applicationStore = executionPlanState.applicationStore;
37
+
38
+ return (
39
+ <PanelContent
40
+ darkMode={
41
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
42
+ }
43
+ >
44
+ {node.executionNodes.length > 0 &&
45
+ node.executionNodes[0] !== undefined &&
46
+ node.executionNodes[0] instanceof SQLExecutionNode && (
47
+ <SQLExecutionNodeViewerHelper
48
+ query={node.executionNodes[0].sqlQuery}
49
+ resultColumns={node.executionNodes[0].resultColumns}
50
+ resultType={node.executionNodes[0].resultType}
51
+ executionPlanState={executionPlanState}
52
+ />
53
+ )}
54
+ <PanelDivider />
55
+ <ResultTypeViewer resultType={resultType} />
56
+ <div className="query-builder__sql__container">
57
+ <Button
58
+ className="btn--dark execution-node-viewer__unsupported-view__to-text-mode__btn"
59
+ onClick={(): void =>
60
+ executionPlanState.setViewMode(EXECUTION_PLAN_VIEW_MODE.JSON)
61
+ }
62
+ text="View JSON"
63
+ />
64
+ </div>
65
+ <PanelDivider />
66
+ </PanelContent>
67
+ );
68
+ });