@finos/legend-query-builder 4.1.8 → 4.1.10
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.
- package/lib/components/QueryBuilder.d.ts.map +1 -1
- package/lib/components/QueryBuilder.js +4 -2
- package/lib/components/QueryBuilder.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +2 -2
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/QueryChat.d.ts +22 -0
- package/lib/components/QueryChat.d.ts.map +1 -0
- package/lib/components/QueryChat.js +28 -0
- package/lib/components/QueryChat.js.map +1 -0
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.d.ts.map +1 -1
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.js +1 -1
- package/lib/components/execution-plan/AllocationExecutionNodeViewer.js.map +1 -1
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.js +1 -1
- package/lib/components/execution-plan/ConstantExecutionNodeViewer.js.map +1 -1
- package/lib/components/execution-plan/ExecutionPlanViewer.d.ts +4 -0
- package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
- package/lib/components/execution-plan/ExecutionPlanViewer.js +43 -5
- package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.d.ts.map +1 -1
- package/lib/components/execution-plan/FunctionParametersValidationNodeViewer.js.map +1 -1
- package/lib/components/execution-plan/ResultTypeViewer.js +2 -2
- package/lib/components/execution-plan/ResultTypeViewer.js.map +1 -1
- package/lib/index.css +17 -1
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderState.d.ts +2 -0
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +6 -0
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +5 -0
- package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js +2 -2
- package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
- package/package.json +8 -8
- package/src/components/QueryBuilder.tsx +17 -0
- package/src/components/QueryBuilderResultPanel.tsx +8 -1
- package/src/components/QueryChat.tsx +73 -0
- package/src/components/execution-plan/AllocationExecutionNodeViewer.tsx +12 -10
- package/src/components/execution-plan/ConstantExecutionNodeViewer.tsx +1 -1
- package/src/components/execution-plan/ExecutionPlanViewer.tsx +171 -19
- package/src/components/execution-plan/FunctionParametersValidationNodeViewer.tsx +1 -2
- package/src/components/execution-plan/ResultTypeViewer.tsx +1 -1
- package/src/stores/QueryBuilderState.ts +7 -0
- package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +9 -0
- package/src/stores/explorer/QueryBuilderExplorerState.ts +2 -2
- package/tsconfig.json +1 -0
@@ -14,7 +14,7 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
-
import { useEffect } from 'react';
|
17
|
+
import { useEffect, useState } from 'react';
|
18
18
|
import {
|
19
19
|
type TreeNodeContainerProps,
|
20
20
|
Dialog,
|
@@ -39,8 +39,10 @@ import {
|
|
39
39
|
ModalFooterButton,
|
40
40
|
PanelHeader,
|
41
41
|
Panel,
|
42
|
+
PanelDivider,
|
43
|
+
Button,
|
42
44
|
} from '@finos/legend-art';
|
43
|
-
import { isNonNullable } from '@finos/legend-shared';
|
45
|
+
import { isNonNullable, prettyCONSTName } from '@finos/legend-shared';
|
44
46
|
import {
|
45
47
|
ExecutionNodeTreeNodeData,
|
46
48
|
ExecutionPlanViewTreeNodeData,
|
@@ -59,6 +61,7 @@ import {
|
|
59
61
|
ConstantExecutionNode,
|
60
62
|
SequenceExecutionNode,
|
61
63
|
type RawExecutionPlan,
|
64
|
+
JavaPlatformImplementation,
|
62
65
|
} from '@finos/legend-graph';
|
63
66
|
import { SQLExecutionNodeViewer } from './SQLExecutionNodeViewer.js';
|
64
67
|
import { FunctionParametersValidationNodeViewer } from './FunctionParametersValidationNodeViewer.js';
|
@@ -95,6 +98,169 @@ export const generateExecutionNodeLabel = (type: ExecutionNode): string => {
|
|
95
98
|
}
|
96
99
|
};
|
97
100
|
|
101
|
+
enum PLAN_TABS {
|
102
|
+
GENERAL = 'GENERAL',
|
103
|
+
GLOBAL_IMPLEMENTATION_SUPPORT = 'GLOBAL_IMPLEMENTATION_SUPPORT',
|
104
|
+
}
|
105
|
+
|
106
|
+
export const ExecutionPlanViewerPanelContent: React.FC<{
|
107
|
+
executionPlanState: ExecutionPlanState;
|
108
|
+
}> = observer((props) => {
|
109
|
+
const { executionPlanState } = props;
|
110
|
+
const applicationStore = executionPlanState.applicationStore;
|
111
|
+
const globalImplementationSupport =
|
112
|
+
executionPlanState.plan?.globalImplementationSupport;
|
113
|
+
const templateFunctions =
|
114
|
+
executionPlanState.plan?.processingTemplateFunctions ?? [];
|
115
|
+
const [selectedTab, setSelectedTab] = useState<PLAN_TABS>(PLAN_TABS.GENERAL);
|
116
|
+
const [selectedJavaClass, setSelectedJavaClass] = useState<
|
117
|
+
string | undefined
|
118
|
+
>(undefined);
|
119
|
+
|
120
|
+
if (
|
121
|
+
globalImplementationSupport &&
|
122
|
+
globalImplementationSupport instanceof JavaPlatformImplementation
|
123
|
+
) {
|
124
|
+
globalImplementationSupport.classes.sort((a, b) =>
|
125
|
+
(a.package + a.name).toLowerCase() > (b.package + b.name).toLowerCase()
|
126
|
+
? 1
|
127
|
+
: -1,
|
128
|
+
);
|
129
|
+
if (
|
130
|
+
globalImplementationSupport.classes.length > 0 &&
|
131
|
+
globalImplementationSupport.classes[0] &&
|
132
|
+
selectedJavaClass === undefined
|
133
|
+
) {
|
134
|
+
setSelectedJavaClass(
|
135
|
+
globalImplementationSupport.classes[0]?.package +
|
136
|
+
globalImplementationSupport.classes[0]?.name,
|
137
|
+
);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
return (
|
142
|
+
<div className="query-builder__execution-plan-form--editor">
|
143
|
+
<div className="panel">
|
144
|
+
<div className="panel__header query-builder__execution-plan-form--editor__header--with-tabs">
|
145
|
+
<div className="uml-element-editor__tabs">
|
146
|
+
{Object.values(PLAN_TABS).map((tab) => (
|
147
|
+
<div
|
148
|
+
key={tab}
|
149
|
+
onClick={() => setSelectedTab(tab)}
|
150
|
+
className={clsx(
|
151
|
+
'query-builder__execution-plan-form--editor__tab',
|
152
|
+
{
|
153
|
+
'query-builder__execution-plan-form--editor__tab--active':
|
154
|
+
tab === selectedTab,
|
155
|
+
},
|
156
|
+
)}
|
157
|
+
>
|
158
|
+
{prettyCONSTName(tab)}
|
159
|
+
</div>
|
160
|
+
))}
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
{selectedTab === PLAN_TABS.GLOBAL_IMPLEMENTATION_SUPPORT &&
|
164
|
+
globalImplementationSupport &&
|
165
|
+
globalImplementationSupport instanceof JavaPlatformImplementation && (
|
166
|
+
<ResizablePanelGroup orientation="vertical">
|
167
|
+
<ResizablePanel minSize={30} size={250}>
|
168
|
+
<PanelContent
|
169
|
+
darkMode={
|
170
|
+
!applicationStore.layoutService
|
171
|
+
.TEMPORARY__isLightColorThemeEnabled
|
172
|
+
}
|
173
|
+
className="query-builder__java__container__panel"
|
174
|
+
>
|
175
|
+
<div className="query-builder__java__container">
|
176
|
+
<div>
|
177
|
+
{globalImplementationSupport.classes.map((cl) => (
|
178
|
+
<div
|
179
|
+
className={clsx(
|
180
|
+
'query-builder__java__container__item',
|
181
|
+
{
|
182
|
+
'query-builder__java__container__item--active':
|
183
|
+
`${cl.package}${cl.name}` === selectedJavaClass,
|
184
|
+
},
|
185
|
+
)}
|
186
|
+
key={cl.package + cl.name}
|
187
|
+
>
|
188
|
+
<button
|
189
|
+
className="query-builder__java__container__item__btn"
|
190
|
+
onClick={() =>
|
191
|
+
setSelectedJavaClass(cl.package + cl.name)
|
192
|
+
}
|
193
|
+
tabIndex={-1}
|
194
|
+
title={`Go to ${cl.package}.${cl.name}`}
|
195
|
+
>
|
196
|
+
{`${cl.package}.${cl.name}`}
|
197
|
+
</button>
|
198
|
+
</div>
|
199
|
+
))}
|
200
|
+
<PanelDivider />
|
201
|
+
</div>
|
202
|
+
</div>
|
203
|
+
</PanelContent>
|
204
|
+
</ResizablePanel>
|
205
|
+
<ResizablePanelSplitter>
|
206
|
+
<ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
|
207
|
+
</ResizablePanelSplitter>
|
208
|
+
<ResizablePanel>
|
209
|
+
{selectedJavaClass && (
|
210
|
+
<CodeEditor
|
211
|
+
inputValue={globalImplementationSupport.classes.reduce(
|
212
|
+
(value, cl) => {
|
213
|
+
if (selectedJavaClass === `${cl.package}${cl.name}`) {
|
214
|
+
return cl.source;
|
215
|
+
}
|
216
|
+
return value;
|
217
|
+
},
|
218
|
+
'',
|
219
|
+
)}
|
220
|
+
isReadOnly={true}
|
221
|
+
language={CODE_EDITOR_LANGUAGE.JAVA}
|
222
|
+
hideMinimap={true}
|
223
|
+
/>
|
224
|
+
)}
|
225
|
+
</ResizablePanel>
|
226
|
+
</ResizablePanelGroup>
|
227
|
+
)}
|
228
|
+
{selectedTab === PLAN_TABS.GENERAL && (
|
229
|
+
<>
|
230
|
+
<div className="query-builder__template--function--editor__header">
|
231
|
+
{`AuthDependent: ${executionPlanState.plan?.authDependent.toString()}`}
|
232
|
+
</div>
|
233
|
+
<div className="query-builder__template--function--editor__title">
|
234
|
+
Template Functions
|
235
|
+
</div>
|
236
|
+
<div className="query-builder__template--function--editor__code">
|
237
|
+
<CodeEditor
|
238
|
+
inputValue={templateFunctions.reduce(
|
239
|
+
(total, func) => (total += `${func}\n`),
|
240
|
+
'',
|
241
|
+
)}
|
242
|
+
isReadOnly={true}
|
243
|
+
language={CODE_EDITOR_LANGUAGE.XML}
|
244
|
+
hideMinimap={true}
|
245
|
+
hideActionBar={true}
|
246
|
+
/>
|
247
|
+
</div>
|
248
|
+
<div className="query-builder__template--function--editor__json">
|
249
|
+
<Button
|
250
|
+
className="btn--dark execution-node-viewer__unsupported-view__to-text-mode__btn"
|
251
|
+
onClick={(): void =>
|
252
|
+
executionPlanState.setViewMode(EXECUTION_PLAN_VIEW_MODE.JSON)
|
253
|
+
}
|
254
|
+
text="View JSON"
|
255
|
+
/>
|
256
|
+
</div>
|
257
|
+
</>
|
258
|
+
)}
|
259
|
+
</div>
|
260
|
+
</div>
|
261
|
+
);
|
262
|
+
});
|
263
|
+
|
98
264
|
const ExecutionNodeElementTreeNodeContainer = observer(
|
99
265
|
(
|
100
266
|
props: TreeNodeContainerProps<
|
@@ -405,23 +571,9 @@ const ExecutionPlanViewPanel = observer(
|
|
405
571
|
/>
|
406
572
|
)}
|
407
573
|
{currentElement instanceof ExecutionPlan && (
|
408
|
-
<
|
409
|
-
|
410
|
-
|
411
|
-
{`Can't display full execution plan`}
|
412
|
-
</div>
|
413
|
-
<button
|
414
|
-
className="btn--dark execution-plan-viewer__unsupported-view__to-text-mode__btn"
|
415
|
-
onClick={(): void =>
|
416
|
-
executionPlanState.setViewMode(
|
417
|
-
EXECUTION_PLAN_VIEW_MODE.JSON,
|
418
|
-
)
|
419
|
-
}
|
420
|
-
>
|
421
|
-
View JSON
|
422
|
-
</button>
|
423
|
-
</div>
|
424
|
-
</BlankPanelContent>
|
574
|
+
<ExecutionPlanViewerPanelContent
|
575
|
+
executionPlanState={executionPlanState}
|
576
|
+
/>
|
425
577
|
)}
|
426
578
|
</>
|
427
579
|
)}
|
@@ -122,6 +122,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
122
122
|
isEditingWatermark = false;
|
123
123
|
isCheckingEntitlments = false;
|
124
124
|
isCalendarEnabled = false;
|
125
|
+
isQueryChatOpened = false;
|
125
126
|
|
126
127
|
class?: Class | undefined;
|
127
128
|
mapping?: Mapping | undefined;
|
@@ -156,6 +157,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
156
157
|
class: observable,
|
157
158
|
mapping: observable,
|
158
159
|
runtimeValue: observable,
|
160
|
+
isQueryChatOpened: observable,
|
159
161
|
|
160
162
|
sideBarClassName: computed,
|
161
163
|
isQuerySupported: computed,
|
@@ -169,6 +171,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
169
171
|
setClass: action,
|
170
172
|
setMapping: action,
|
171
173
|
setRuntimeValue: action,
|
174
|
+
setIsQueryChatOpened: action,
|
172
175
|
|
173
176
|
resetQueryResult: action,
|
174
177
|
resetQueryContent: action,
|
@@ -243,6 +246,10 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
243
246
|
return this.allVariables.map((e) => e.name);
|
244
247
|
}
|
245
248
|
|
249
|
+
setIsQueryChatOpened(val: boolean): void {
|
250
|
+
this.isQueryChatOpened = val;
|
251
|
+
}
|
252
|
+
|
246
253
|
setShowFunctionsExplorerPanel(val: boolean): void {
|
247
254
|
this.showFunctionsExplorerPanel = val;
|
248
255
|
}
|
@@ -45,6 +45,10 @@ export type QueryExportUsageConfiguration = {
|
|
45
45
|
renderer(): React.ReactNode;
|
46
46
|
};
|
47
47
|
|
48
|
+
export type QueryChatRenderer = (
|
49
|
+
queryBuilderState: QueryBuilderState,
|
50
|
+
) => React.ReactNode;
|
51
|
+
|
48
52
|
export interface QueryBuilder_LegendApplicationPlugin_Extension
|
49
53
|
extends LegendApplicationPlugin {
|
50
54
|
/**
|
@@ -61,4 +65,9 @@ export interface QueryBuilder_LegendApplicationPlugin_Extension
|
|
61
65
|
* Get the list of query usage configurations
|
62
66
|
*/
|
63
67
|
getExtraQueryUsageConfigurations?(): QueryExportUsageConfiguration[];
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Get the list of query chat configurations
|
71
|
+
*/
|
72
|
+
getExtraQueryChatRenderers?(): QueryChatRenderer[];
|
64
73
|
}
|
@@ -676,8 +676,8 @@ export class QueryBuilderExplorerState {
|
|
676
676
|
// This makes the assumption that the mapping has not been edited, which is a valid assumption since query is not for editing mappings
|
677
677
|
if (
|
678
678
|
this.queryBuilderState.mapping &&
|
679
|
-
this.queryBuilderState.mapping !==
|
680
|
-
this.mappingModelCoverageAnalysisResult?.mapping
|
679
|
+
this.queryBuilderState.mapping.path !==
|
680
|
+
this.mappingModelCoverageAnalysisResult?.mapping.path
|
681
681
|
) {
|
682
682
|
this.mappingModelCoverageAnalysisState.inProgress();
|
683
683
|
QueryBuilderTelemetryHelper.logEvent_QueryMappingModelCoverageAnalysisLaunched(
|
package/tsconfig.json
CHANGED
@@ -217,6 +217,7 @@
|
|
217
217
|
"./src/components/QueryBuilderSideBar.tsx",
|
218
218
|
"./src/components/QueryBuilderTextEditor.tsx",
|
219
219
|
"./src/components/QueryBuilderUnsupportedQueryEditor.tsx",
|
220
|
+
"./src/components/QueryChat.tsx",
|
220
221
|
"./src/components/QueryLoader.tsx",
|
221
222
|
"./src/components/QueryUsageViewer.tsx",
|
222
223
|
"./src/components/ServiceQuerySetupUtils.tsx",
|