@finos/legend-query-builder 4.14.9 → 4.14.11
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/QueryBuilderEvent.d.ts +2 -1
- package/lib/__lib__/QueryBuilderEvent.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderEvent.js +1 -0
- package/lib/__lib__/QueryBuilderEvent.js.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.d.ts +3 -1
- package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
- package/lib/__lib__/QueryBuilderTesting.js +3 -0
- package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
- package/lib/components/QueryBuilder.d.ts.map +1 -1
- package/lib/components/QueryBuilder.js +45 -27
- package/lib/components/QueryBuilder.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +86 -44
- package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
- package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
- package/lib/components/shared/LambdaEditor.js +10 -5
- package/lib/components/shared/LambdaEditor.js.map +1 -1
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.d.ts.map +1 -1
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.js +12 -11
- package/lib/components/shared/QueryBuilderPropertyInfoTooltip.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/QueryBuilderChangeHistoryState.d.ts +35 -0
- package/lib/stores/QueryBuilderChangeHistoryState.d.ts.map +1 -0
- package/lib/stores/QueryBuilderChangeHistoryState.js +106 -0
- package/lib/stores/QueryBuilderChangeHistoryState.js.map +1 -0
- 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/fetch-structure/tds/QueryResultSetModifierState.d.ts +2 -2
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js +7 -7
- package/lib/stores/fetch-structure/tds/QueryResultSetModifierState.js.map +1 -1
- package/package.json +5 -5
- package/src/__lib__/QueryBuilderEvent.ts +2 -0
- package/src/__lib__/QueryBuilderTesting.ts +3 -0
- package/src/components/QueryBuilder.tsx +41 -0
- package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +174 -94
- package/src/components/shared/LambdaEditor.tsx +10 -8
- package/src/components/shared/QueryBuilderPropertyInfoTooltip.tsx +81 -65
- package/src/stores/QueryBuilderChangeHistoryState.ts +129 -0
- package/src/stores/QueryBuilderState.ts +6 -0
- package/src/stores/fetch-structure/tds/QueryResultSetModifierState.ts +7 -12
- package/tsconfig.json +1 -0
@@ -18,6 +18,7 @@ import {
|
|
18
18
|
ShareBoxIcon,
|
19
19
|
type TooltipPlacement,
|
20
20
|
Tooltip,
|
21
|
+
ClickAwayListener,
|
21
22
|
} from '@finos/legend-art';
|
22
23
|
import {
|
23
24
|
type AbstractProperty,
|
@@ -137,73 +138,88 @@ export const QueryBuilderPropertyInfoTooltip: React.FC<{
|
|
137
138
|
explorerState,
|
138
139
|
} = props;
|
139
140
|
|
141
|
+
const [open, setIsOpen] = useState(false);
|
142
|
+
|
140
143
|
return (
|
141
|
-
<
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
onClick={() => explorerState.highlightTreeNode(path)}
|
171
|
-
title="Show in tree"
|
172
|
-
>
|
173
|
-
<ShareBoxIcon color="white" />
|
174
|
-
</button>
|
144
|
+
<ClickAwayListener onClickAway={() => setIsOpen(false)}>
|
145
|
+
<div>
|
146
|
+
<Tooltip
|
147
|
+
arrow={true}
|
148
|
+
{...(placement !== undefined ? { placement } : {})}
|
149
|
+
classes={{
|
150
|
+
tooltip: 'query-builder__tooltip',
|
151
|
+
arrow: 'query-builder__tooltip__arrow',
|
152
|
+
tooltipPlacementRight: 'query-builder__tooltip--right',
|
153
|
+
}}
|
154
|
+
open={open}
|
155
|
+
onClose={() => setIsOpen(false)}
|
156
|
+
TransitionProps={{
|
157
|
+
// disable transition
|
158
|
+
// NOTE: somehow, this is the only workaround we have, if for example
|
159
|
+
// we set `appear = true`, the tooltip will jump out of position
|
160
|
+
timeout: 0,
|
161
|
+
}}
|
162
|
+
disableFocusListener={true}
|
163
|
+
disableHoverListener={true}
|
164
|
+
disableTouchListener={true}
|
165
|
+
title={
|
166
|
+
<div className="query-builder__tooltip__content">
|
167
|
+
<div className="query-builder__tooltip__header">{title}</div>
|
168
|
+
<div className="query-builder__tooltip__item">
|
169
|
+
<div className="query-builder__tooltip__item__label">Type</div>
|
170
|
+
<div className="query-builder__tooltip__item__value">
|
171
|
+
{type?.path ?? property.genericType.value.rawType.path}
|
172
|
+
</div>
|
175
173
|
</div>
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
174
|
+
<div className="query-builder__tooltip__item">
|
175
|
+
<div className="query-builder__tooltip__item__label">Path</div>
|
176
|
+
<div className="query-builder__tooltip__item__value">
|
177
|
+
{path}
|
178
|
+
</div>
|
179
|
+
{explorerState && (
|
180
|
+
<div className="query-builder__tooltip__item__action">
|
181
|
+
<button
|
182
|
+
onClick={() => explorerState.highlightTreeNode(path)}
|
183
|
+
title="Show in tree"
|
184
|
+
>
|
185
|
+
<ShareBoxIcon color="white" />
|
186
|
+
</button>
|
187
|
+
</div>
|
188
|
+
)}
|
189
|
+
</div>
|
190
|
+
<div className="query-builder__tooltip__item">
|
191
|
+
<div className="query-builder__tooltip__item__label">
|
192
|
+
Multiplicity
|
193
|
+
</div>
|
194
|
+
<div className="query-builder__tooltip__item__value">
|
195
|
+
{getMultiplicityDescription(property.multiplicity)}
|
196
|
+
</div>
|
197
|
+
</div>
|
198
|
+
<div className="query-builder__tooltip__item">
|
199
|
+
<div className="query-builder__tooltip__item__label">
|
200
|
+
Derived Property
|
201
|
+
</div>
|
202
|
+
<div className="query-builder__tooltip__item__value">
|
203
|
+
{property instanceof DerivedProperty ? 'Yes' : 'No'}
|
204
|
+
</div>
|
205
|
+
</div>
|
206
|
+
<div className="query-builder__tooltip__item">
|
207
|
+
<div className="query-builder__tooltip__item__label">
|
208
|
+
Mapped
|
209
|
+
</div>
|
210
|
+
<div className="query-builder__tooltip__item__value">
|
211
|
+
{isMapped ? 'Yes' : 'No'}
|
212
|
+
</div>
|
213
|
+
</div>
|
214
|
+
<QueryBuilderTaggedValueInfoTooltip
|
215
|
+
taggedValues={property.taggedValues}
|
216
|
+
/>
|
198
217
|
</div>
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
>
|
206
|
-
{children}
|
207
|
-
</Tooltip>
|
218
|
+
}
|
219
|
+
>
|
220
|
+
<div onClick={() => setIsOpen(true)}>{children}</div>
|
221
|
+
</Tooltip>
|
222
|
+
</div>
|
223
|
+
</ClickAwayListener>
|
208
224
|
);
|
209
225
|
};
|
@@ -0,0 +1,129 @@
|
|
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 { type RawLambda } from '@finos/legend-graph';
|
18
|
+
import {
|
19
|
+
ActionState,
|
20
|
+
LogEvent,
|
21
|
+
assertErrorThrown,
|
22
|
+
guaranteeNonNullable,
|
23
|
+
} from '@finos/legend-shared';
|
24
|
+
import { makeObservable, observable, computed, action } from 'mobx';
|
25
|
+
import type { QueryBuilderState } from './QueryBuilderState.js';
|
26
|
+
import { QUERY_BUILDER_EVENT } from '../__lib__/QueryBuilderEvent.js';
|
27
|
+
|
28
|
+
export class QueryBuilderChangeHistoryState {
|
29
|
+
readonly queryBuilderState: QueryBuilderState;
|
30
|
+
readonly initState = ActionState.create();
|
31
|
+
|
32
|
+
querySnapshotBuffer: RawLambda[] = [];
|
33
|
+
currentQuery: RawLambda | undefined;
|
34
|
+
pointer = -1;
|
35
|
+
bufferSize = 10;
|
36
|
+
|
37
|
+
constructor(queryBuilderState: QueryBuilderState) {
|
38
|
+
makeObservable(this, {
|
39
|
+
currentQuery: observable,
|
40
|
+
pointer: observable,
|
41
|
+
querySnapshotBuffer: observable,
|
42
|
+
initialize: action,
|
43
|
+
undo: action,
|
44
|
+
redo: action,
|
45
|
+
setCurrentQuery: action,
|
46
|
+
cacheNewQuery: action,
|
47
|
+
canRedo: computed,
|
48
|
+
canUndo: computed,
|
49
|
+
});
|
50
|
+
|
51
|
+
this.queryBuilderState = queryBuilderState;
|
52
|
+
}
|
53
|
+
|
54
|
+
get canRedo(): boolean {
|
55
|
+
return this.pointer < this.querySnapshotBuffer.length - 1;
|
56
|
+
}
|
57
|
+
|
58
|
+
get canUndo(): boolean {
|
59
|
+
return this.pointer > 0;
|
60
|
+
}
|
61
|
+
|
62
|
+
redo(): void {
|
63
|
+
if (this.canRedo) {
|
64
|
+
this.pointer = this.pointer + 1;
|
65
|
+
const query = this.querySnapshotBuffer[this.pointer];
|
66
|
+
this.setCurrentQuery(query);
|
67
|
+
this.queryBuilderState.rebuildWithQuery(guaranteeNonNullable(query), {
|
68
|
+
preserveParameterValues: true,
|
69
|
+
preserveResult: true,
|
70
|
+
});
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
undo(): void {
|
75
|
+
if (this.canUndo) {
|
76
|
+
this.pointer = this.pointer - 1;
|
77
|
+
const query = this.querySnapshotBuffer[this.pointer];
|
78
|
+
this.setCurrentQuery(query);
|
79
|
+
this.queryBuilderState.rebuildWithQuery(guaranteeNonNullable(query), {
|
80
|
+
preserveParameterValues: true,
|
81
|
+
preserveResult: true,
|
82
|
+
});
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
setCurrentQuery(query: RawLambda | undefined): void {
|
87
|
+
this.currentQuery = query;
|
88
|
+
}
|
89
|
+
|
90
|
+
initialize(initialQuery: RawLambda): void {
|
91
|
+
if (this.queryBuilderState.isQuerySupported) {
|
92
|
+
this.initState.inProgress();
|
93
|
+
this.currentQuery = initialQuery;
|
94
|
+
this.querySnapshotBuffer.push(initialQuery);
|
95
|
+
this.pointer = this.pointer + 1;
|
96
|
+
this.initState.complete();
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
cacheNewQuery(query: RawLambda): void {
|
101
|
+
try {
|
102
|
+
if (this.queryBuilderState.isQuerySupported) {
|
103
|
+
if (query.hashCode !== this.currentQuery?.hashCode) {
|
104
|
+
if (
|
105
|
+
this.querySnapshotBuffer.length === this.bufferSize &&
|
106
|
+
this.pointer === this.querySnapshotBuffer.length - 1
|
107
|
+
) {
|
108
|
+
// only record 10 query snapshots
|
109
|
+
this.querySnapshotBuffer = this.querySnapshotBuffer.slice(1);
|
110
|
+
} else {
|
111
|
+
this.querySnapshotBuffer = this.querySnapshotBuffer.slice(
|
112
|
+
0,
|
113
|
+
this.pointer + 1,
|
114
|
+
);
|
115
|
+
}
|
116
|
+
this.querySnapshotBuffer.push(query);
|
117
|
+
this.pointer = this.querySnapshotBuffer.length - 1;
|
118
|
+
this.setCurrentQuery(query);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
} catch (error) {
|
122
|
+
assertErrorThrown(error);
|
123
|
+
this.queryBuilderState.applicationStore.logService.error(
|
124
|
+
LogEvent.create(QUERY_BUILDER_EVENT.CHANGE_HISTORY_ERROR),
|
125
|
+
`Can't cache query in query builder change history buffer: ${error.message}`,
|
126
|
+
);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
@@ -104,6 +104,7 @@ import {
|
|
104
104
|
} from './QueryBuilderExecutionContextState.js';
|
105
105
|
import type { QueryBuilderConfig } from '../graph-manager/QueryBuilderConfig.js';
|
106
106
|
import { QUERY_BUILDER_EVENT } from '../__lib__/QueryBuilderEvent.js';
|
107
|
+
import { QueryBuilderChangeHistoryState } from './QueryBuilderChangeHistoryState.js';
|
107
108
|
|
108
109
|
export interface QuerySDLC {}
|
109
110
|
|
@@ -136,6 +137,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
136
137
|
resultState: QueryBuilderResultState;
|
137
138
|
textEditorState: QueryBuilderTextEditorState;
|
138
139
|
unsupportedQueryState: QueryBuilderUnsupportedQueryState;
|
140
|
+
changeHistoryState: QueryBuilderChangeHistoryState;
|
139
141
|
showFunctionsExplorerPanel = false;
|
140
142
|
showParametersPanel = false;
|
141
143
|
isEditingWatermark = false;
|
@@ -184,6 +186,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
184
186
|
isCheckingEntitlments: observable,
|
185
187
|
isCalendarEnabled: observable,
|
186
188
|
changeDetectionState: observable,
|
189
|
+
changeHistoryState: observable,
|
187
190
|
executionContextState: observable,
|
188
191
|
class: observable,
|
189
192
|
isQueryChatOpened: observable,
|
@@ -236,6 +239,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
236
239
|
this.graphManagerState.pluginManager.getPureGraphManagerPlugins(),
|
237
240
|
);
|
238
241
|
this.changeDetectionState = new QueryBuilderChangeDetectionState(this);
|
242
|
+
this.changeHistoryState = new QueryBuilderChangeHistoryState(this);
|
239
243
|
this.config = config;
|
240
244
|
this.sourceInfo = sourceInfo;
|
241
245
|
}
|
@@ -441,6 +445,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
441
445
|
this.explorerState.refreshTreeData();
|
442
446
|
this.fetchStructureState.implementation.onClassChange(val);
|
443
447
|
this.milestoningState.updateMilestoningConfiguration();
|
448
|
+
this.changeHistoryState.cacheNewQuery(this.buildQuery());
|
444
449
|
}
|
445
450
|
|
446
451
|
changeMapping(val: Mapping, options?: { keepQueryContent?: boolean }): void {
|
@@ -553,6 +558,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
|
|
553
558
|
});
|
554
559
|
this.resetQueryResult();
|
555
560
|
this.changeDetectionState.initialize(query);
|
561
|
+
this.changeHistoryState.initialize(query);
|
556
562
|
}
|
557
563
|
|
558
564
|
/**
|
@@ -16,12 +16,7 @@
|
|
16
16
|
|
17
17
|
import { action, computed, makeObservable, observable } from 'mobx';
|
18
18
|
import type { QueryBuilderTDSState } from './QueryBuilderTDSState.js';
|
19
|
-
import {
|
20
|
-
addUniqueEntry,
|
21
|
-
deleteEntry,
|
22
|
-
type Hashable,
|
23
|
-
hashArray,
|
24
|
-
} from '@finos/legend-shared';
|
19
|
+
import { addUniqueEntry, type Hashable, hashArray } from '@finos/legend-shared';
|
25
20
|
import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../../QueryBuilderStateHashUtils.js';
|
26
21
|
import type { QueryBuilderTDSColumnState } from './QueryBuilderTDSColumnState.js';
|
27
22
|
import { COLUMN_SORT_TYPE } from '../../../graph/QueryBuilderMetaModelConst.js';
|
@@ -76,8 +71,8 @@ export class QueryResultSetModifierState implements Hashable {
|
|
76
71
|
slice: observable.ref,
|
77
72
|
setShowModal: action,
|
78
73
|
setLimit: action,
|
79
|
-
|
80
|
-
|
74
|
+
setDistinct: action,
|
75
|
+
setSortColumns: action,
|
81
76
|
addSortColumn: action,
|
82
77
|
updateSortColumns: action,
|
83
78
|
setSlice: action,
|
@@ -96,12 +91,12 @@ export class QueryResultSetModifierState implements Hashable {
|
|
96
91
|
this.limit = val === undefined || val <= 0 ? undefined : val;
|
97
92
|
}
|
98
93
|
|
99
|
-
|
100
|
-
this.distinct =
|
94
|
+
setDistinct(val: boolean): void {
|
95
|
+
this.distinct = val;
|
101
96
|
}
|
102
97
|
|
103
|
-
|
104
|
-
|
98
|
+
setSortColumns(val: SortColumnState[]): void {
|
99
|
+
this.sortColumns = val;
|
105
100
|
}
|
106
101
|
|
107
102
|
addSortColumn(val: SortColumnState): void {
|
package/tsconfig.json
CHANGED
@@ -56,6 +56,7 @@
|
|
56
56
|
"./src/graph-manager/protocol/pure/v1/V1_QueryBuilder_PureGraphManagerExtension.ts",
|
57
57
|
"./src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts",
|
58
58
|
"./src/stores/QueryBuilderChangeDetectionState.ts",
|
59
|
+
"./src/stores/QueryBuilderChangeHistoryState.ts",
|
59
60
|
"./src/stores/QueryBuilderCommand.ts",
|
60
61
|
"./src/stores/QueryBuilderConfig.ts",
|
61
62
|
"./src/stores/QueryBuilderConstantsState.ts",
|