@finos/legend-query-builder 4.14.27 → 4.14.29
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/components/QueryBuilder.d.ts.map +1 -1
- package/lib/components/QueryBuilder.js +16 -32
- package/lib/components/QueryBuilder.js.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.js +6 -2
- package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +10 -2
- package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js +1 -0
- package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderState.d.ts +2 -1
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +10 -2
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +4 -0
- package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
- package/package.json +3 -3
- package/src/components/QueryBuilder.tsx +86 -141
- package/src/components/QueryBuilderPropertyExpressionEditor.tsx +6 -2
- package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +10 -2
- package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +1 -0
- package/src/stores/QueryBuilderState.ts +21 -0
- package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +7 -0
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
import { observer } from 'mobx-react-lite';
|
18
18
|
import {
|
19
|
-
clsx,
|
20
19
|
HammerIcon,
|
21
20
|
ResizablePanelGroup,
|
22
21
|
ResizablePanel,
|
@@ -31,7 +30,6 @@ import {
|
|
31
30
|
CaretDownIcon,
|
32
31
|
DiffIcon,
|
33
32
|
WaterDropIcon,
|
34
|
-
AssistantIcon,
|
35
33
|
MenuContentDivider,
|
36
34
|
Dialog,
|
37
35
|
Modal,
|
@@ -43,6 +41,9 @@ import {
|
|
43
41
|
CalendarClockIcon,
|
44
42
|
ChatIcon,
|
45
43
|
PanelLoadingIndicator,
|
44
|
+
SerializeIcon,
|
45
|
+
DataAccessIcon,
|
46
|
+
AssistantIcon,
|
46
47
|
} from '@finos/legend-art';
|
47
48
|
import { QueryBuilderFilterPanel } from './filter/QueryBuilderFilterPanel.js';
|
48
49
|
import { QueryBuilderExplorerPanel } from './explorer/QueryBuilderExplorerPanel.js';
|
@@ -57,7 +58,6 @@ import { flowResult } from 'mobx';
|
|
57
58
|
import { QueryBuilderUnsupportedQueryEditor } from './QueryBuilderUnsupportedQueryEditor.js';
|
58
59
|
import {
|
59
60
|
BackdropContainer,
|
60
|
-
useApplicationStore,
|
61
61
|
useCommands,
|
62
62
|
ActionAlertActionType,
|
63
63
|
ActionAlertType,
|
@@ -78,138 +78,6 @@ import { QueryChat } from './QueryChat.js';
|
|
78
78
|
import { useEffect, useRef } from 'react';
|
79
79
|
import { RedoButton, UndoButton } from '@finos/legend-lego/application';
|
80
80
|
|
81
|
-
const QueryBuilderStatusBar = observer(
|
82
|
-
(props: { queryBuilderState: QueryBuilderState }) => {
|
83
|
-
const { queryBuilderState } = props;
|
84
|
-
const applicationStore = useApplicationStore();
|
85
|
-
const showDiff = (): void =>
|
86
|
-
queryBuilderState.changeDetectionState.showDiffViewPanel();
|
87
|
-
const openLambdaEditor = (mode: QueryBuilderTextEditorMode): void =>
|
88
|
-
queryBuilderState.textEditorState.openModal(mode);
|
89
|
-
const compile = applicationStore.guardUnhandledError(() =>
|
90
|
-
flowResult(queryBuilderState.compileQuery()),
|
91
|
-
);
|
92
|
-
const toggleAssistant = (): void =>
|
93
|
-
applicationStore.assistantService.toggleAssistant();
|
94
|
-
const openQueryChat = (): void =>
|
95
|
-
queryBuilderState.setIsQueryChatOpened(true);
|
96
|
-
|
97
|
-
return (
|
98
|
-
<div className="query-builder__status-bar">
|
99
|
-
<div className="query-builder__status-bar__left"></div>
|
100
|
-
<div className="query-builder__status-bar__right">
|
101
|
-
{queryBuilderState.changeDetectionState.initState.hasCompleted && (
|
102
|
-
<>
|
103
|
-
<button
|
104
|
-
className={clsx(
|
105
|
-
'query-builder__status-bar__action query-builder__status-bar__view-diff-btn',
|
106
|
-
)}
|
107
|
-
disabled={!queryBuilderState.changeDetectionState.hasChanged}
|
108
|
-
onClick={showDiff}
|
109
|
-
tabIndex={-1}
|
110
|
-
title={
|
111
|
-
queryBuilderState.changeDetectionState.hasChanged
|
112
|
-
? 'Show changes'
|
113
|
-
: 'Query has not been changed'
|
114
|
-
}
|
115
|
-
>
|
116
|
-
<DiffIcon />
|
117
|
-
</button>
|
118
|
-
{queryBuilderState.changeDetectionState.diffViewState && (
|
119
|
-
<QueryBuilderDiffViewPanelDiaglog
|
120
|
-
diffViewState={
|
121
|
-
queryBuilderState.changeDetectionState.diffViewState
|
122
|
-
}
|
123
|
-
/>
|
124
|
-
)}
|
125
|
-
</>
|
126
|
-
)}
|
127
|
-
{queryBuilderState.isQueryChatOpened && (
|
128
|
-
<QueryChat queryBuilderState={queryBuilderState} />
|
129
|
-
)}
|
130
|
-
{!queryBuilderState.config?.TEMPORARY__disableQueryBuilderChat && (
|
131
|
-
<button
|
132
|
-
className={clsx(
|
133
|
-
'query-builder__status-bar__action query-builder__status-bar__action__toggler',
|
134
|
-
{
|
135
|
-
'query-builder__status-bar__action__toggler--toggled':
|
136
|
-
queryBuilderState.isQueryChatOpened === true,
|
137
|
-
},
|
138
|
-
)}
|
139
|
-
onClick={openQueryChat}
|
140
|
-
tabIndex={-1}
|
141
|
-
title="Open Query Chat"
|
142
|
-
>
|
143
|
-
<ChatIcon />
|
144
|
-
</button>
|
145
|
-
)}
|
146
|
-
<button
|
147
|
-
className={clsx(
|
148
|
-
'query-builder__status-bar__action query-builder__status-bar__compile-btn',
|
149
|
-
{
|
150
|
-
'query-builder__status-bar__compile-btn--wiggling':
|
151
|
-
queryBuilderState.queryCompileState.isInProgress,
|
152
|
-
},
|
153
|
-
)}
|
154
|
-
disabled={queryBuilderState.queryCompileState.isInProgress}
|
155
|
-
onClick={compile}
|
156
|
-
tabIndex={-1}
|
157
|
-
title="Compile (F9)"
|
158
|
-
>
|
159
|
-
<HammerIcon />
|
160
|
-
</button>
|
161
|
-
<button
|
162
|
-
className={clsx(
|
163
|
-
'query-builder__status-bar__action query-builder__status-bar__action__toggler',
|
164
|
-
{
|
165
|
-
'query-builder__status-bar__action__toggler--toggled':
|
166
|
-
queryBuilderState.textEditorState.mode ===
|
167
|
-
QueryBuilderTextEditorMode.JSON,
|
168
|
-
},
|
169
|
-
)}
|
170
|
-
onClick={(): void =>
|
171
|
-
openLambdaEditor(QueryBuilderTextEditorMode.JSON)
|
172
|
-
}
|
173
|
-
tabIndex={-1}
|
174
|
-
title="View Query Protocol"
|
175
|
-
>{`{ }`}</button>
|
176
|
-
<button
|
177
|
-
className={clsx(
|
178
|
-
'query-builder__status-bar__action query-builder__status-bar__action__toggler',
|
179
|
-
{
|
180
|
-
'query-builder__status-bar__action__toggler--toggled':
|
181
|
-
queryBuilderState.textEditorState.mode ===
|
182
|
-
QueryBuilderTextEditorMode.TEXT,
|
183
|
-
},
|
184
|
-
)}
|
185
|
-
onClick={(): void =>
|
186
|
-
openLambdaEditor(QueryBuilderTextEditorMode.TEXT)
|
187
|
-
}
|
188
|
-
tabIndex={-1}
|
189
|
-
title="View Query in Pure"
|
190
|
-
>
|
191
|
-
<HackerIcon />
|
192
|
-
</button>
|
193
|
-
<button
|
194
|
-
className={clsx(
|
195
|
-
'query-builder__status-bar__action query-builder__status-bar__action__toggler',
|
196
|
-
{
|
197
|
-
'query-builder__status-bar__action__toggler--toggled':
|
198
|
-
!applicationStore.assistantService.isHidden,
|
199
|
-
},
|
200
|
-
)}
|
201
|
-
onClick={toggleAssistant}
|
202
|
-
tabIndex={-1}
|
203
|
-
title="Toggle assistant"
|
204
|
-
>
|
205
|
-
<AssistantIcon />
|
206
|
-
</button>
|
207
|
-
</div>
|
208
|
-
</div>
|
209
|
-
);
|
210
|
-
},
|
211
|
-
);
|
212
|
-
|
213
81
|
const QueryBuilderPostGraphFetchPanel = observer(
|
214
82
|
(props: { graphFetchState: QueryBuilderGraphFetchTreeState }) => {
|
215
83
|
const { graphFetchState } = props;
|
@@ -381,6 +249,16 @@ export const QueryBuilder = observer(
|
|
381
249
|
queryBuilderState.changeHistoryState.redo();
|
382
250
|
};
|
383
251
|
|
252
|
+
const toggleAssistant = (): void =>
|
253
|
+
applicationStore.assistantService.toggleAssistant();
|
254
|
+
const compileQuery = applicationStore.guardUnhandledError(() =>
|
255
|
+
flowResult(queryBuilderState.compileQuery()),
|
256
|
+
);
|
257
|
+
const showDiff = (): void =>
|
258
|
+
queryBuilderState.changeDetectionState.showDiffViewPanel();
|
259
|
+
const openQueryChat = (): void =>
|
260
|
+
queryBuilderState.setIsQueryChatOpened(true);
|
261
|
+
|
384
262
|
useEffect(() => {
|
385
263
|
// this condition is for passing all exisitng tests because when we initialize a queryBuilderState for a test,
|
386
264
|
// we use an empty RawLambda with an empty class and this useEffect is called earlier than initializeWithQuery()
|
@@ -576,7 +454,9 @@ export const QueryBuilder = observer(
|
|
576
454
|
</MenuContentItemLabel>
|
577
455
|
</MenuContentItem>
|
578
456
|
<MenuContentItem onClick={openWatermark}>
|
579
|
-
<MenuContentItemIcon>
|
457
|
+
<MenuContentItemIcon>
|
458
|
+
<WaterDropIcon />
|
459
|
+
</MenuContentItemIcon>
|
580
460
|
<MenuContentItemLabel>
|
581
461
|
Show Watermark
|
582
462
|
</MenuContentItemLabel>
|
@@ -594,7 +474,9 @@ export const QueryBuilder = observer(
|
|
594
474
|
<MenuContentItemIcon>
|
595
475
|
{queryBuilderState.isCalendarEnabled ? (
|
596
476
|
<CheckIcon />
|
597
|
-
) :
|
477
|
+
) : (
|
478
|
+
<CalendarClockIcon />
|
479
|
+
)}
|
598
480
|
</MenuContentItemIcon>
|
599
481
|
<MenuContentItemLabel>
|
600
482
|
Enable Calendar
|
@@ -611,23 +493,77 @@ export const QueryBuilder = observer(
|
|
611
493
|
.projectionColumns.length === 0
|
612
494
|
}
|
613
495
|
>
|
614
|
-
<MenuContentItemIcon
|
496
|
+
<MenuContentItemIcon>
|
497
|
+
<DataAccessIcon />
|
498
|
+
</MenuContentItemIcon>
|
615
499
|
<MenuContentItemLabel>
|
616
500
|
Check Entitlements
|
617
501
|
</MenuContentItemLabel>
|
618
502
|
</MenuContentItem>
|
619
503
|
<MenuContentItem onClick={editQueryInPure}>
|
620
|
-
<MenuContentItemIcon
|
504
|
+
<MenuContentItemIcon>
|
505
|
+
<HackerIcon />
|
506
|
+
</MenuContentItemIcon>
|
621
507
|
<MenuContentItemLabel>
|
622
508
|
Edit Query in Pure
|
623
509
|
</MenuContentItemLabel>
|
624
510
|
</MenuContentItem>
|
625
511
|
<MenuContentItem onClick={showQueryProtocol}>
|
626
|
-
<MenuContentItemIcon
|
512
|
+
<MenuContentItemIcon>
|
513
|
+
<SerializeIcon />
|
514
|
+
</MenuContentItemIcon>
|
627
515
|
<MenuContentItemLabel>
|
628
516
|
Show Query Protocol
|
629
517
|
</MenuContentItemLabel>
|
630
518
|
</MenuContentItem>
|
519
|
+
<MenuContentItem onClick={compileQuery}>
|
520
|
+
<MenuContentItemIcon>
|
521
|
+
<HammerIcon />
|
522
|
+
</MenuContentItemIcon>
|
523
|
+
<MenuContentItemLabel>
|
524
|
+
Compile Query (F9)
|
525
|
+
</MenuContentItemLabel>
|
526
|
+
</MenuContentItem>
|
527
|
+
{queryBuilderState.changeDetectionState.initState
|
528
|
+
.hasCompleted && (
|
529
|
+
<MenuContentItem
|
530
|
+
disabled={
|
531
|
+
!queryBuilderState.changeDetectionState.hasChanged
|
532
|
+
}
|
533
|
+
onClick={showDiff}
|
534
|
+
title={
|
535
|
+
queryBuilderState.changeDetectionState.hasChanged
|
536
|
+
? 'Show changes'
|
537
|
+
: 'Query has not been changed'
|
538
|
+
}
|
539
|
+
>
|
540
|
+
<MenuContentItemIcon>
|
541
|
+
<DiffIcon />
|
542
|
+
</MenuContentItemIcon>
|
543
|
+
<MenuContentItemLabel>
|
544
|
+
Show Query Diff
|
545
|
+
</MenuContentItemLabel>
|
546
|
+
</MenuContentItem>
|
547
|
+
)}
|
548
|
+
{!queryBuilderState.config
|
549
|
+
?.TEMPORARY__disableQueryBuilderChat && (
|
550
|
+
<MenuContentItem onClick={openQueryChat}>
|
551
|
+
<MenuContentItemIcon>
|
552
|
+
<ChatIcon />
|
553
|
+
</MenuContentItemIcon>
|
554
|
+
<MenuContentItemLabel>
|
555
|
+
Open Query Chat
|
556
|
+
</MenuContentItemLabel>
|
557
|
+
</MenuContentItem>
|
558
|
+
)}
|
559
|
+
<MenuContentItem onClick={toggleAssistant}>
|
560
|
+
<MenuContentItemIcon>
|
561
|
+
<AssistantIcon />
|
562
|
+
</MenuContentItemIcon>
|
563
|
+
<MenuContentItemLabel>
|
564
|
+
Open Assistant
|
565
|
+
</MenuContentItemLabel>
|
566
|
+
</MenuContentItem>
|
631
567
|
</MenuContent>
|
632
568
|
}
|
633
569
|
menuProps={{
|
@@ -736,9 +672,19 @@ export const QueryBuilder = observer(
|
|
736
672
|
</ResizablePanelGroup>
|
737
673
|
</div>
|
738
674
|
</div>
|
675
|
+
{queryBuilderState.isQueryChatOpened && (
|
676
|
+
<QueryChat queryBuilderState={queryBuilderState} />
|
677
|
+
)}
|
739
678
|
{queryBuilderState.textEditorState.mode && (
|
740
679
|
<QueryBuilderTextEditor queryBuilderState={queryBuilderState} />
|
741
680
|
)}
|
681
|
+
{queryBuilderState.changeDetectionState.diffViewState && (
|
682
|
+
<QueryBuilderDiffViewPanelDiaglog
|
683
|
+
diffViewState={
|
684
|
+
queryBuilderState.changeDetectionState.diffViewState
|
685
|
+
}
|
686
|
+
/>
|
687
|
+
)}
|
742
688
|
{queryBuilderState.checkEntitlementsState
|
743
689
|
.showCheckEntitlementsViewer && (
|
744
690
|
<Dialog
|
@@ -789,7 +735,6 @@ export const QueryBuilder = observer(
|
|
789
735
|
</Dialog>
|
790
736
|
)}
|
791
737
|
</div>
|
792
|
-
<QueryBuilderStatusBar queryBuilderState={queryBuilderState} />
|
793
738
|
</div>
|
794
739
|
);
|
795
740
|
},
|
@@ -408,11 +408,15 @@ export const QueryBuilderEditablePropertyName = observer(
|
|
408
408
|
onChange={changeColumnName}
|
409
409
|
onKeyDown={(event: React.KeyboardEvent<HTMLInputElement>) => {
|
410
410
|
if (event.key === 'Enter') {
|
411
|
-
|
411
|
+
if (columnName.length > 0) {
|
412
|
+
setIsEditingColumnName(false);
|
413
|
+
}
|
412
414
|
}
|
413
415
|
}}
|
414
416
|
onBlur={() => {
|
415
|
-
|
417
|
+
if (columnName.length > 0) {
|
418
|
+
setIsEditingColumnName(false);
|
419
|
+
}
|
416
420
|
}}
|
417
421
|
error={error}
|
418
422
|
ref={columnNameInputRef}
|
@@ -789,7 +789,11 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
789
789
|
projectionColumnState={projectionColumnState}
|
790
790
|
changeColumnName={changeColumnName}
|
791
791
|
error={
|
792
|
-
isDuplicatedColumnName
|
792
|
+
isDuplicatedColumnName
|
793
|
+
? 'Duplicated column'
|
794
|
+
: projectionColumnState.columnName.length === 0
|
795
|
+
? 'Empty column name'
|
796
|
+
: undefined
|
793
797
|
}
|
794
798
|
/>
|
795
799
|
</div>
|
@@ -812,7 +816,11 @@ const QueryBuilderProjectionColumnEditor = observer(
|
|
812
816
|
columnName={projectionColumnState.columnName}
|
813
817
|
changeColumnName={changeColumnName}
|
814
818
|
error={
|
815
|
-
isDuplicatedColumnName
|
819
|
+
isDuplicatedColumnName
|
820
|
+
? 'Duplicated column'
|
821
|
+
: projectionColumnState.columnName.length === 0
|
822
|
+
? 'Empty column name'
|
823
|
+
: undefined
|
816
824
|
}
|
817
825
|
title={projectionColumnState.columnName}
|
818
826
|
/>
|
@@ -32,6 +32,7 @@ import {
|
|
32
32
|
ActionState,
|
33
33
|
hashArray,
|
34
34
|
assertTrue,
|
35
|
+
assertNonNullable,
|
35
36
|
} from '@finos/legend-shared';
|
36
37
|
import { QueryBuilderFilterState } from './filter/QueryBuilderFilterState.js';
|
37
38
|
import { QueryBuilderFetchStructureState } from './fetch-structure/QueryBuilderFetchStructureState.js';
|
@@ -54,6 +55,7 @@ import {
|
|
54
55
|
type ValueSpecification,
|
55
56
|
type Type,
|
56
57
|
type QueryGridConfig,
|
58
|
+
type QueryExecutionContext,
|
57
59
|
GRAPH_MANAGER_EVENT,
|
58
60
|
CompilationError,
|
59
61
|
extractSourceInformationCoordinates,
|
@@ -73,6 +75,7 @@ import {
|
|
73
75
|
InstanceValue,
|
74
76
|
Multiplicity,
|
75
77
|
RuntimePointer,
|
78
|
+
QueryExplicitExecutionContext,
|
76
79
|
} from '@finos/legend-graph';
|
77
80
|
import { buildLambdaFunction } from './QueryBuilderValueSpecificationBuilder.js';
|
78
81
|
import type {
|
@@ -287,6 +290,24 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
287
290
|
return this.allVariables.map((e) => e.name);
|
288
291
|
}
|
289
292
|
|
293
|
+
getQueryExecutionContext(): QueryExecutionContext {
|
294
|
+
const queryExeContext = new QueryExplicitExecutionContext();
|
295
|
+
const runtimeValue = guaranteeType(
|
296
|
+
this.executionContextState.runtimeValue,
|
297
|
+
RuntimePointer,
|
298
|
+
'Query runtime must be of type runtime pointer',
|
299
|
+
);
|
300
|
+
assertNonNullable(
|
301
|
+
this.executionContextState.mapping,
|
302
|
+
'Query required mapping to update',
|
303
|
+
);
|
304
|
+
queryExeContext.mapping = PackageableElementExplicitReference.create(
|
305
|
+
this.executionContextState.mapping,
|
306
|
+
);
|
307
|
+
queryExeContext.runtime = runtimeValue.packageableRuntime;
|
308
|
+
return queryExeContext;
|
309
|
+
}
|
310
|
+
|
290
311
|
/**
|
291
312
|
* Gets information about the current queryBuilderState.
|
292
313
|
* This information can be used as a part of analytics
|
@@ -279,6 +279,13 @@ export class QueryBuilderTDSState
|
|
279
279
|
get fetchStructureValidationIssues(): string[] {
|
280
280
|
const validationIssues: string[] = [];
|
281
281
|
|
282
|
+
const hasEmptyProjectionColumnName = this.projectionColumns.some(
|
283
|
+
(column) => column.columnName.length === 0,
|
284
|
+
);
|
285
|
+
if (hasEmptyProjectionColumnName) {
|
286
|
+
validationIssues.push('Query has projection column with no name');
|
287
|
+
}
|
288
|
+
|
282
289
|
const hasInValidCalendarAggregateColumns =
|
283
290
|
this.aggregationState.columns.some(
|
284
291
|
(column) =>
|