@finos/legend-application-query 5.0.1 → 5.2.1
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/application/LegendQueryApplicationConfig.d.ts +17 -1
- package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendQueryApplicationConfig.js +23 -1
- package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
- package/lib/components/QueryBuilder.d.ts.map +1 -1
- package/lib/components/QueryBuilder.js +3 -1
- package/lib/components/QueryBuilder.js.map +1 -1
- package/lib/components/QueryBuilderExplorerPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderExplorerPanel.js +10 -35
- package/lib/components/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.js +78 -35
- package/lib/components/QueryBuilderFetchStructurePanel.js.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.js +80 -66
- package/lib/components/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/components/QueryBuilderFunctionsExplorerPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFunctionsExplorerPanel.js +9 -39
- package/lib/components/QueryBuilderFunctionsExplorerPanel.js.map +1 -1
- package/lib/components/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderGraphFetchTreePanel.js +5 -5
- package/lib/components/QueryBuilderGraphFetchTreePanel.js.map +1 -1
- package/lib/components/QueryBuilderLambdaEditor.d.ts +1 -0
- package/lib/components/QueryBuilderLambdaEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderLambdaEditor.js +2 -2
- package/lib/components/QueryBuilderLambdaEditor.js.map +1 -1
- package/lib/components/QueryBuilderMilestoneEditor.js +5 -5
- package/lib/components/QueryBuilderMilestoneEditor.js.map +1 -1
- package/lib/components/QueryBuilderPanelIssueCountBadge.d.ts +20 -0
- package/lib/components/QueryBuilderPanelIssueCountBadge.d.ts.map +1 -0
- package/lib/components/QueryBuilderPanelIssueCountBadge.js +28 -0
- package/lib/components/QueryBuilderPanelIssueCountBadge.js.map +1 -0
- package/lib/components/QueryBuilderParameterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderParameterPanel.js +13 -33
- package/lib/components/QueryBuilderParameterPanel.js.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.js +59 -62
- package/lib/components/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/QueryBuilderProjectionPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderProjectionPanel.js +47 -63
- package/lib/components/QueryBuilderProjectionPanel.js.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertyExpressionEditor.js +11 -11
- package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
- package/lib/components/QueryBuilderPropertySearchPanel.js +5 -7
- package/lib/components/QueryBuilderPropertySearchPanel.js.map +1 -1
- package/lib/components/QueryBuilderResultModifierPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultModifierPanel.js +3 -1
- package/lib/components/QueryBuilderResultModifierPanel.js.map +1 -1
- package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +37 -23
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/QueryBuilderSetupPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderSetupPanel.js +10 -9
- package/lib/components/QueryBuilderSetupPanel.js.map +1 -1
- package/lib/components/QueryBuilderUnsupportedQueryEditor.d.ts.map +1 -1
- package/lib/components/QueryBuilderUnsupportedQueryEditor.js +4 -2
- package/lib/components/QueryBuilderUnsupportedQueryEditor.js.map +1 -1
- package/lib/components/QueryEditor.d.ts.map +1 -1
- package/lib/components/QueryEditor.js +16 -4
- package/lib/components/QueryEditor.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +10 -9
- package/lib/stores/QueryBuilderExplorerState.d.ts +1 -1
- package/lib/stores/QueryBuilderExplorerState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderExplorerState.js +18 -3
- package/lib/stores/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/QueryBuilderFetchStructureState.d.ts +8 -1
- package/lib/stores/QueryBuilderFetchStructureState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderFetchStructureState.js +10 -2
- package/lib/stores/QueryBuilderFetchStructureState.js.map +1 -1
- package/lib/stores/QueryBuilderFilterState.d.ts +10 -5
- package/lib/stores/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderFilterState.js +34 -8
- package/lib/stores/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderGraphFetchTreeState.js +6 -3
- package/lib/stores/QueryBuilderGraphFetchTreeState.js.map +1 -1
- package/lib/stores/QueryBuilderLambdaProcessor.d.ts.map +1 -1
- package/lib/stores/QueryBuilderLambdaProcessor.js +2 -0
- package/lib/stores/QueryBuilderLambdaProcessor.js.map +1 -1
- package/lib/stores/QueryBuilderOperatorLoader.d.ts +47 -0
- package/lib/stores/QueryBuilderOperatorLoader.d.ts.map +1 -0
- package/lib/stores/QueryBuilderOperatorLoader.js +94 -0
- package/lib/stores/QueryBuilderOperatorLoader.js.map +1 -0
- package/lib/stores/QueryBuilderOperatorsHelper.d.ts +1 -0
- package/lib/stores/QueryBuilderOperatorsHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderOperatorsHelper.js +28 -1
- package/lib/stores/QueryBuilderOperatorsHelper.js.map +1 -1
- package/lib/stores/QueryBuilderPostFilterState.d.ts +9 -6
- package/lib/stores/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderPostFilterState.js +31 -7
- package/lib/stores/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/QueryBuilderPreviewDataHelper.d.ts +4 -3
- package/lib/stores/QueryBuilderPreviewDataHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderPreviewDataHelper.js +77 -97
- package/lib/stores/QueryBuilderPreviewDataHelper.js.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.d.ts +4 -7
- package/lib/stores/QueryBuilderProjectionState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.js +23 -39
- package/lib/stores/QueryBuilderProjectionState.js.map +1 -1
- package/lib/stores/QueryBuilderPropertySearchPanelState.js +1 -1
- package/lib/stores/QueryBuilderPropertySearchPanelState.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts +5 -2
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +19 -7
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/QueryBuilderSetupState.js +1 -1
- package/lib/stores/QueryBuilderSetupState.js.map +1 -1
- package/lib/stores/QueryBuilderState.d.ts +7 -0
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +18 -58
- package/lib/stores/QueryBuilderState.js.map +1 -1
- package/lib/stores/QueryBuilderTestUtils.d.ts +24 -0
- package/lib/stores/QueryBuilderTestUtils.d.ts.map +1 -0
- package/lib/stores/QueryBuilderTestUtils.js +49 -0
- package/lib/stores/QueryBuilderTestUtils.js.map +1 -0
- package/lib/stores/QueryBuilderTypeaheadHelper.d.ts +24 -0
- package/lib/stores/QueryBuilderTypeaheadHelper.d.ts.map +1 -0
- package/lib/stores/QueryBuilderTypeaheadHelper.js +89 -0
- package/lib/stores/QueryBuilderTypeaheadHelper.js.map +1 -0
- package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
- package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js +7 -7
- package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.js.map +1 -1
- package/lib/stores/QueryEditorStore.d.ts.map +1 -1
- package/lib/stores/QueryEditorStore.js +14 -3
- package/lib/stores/QueryEditorStore.js.map +1 -1
- package/lib/stores/QueryFunctionsExplorerState.d.ts +2 -6
- package/lib/stores/QueryFunctionsExplorerState.d.ts.map +1 -1
- package/lib/stores/QueryFunctionsExplorerState.js +2 -11
- package/lib/stores/QueryFunctionsExplorerState.js.map +1 -1
- package/lib/stores/QueryParametersState.d.ts +1 -3
- package/lib/stores/QueryParametersState.d.ts.map +1 -1
- package/lib/stores/QueryParametersState.js +1 -4
- package/lib/stores/QueryParametersState.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js +9 -32
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_Equal.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js +9 -32
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js +9 -32
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js +9 -33
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js +9 -32
- package/lib/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js +7 -30
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js +8 -31
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js +8 -31
- package/lib/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
- package/package.json +17 -16
- package/src/application/LegendQueryApplicationConfig.ts +35 -1
- package/src/components/QueryBuilder.tsx +13 -2
- package/src/components/QueryBuilderExplorerPanel.tsx +20 -57
- package/src/components/QueryBuilderFetchStructurePanel.tsx +94 -41
- package/src/components/QueryBuilderFilterPanel.tsx +271 -232
- package/src/components/QueryBuilderFunctionsExplorerPanel.tsx +24 -68
- package/src/components/QueryBuilderGraphFetchTreePanel.tsx +34 -25
- package/src/components/QueryBuilderLambdaEditor.tsx +3 -0
- package/src/components/QueryBuilderMilestoneEditor.tsx +34 -34
- package/src/components/QueryBuilderPanelIssueCountBadge.tsx +38 -0
- package/src/components/QueryBuilderParameterPanel.tsx +23 -55
- package/src/components/QueryBuilderPostFilterPanel.tsx +245 -233
- package/src/components/QueryBuilderProjectionPanel.tsx +127 -154
- package/src/components/QueryBuilderPropertyExpressionEditor.tsx +61 -57
- package/src/components/QueryBuilderPropertySearchPanel.tsx +9 -9
- package/src/components/QueryBuilderResultModifierPanel.tsx +4 -2
- package/src/components/QueryBuilderResultPanel.tsx +139 -91
- package/src/components/QueryBuilderSetupPanel.tsx +13 -12
- package/src/components/QueryBuilderUnsupportedQueryEditor.tsx +4 -2
- package/src/components/QueryEditor.tsx +39 -1
- package/src/stores/QueryBuilderExplorerState.ts +22 -3
- package/src/stores/QueryBuilderFetchStructureState.ts +18 -2
- package/src/stores/QueryBuilderFilterState.ts +52 -7
- package/src/stores/QueryBuilderGraphFetchTreeState.ts +14 -8
- package/src/stores/QueryBuilderLambdaProcessor.ts +8 -0
- package/src/stores/QueryBuilderOperatorLoader.ts +133 -0
- package/src/stores/QueryBuilderOperatorsHelper.ts +35 -0
- package/src/stores/QueryBuilderPostFilterState.ts +47 -8
- package/src/stores/QueryBuilderPreviewDataHelper.ts +122 -217
- package/src/stores/QueryBuilderProjectionState.ts +40 -53
- package/src/stores/QueryBuilderPropertySearchPanelState.ts +1 -1
- package/src/stores/QueryBuilderResultState.ts +27 -9
- package/src/stores/QueryBuilderSetupState.ts +1 -1
- package/src/stores/QueryBuilderState.ts +35 -94
- package/src/stores/QueryBuilderTestUtils.ts +93 -0
- package/src/stores/QueryBuilderTypeaheadHelper.ts +149 -0
- package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +9 -7
- package/src/stores/QueryEditorStore.ts +19 -3
- package/src/stores/QueryFunctionsExplorerState.ts +1 -11
- package/src/stores/QueryParametersState.ts +1 -3
- package/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts +14 -36
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts +17 -36
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts +17 -36
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts +17 -37
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts +17 -36
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts +14 -34
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts +19 -37
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts +19 -37
- package/tsconfig.json +4 -0
@@ -14,6 +14,7 @@
|
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
16
|
|
17
|
+
import { useRef, useState } from 'react';
|
17
18
|
import {
|
18
19
|
clsx,
|
19
20
|
CheckSquareIcon,
|
@@ -28,6 +29,7 @@ import {
|
|
28
29
|
SearchIcon,
|
29
30
|
ChevronDownIcon,
|
30
31
|
ChevronRightIcon,
|
32
|
+
useDragPreviewLayer,
|
31
33
|
} from '@finos/legend-art';
|
32
34
|
import {
|
33
35
|
Class,
|
@@ -37,9 +39,7 @@ import {
|
|
37
39
|
} from '@finos/legend-graph';
|
38
40
|
import { guaranteeNonNullable } from '@finos/legend-shared';
|
39
41
|
import { observer } from 'mobx-react-lite';
|
40
|
-
import { useEffect, useRef, useState } from 'react';
|
41
42
|
import { useDrag } from 'react-dnd';
|
42
|
-
import { getEmptyImage } from 'react-dnd-html5-backend';
|
43
43
|
import { QUERY_BUILDER_PROPERTY_SEARCH_TYPE } from '../QueryBuilder_Const.js';
|
44
44
|
import {
|
45
45
|
type QueryBuilderExplorerTreeNodeData,
|
@@ -116,7 +116,9 @@ const QueryBuilderTreeNodeViewer = observer(
|
|
116
116
|
props;
|
117
117
|
const [isExpandable, setIsExpandable] = useState(false);
|
118
118
|
const propertySearchPanelState = explorerState.propertySearchPanelState;
|
119
|
-
const [, dragConnector, dragPreviewConnector] = useDrag
|
119
|
+
const [, dragConnector, dragPreviewConnector] = useDrag<{
|
120
|
+
node?: QueryBuilderExplorerTreePropertyNodeData;
|
121
|
+
}>(
|
120
122
|
() => ({
|
121
123
|
type:
|
122
124
|
node instanceof QueryBuilderExplorerTreePropertyNodeData
|
@@ -126,16 +128,17 @@ const QueryBuilderTreeNodeViewer = observer(
|
|
126
128
|
? QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.CLASS_PROPERTY
|
127
129
|
: QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.PRIMITIVE_PROPERTY
|
128
130
|
: QUERY_BUILDER_EXPLORER_TREE_DND_TYPE.ROOT,
|
129
|
-
item: ()
|
131
|
+
item: () =>
|
130
132
|
node instanceof QueryBuilderExplorerTreePropertyNodeData
|
131
133
|
? { node }
|
132
134
|
: {},
|
133
|
-
collect: (monitor)
|
135
|
+
collect: (monitor) => ({
|
134
136
|
isDragging: monitor.isDragging(),
|
135
137
|
}),
|
136
138
|
}),
|
137
139
|
[node],
|
138
140
|
);
|
141
|
+
useDragPreviewLayer(dragPreviewConnector);
|
139
142
|
const isMultiple =
|
140
143
|
(node instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
141
144
|
(node.property.multiplicity.upperBound === undefined ||
|
@@ -169,6 +172,7 @@ const QueryBuilderTreeNodeViewer = observer(
|
|
169
172
|
),
|
170
173
|
);
|
171
174
|
if (
|
175
|
+
propertyTreeNodeData &&
|
172
176
|
!(propertyTreeNodeData.type instanceof Class) &&
|
173
177
|
propertyTreeNodeData.mappingData.mapped
|
174
178
|
) {
|
@@ -185,10 +189,6 @@ const QueryBuilderTreeNodeViewer = observer(
|
|
185
189
|
node.parentId === pn.id,
|
186
190
|
);
|
187
191
|
|
188
|
-
useEffect(() => {
|
189
|
-
dragPreviewConnector(getEmptyImage(), { captureDraggingState: true });
|
190
|
-
}, [dragPreviewConnector]);
|
191
|
-
|
192
192
|
return (
|
193
193
|
<div>
|
194
194
|
<div
|
@@ -32,6 +32,7 @@ import {
|
|
32
32
|
import type { QueryBuilderState } from '../stores/QueryBuilderState.js';
|
33
33
|
import type { QueryBuilderProjectionColumnState } from '../stores/QueryBuilderProjectionState.js';
|
34
34
|
import { guaranteeNonNullable } from '@finos/legend-shared';
|
35
|
+
import { useApplicationStore } from '@finos/legend-application';
|
35
36
|
|
36
37
|
const ColumnSortEditor = observer(
|
37
38
|
(props: {
|
@@ -39,6 +40,7 @@ const ColumnSortEditor = observer(
|
|
39
40
|
columnSort: SortColumnState;
|
40
41
|
}) => {
|
41
42
|
const { queryBuilderState, columnSort } = props;
|
43
|
+
const applicationStore = useApplicationStore();
|
42
44
|
const projectionState =
|
43
45
|
queryBuilderState.fetchStructureState.projectionState;
|
44
46
|
const sortColumns = queryBuilderState.resultSetModifierState.sortColumns;
|
@@ -81,7 +83,7 @@ const ColumnSortEditor = observer(
|
|
81
83
|
disabled={projectionOptions.length <= 1}
|
82
84
|
onChange={onChange}
|
83
85
|
value={value}
|
84
|
-
darkMode={
|
86
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
85
87
|
/>
|
86
88
|
<button
|
87
89
|
className="btn--dark btn--sm query-builder__projection__options__sort__type-btn"
|
@@ -95,7 +97,7 @@ const ColumnSortEditor = observer(
|
|
95
97
|
)}
|
96
98
|
</button>
|
97
99
|
<button
|
98
|
-
className="query-builder__projection__options__sort__remove-btn"
|
100
|
+
className="query-builder__projection__options__sort__remove-btn btn--dark btn--caution"
|
99
101
|
onClick={deleteColumnSort}
|
100
102
|
tabIndex={-1}
|
101
103
|
title={'Remove'}
|
@@ -25,6 +25,7 @@ import {
|
|
25
25
|
CaretDownIcon,
|
26
26
|
ContextMenu,
|
27
27
|
clsx,
|
28
|
+
PauseCircleIcon,
|
28
29
|
} from '@finos/legend-art';
|
29
30
|
import { observer } from 'mobx-react-lite';
|
30
31
|
import { flowResult } from 'mobx';
|
@@ -287,6 +288,61 @@ const QueryBuilderResultContextMenu = observer(
|
|
287
288
|
}),
|
288
289
|
);
|
289
290
|
|
291
|
+
const QueryBuilderGridResult = observer(
|
292
|
+
(props: {
|
293
|
+
executionResult: TdsExecutionResult;
|
294
|
+
queryBuilderState: QueryBuilderState;
|
295
|
+
}) => {
|
296
|
+
const { executionResult, queryBuilderState } = props;
|
297
|
+
const [cellDoubleClickedEvent, setCellDoubleClickedEvent] =
|
298
|
+
useState<CellMouseOverEvent | null>(null);
|
299
|
+
const columns = executionResult.result.columns;
|
300
|
+
const rowData = executionResult.result.rows.map((_row) => {
|
301
|
+
const row: Record<PropertyKey, unknown> = {};
|
302
|
+
const cols = executionResult.result.columns;
|
303
|
+
_row.values.forEach((value, idx) => {
|
304
|
+
// `ag-grid` shows `false` value as empty string so we have
|
305
|
+
// call `.toString()` to avoid this behavior.
|
306
|
+
// See https://github.com/finos/legend-studio/issues/1008
|
307
|
+
row[cols[idx] as string] = isBoolean(value) ? String(value) : value;
|
308
|
+
});
|
309
|
+
return row;
|
310
|
+
});
|
311
|
+
|
312
|
+
return (
|
313
|
+
<ContextMenu
|
314
|
+
content={
|
315
|
+
<QueryBuilderResultContextMenu
|
316
|
+
event={cellDoubleClickedEvent}
|
317
|
+
queryBuilderState={queryBuilderState}
|
318
|
+
/>
|
319
|
+
}
|
320
|
+
menuProps={{ elevation: 7 }}
|
321
|
+
key={executionResult._UUID}
|
322
|
+
className={clsx('ag-theme-balham-dark query-builder__result__tds-grid')}
|
323
|
+
>
|
324
|
+
<AgGridReact
|
325
|
+
rowData={rowData}
|
326
|
+
onCellMouseOver={(event): void => {
|
327
|
+
setCellDoubleClickedEvent(event);
|
328
|
+
}}
|
329
|
+
>
|
330
|
+
{columns.map((colName) => (
|
331
|
+
<AgGridColumn
|
332
|
+
minWidth={50}
|
333
|
+
sortable={true}
|
334
|
+
resizable={true}
|
335
|
+
field={colName}
|
336
|
+
key={colName}
|
337
|
+
flex={1}
|
338
|
+
/>
|
339
|
+
))}
|
340
|
+
</AgGridReact>
|
341
|
+
</ContextMenu>
|
342
|
+
);
|
343
|
+
},
|
344
|
+
);
|
345
|
+
|
290
346
|
const QueryBuilderResultValues = observer(
|
291
347
|
(props: {
|
292
348
|
executionResult: ExecutionResult;
|
@@ -294,52 +350,11 @@ const QueryBuilderResultValues = observer(
|
|
294
350
|
}) => {
|
295
351
|
const { executionResult, queryBuilderState } = props;
|
296
352
|
if (executionResult instanceof TdsExecutionResult) {
|
297
|
-
const [cellDoubleClickedEvent, setCellDoubleClickedEvent] =
|
298
|
-
useState<CellMouseOverEvent | null>(null);
|
299
|
-
const columns = executionResult.result.columns;
|
300
|
-
const rowData = executionResult.result.rows.map((_row) => {
|
301
|
-
const row: Record<PropertyKey, unknown> = {};
|
302
|
-
const cols = executionResult.result.columns;
|
303
|
-
_row.values.forEach((value, idx) => {
|
304
|
-
// `ag-grid` shows `false` value as empty string so we have
|
305
|
-
// call `.toString()` to avoid this behavior.
|
306
|
-
// See https://github.com/finos/legend-studio/issues/1008
|
307
|
-
row[cols[idx] as string] = isBoolean(value) ? String(value) : value;
|
308
|
-
});
|
309
|
-
return row;
|
310
|
-
});
|
311
353
|
return (
|
312
|
-
<
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
queryBuilderState={queryBuilderState}
|
317
|
-
/>
|
318
|
-
}
|
319
|
-
menuProps={{ elevation: 7 }}
|
320
|
-
key={executionResult._UUID}
|
321
|
-
className={clsx(
|
322
|
-
'ag-theme-balham-dark query-builder__result__tds-grid',
|
323
|
-
)}
|
324
|
-
>
|
325
|
-
<AgGridReact
|
326
|
-
rowData={rowData}
|
327
|
-
onCellMouseOver={(event): void => {
|
328
|
-
setCellDoubleClickedEvent(event);
|
329
|
-
}}
|
330
|
-
>
|
331
|
-
{columns.map((colName) => (
|
332
|
-
<AgGridColumn
|
333
|
-
minWidth={50}
|
334
|
-
sortable={true}
|
335
|
-
resizable={true}
|
336
|
-
field={colName}
|
337
|
-
key={colName}
|
338
|
-
flex={1}
|
339
|
-
/>
|
340
|
-
))}
|
341
|
-
</AgGridReact>
|
342
|
-
</ContextMenu>
|
354
|
+
<QueryBuilderGridResult
|
355
|
+
queryBuilderState={queryBuilderState}
|
356
|
+
executionResult={executionResult}
|
357
|
+
/>
|
343
358
|
);
|
344
359
|
} else if (executionResult instanceof RawExecutionResult) {
|
345
360
|
return (
|
@@ -413,27 +428,35 @@ export const QueryBuilderResultPanel = observer(
|
|
413
428
|
],
|
414
429
|
});
|
415
430
|
};
|
416
|
-
const
|
431
|
+
const queryValidationIssues = queryBuilderState.validationIssues;
|
432
|
+
const isQueryValid =
|
433
|
+
!queryBuilderState.isQuerySupported() || !queryValidationIssues;
|
434
|
+
const runQuery = (): void => {
|
417
435
|
if (queryParametersState.parameterStates.length) {
|
418
436
|
queryParametersState.parameterValuesEditorState.open(
|
419
437
|
(): Promise<void> =>
|
420
|
-
flowResult(resultState.
|
438
|
+
flowResult(resultState.runQuery()).catch(
|
421
439
|
applicationStore.alertUnhandledError,
|
422
440
|
),
|
423
441
|
PARAMETER_SUBMIT_ACTION.EXECUTE,
|
424
442
|
);
|
425
443
|
} else {
|
426
|
-
flowResult(resultState.
|
444
|
+
flowResult(resultState.runQuery()).catch(
|
427
445
|
applicationStore.alertUnhandledError,
|
428
446
|
);
|
429
447
|
}
|
430
448
|
};
|
449
|
+
const cancelQuery = (): void => {
|
450
|
+
resultState.setIsRunningQuery(false);
|
451
|
+
queryBuilderState.resultState.setQueryRunPromise(undefined);
|
452
|
+
};
|
431
453
|
const generatePlan = applicationStore.guardUnhandledError(() =>
|
432
454
|
flowResult(resultState.generatePlan(false)),
|
433
455
|
);
|
434
456
|
const debugPlanGeneration = applicationStore.guardUnhandledError(() =>
|
435
457
|
flowResult(resultState.generatePlan(true)),
|
436
458
|
);
|
459
|
+
|
437
460
|
const changeLimit: React.ChangeEventHandler<HTMLInputElement> = (event) => {
|
438
461
|
const val = event.target.value;
|
439
462
|
queryBuilderState.resultState.setPreviewLimit(
|
@@ -469,52 +492,72 @@ export const QueryBuilderResultPanel = observer(
|
|
469
492
|
type="number"
|
470
493
|
value={resultState.previewLimit}
|
471
494
|
onChange={changeLimit}
|
495
|
+
disabled={!isQueryValid}
|
472
496
|
/>
|
473
497
|
</div>
|
474
498
|
)}
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
499
|
+
{resultState.isRunningQuery ? (
|
500
|
+
<button
|
501
|
+
className="query-builder__result__stop-btn"
|
502
|
+
onClick={cancelQuery}
|
503
|
+
tabIndex={-1}
|
504
|
+
disabled={!isQueryValid}
|
505
|
+
>
|
506
|
+
<div className="btn--dark btn--caution query-builder__result__stop-btn__label">
|
507
|
+
<PauseCircleIcon className="query-builder__result__stop-btn__label__icon" />
|
508
|
+
<div className="query-builder__result__stop-btn__label__title">
|
509
|
+
Stop
|
510
|
+
</div>
|
487
511
|
</div>
|
488
|
-
</
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
}
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
Generate Plan
|
501
|
-
</MenuContentItem>
|
502
|
-
<MenuContentItem
|
503
|
-
className="query-builder__result__execute-btn__option"
|
504
|
-
onClick={debugPlanGeneration}
|
505
|
-
>
|
506
|
-
Debug
|
507
|
-
</MenuContentItem>
|
508
|
-
</MenuContent>
|
512
|
+
</button>
|
513
|
+
) : (
|
514
|
+
<button
|
515
|
+
className="query-builder__result__execute-btn"
|
516
|
+
onClick={runQuery}
|
517
|
+
tabIndex={-1}
|
518
|
+
title={
|
519
|
+
queryValidationIssues
|
520
|
+
? `Query is not valid:\n${queryValidationIssues
|
521
|
+
.map((issue) => `\u2022 ${issue}`)
|
522
|
+
.join('\n')}`
|
523
|
+
: undefined
|
509
524
|
}
|
510
|
-
|
511
|
-
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
512
|
-
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
513
|
-
}}
|
525
|
+
disabled={!isQueryValid}
|
514
526
|
>
|
515
|
-
<
|
516
|
-
|
517
|
-
|
527
|
+
<div className="query-builder__result__execute-btn__label">
|
528
|
+
<PlayIcon className="query-builder__result__execute-btn__label__icon" />
|
529
|
+
<div className="query-builder__result__execute-btn__label__title">
|
530
|
+
Run Query
|
531
|
+
</div>
|
532
|
+
</div>
|
533
|
+
<DropdownMenu
|
534
|
+
className="query-builder__result__execute-btn__dropdown-btn"
|
535
|
+
disabled={resultState.isGeneratingPlan}
|
536
|
+
content={
|
537
|
+
<MenuContent>
|
538
|
+
<MenuContentItem
|
539
|
+
className="query-builder__result__execute-btn__option"
|
540
|
+
onClick={generatePlan}
|
541
|
+
>
|
542
|
+
Generate Plan
|
543
|
+
</MenuContentItem>
|
544
|
+
<MenuContentItem
|
545
|
+
className="query-builder__result__execute-btn__option"
|
546
|
+
onClick={debugPlanGeneration}
|
547
|
+
>
|
548
|
+
Debug
|
549
|
+
</MenuContentItem>
|
550
|
+
</MenuContent>
|
551
|
+
}
|
552
|
+
menuProps={{
|
553
|
+
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
554
|
+
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
555
|
+
}}
|
556
|
+
>
|
557
|
+
<CaretDownIcon />
|
558
|
+
</DropdownMenu>
|
559
|
+
</button>
|
560
|
+
)}
|
518
561
|
<DropdownMenu
|
519
562
|
className="query-builder__result__export__dropdown"
|
520
563
|
content={
|
@@ -542,19 +585,24 @@ export const QueryBuilderResultPanel = observer(
|
|
542
585
|
className="query-builder__result__export__dropdown__label"
|
543
586
|
tabIndex={-1}
|
544
587
|
title="Export"
|
588
|
+
disabled={!isQueryValid}
|
545
589
|
>
|
546
590
|
Export
|
547
591
|
</button>
|
548
|
-
<
|
592
|
+
<button
|
593
|
+
className="query-builder__result__export__dropdown__trigger"
|
594
|
+
tabIndex={-1}
|
595
|
+
disabled={!isQueryValid}
|
596
|
+
>
|
549
597
|
<CaretDownIcon />
|
550
|
-
</
|
598
|
+
</button>
|
551
599
|
</DropdownMenu>
|
552
600
|
</div>
|
553
601
|
</div>
|
554
602
|
<div className="panel__content">
|
555
603
|
<PanelLoadingIndicator
|
556
604
|
isLoading={
|
557
|
-
resultState.
|
605
|
+
resultState.isRunningQuery ||
|
558
606
|
resultState.isGeneratingPlan ||
|
559
607
|
resultState.exportDataState.isInProgress
|
560
608
|
}
|
@@ -21,7 +21,6 @@ import {
|
|
21
21
|
PURE_ClassIcon,
|
22
22
|
PURE_MappingIcon,
|
23
23
|
PURE_RuntimeIcon,
|
24
|
-
EyeIcon,
|
25
24
|
ClockIcon,
|
26
25
|
clsx,
|
27
26
|
} from '@finos/legend-art';
|
@@ -46,8 +45,9 @@ import {
|
|
46
45
|
} from '@finos/legend-graph';
|
47
46
|
import {
|
48
47
|
type PackageableElementOption,
|
49
|
-
|
48
|
+
getPackageableElementOptionFormatter,
|
50
49
|
buildElementOption,
|
50
|
+
useApplicationStore,
|
51
51
|
} from '@finos/legend-application';
|
52
52
|
import { MilestoningParametersEditor } from './QueryBuilderMilestoneEditor.js';
|
53
53
|
import { useState } from 'react';
|
@@ -124,8 +124,8 @@ const generateClassLabel = (
|
|
124
124
|
>
|
125
125
|
{val.name}
|
126
126
|
</div>
|
127
|
-
<
|
128
|
-
className="query-builder__setup__config__item__class-
|
127
|
+
<ClockIcon
|
128
|
+
className="query-builder__setup__config__item__class-label__milestoning"
|
129
129
|
title={milestoningParameterValues}
|
130
130
|
/>
|
131
131
|
</div>
|
@@ -151,6 +151,7 @@ const generateClassLabel = (
|
|
151
151
|
export const QueryBuilderSetupPanel = observer(
|
152
152
|
(props: { queryBuilderState: QueryBuilderState }) => {
|
153
153
|
const { queryBuilderState } = props;
|
154
|
+
const applicationStore = useApplicationStore();
|
154
155
|
const querySetupState = queryBuilderState.querySetupState;
|
155
156
|
const [isMilestoneEditorOpened, setIsMilestoneEditorOpened] =
|
156
157
|
useState<boolean>(false);
|
@@ -266,15 +267,15 @@ export const QueryBuilderSetupPanel = observer(
|
|
266
267
|
options={classOptions}
|
267
268
|
onChange={changeClass}
|
268
269
|
value={selectedClassOption}
|
269
|
-
darkMode={
|
270
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
270
271
|
disabled={!isQuerySupported || querySetupState.classIsReadOnly}
|
271
272
|
filterOption={elementFilterOption}
|
272
|
-
formatOptionLabel={
|
273
|
-
darkMode:
|
273
|
+
formatOptionLabel={getPackageableElementOptionFormatter({
|
274
|
+
darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
|
274
275
|
})}
|
275
276
|
/>
|
276
277
|
<button
|
277
|
-
className="btn--dark btn__icon--dark"
|
278
|
+
className="btn--dark btn__icon--dark query-builder__setup__milestoning"
|
278
279
|
tabIndex={-1}
|
279
280
|
onClick={(): void => setIsMilestoneEditorOpened(true)}
|
280
281
|
disabled={!isMilestonedQuery}
|
@@ -302,10 +303,10 @@ export const QueryBuilderSetupPanel = observer(
|
|
302
303
|
options={mappingOptions}
|
303
304
|
onChange={changeMapping}
|
304
305
|
value={selectedMappingOption}
|
305
|
-
darkMode={
|
306
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
306
307
|
filterOption={elementFilterOption}
|
307
|
-
formatOptionLabel={
|
308
|
-
darkMode:
|
308
|
+
formatOptionLabel={getPackageableElementOptionFormatter({
|
309
|
+
darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
|
309
310
|
})}
|
310
311
|
/>
|
311
312
|
</div>
|
@@ -330,7 +331,7 @@ export const QueryBuilderSetupPanel = observer(
|
|
330
331
|
options={runtimeOptions}
|
331
332
|
onChange={changeRuntime}
|
332
333
|
value={selectedRuntimeOption}
|
333
|
-
darkMode={
|
334
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
334
335
|
filterOption={runtimeFilterOption}
|
335
336
|
/>
|
336
337
|
</div>
|
@@ -48,7 +48,9 @@ const QueryBuilderUnsupportedQueryEditPanel = observer(
|
|
48
48
|
const { queryBuilderState } = props;
|
49
49
|
const queryUnsupportedState = queryBuilderState.queryUnsupportedState;
|
50
50
|
const lambdaError = queryUnsupportedState.lambdaError;
|
51
|
-
const errorMessage = lambdaError
|
51
|
+
const errorMessage = lambdaError?.message
|
52
|
+
? ` due to: ${lambdaError.message}`
|
53
|
+
: '';
|
52
54
|
const openLambdaModal = (): void =>
|
53
55
|
queryBuilderState.queryTextEditorState.openModal(
|
54
56
|
QueryTextEditorMode.TEXT,
|
@@ -63,7 +65,7 @@ const QueryBuilderUnsupportedQueryEditPanel = observer(
|
|
63
65
|
<div className="panel__content">
|
64
66
|
<BlankPanelContent>
|
65
67
|
<div className="query-builder__unsupported-view__main">
|
66
|
-
<div className="query-builder__unsupported-view__summary">{`Can't display query in form mode
|
68
|
+
<div className="query-builder__unsupported-view__summary">{`Can't display query in form mode${errorMessage}`}</div>
|
67
69
|
<button
|
68
70
|
className="btn--dark query-builder__unsupported-view__to-text-mode__btn"
|
69
71
|
onClick={openLambdaModal}
|
@@ -22,6 +22,9 @@ import {
|
|
22
22
|
RobotIcon,
|
23
23
|
SaveIcon,
|
24
24
|
BlankPanelContent,
|
25
|
+
clsx,
|
26
|
+
EmptyLightBulbIcon,
|
27
|
+
LightBulbIcon,
|
25
28
|
} from '@finos/legend-art';
|
26
29
|
import { getQueryParameters } from '@finos/legend-shared';
|
27
30
|
import { observer } from 'mobx-react-lite';
|
@@ -108,6 +111,8 @@ const QueryExportDialogContent = observer(
|
|
108
111
|
)}
|
109
112
|
<button
|
110
113
|
className="btn modal__footer__close-btn btn--dark"
|
114
|
+
// TODO?: we should probably annotate here why,
|
115
|
+
// when we disable this action
|
111
116
|
disabled={!allowCreate}
|
112
117
|
onClick={create}
|
113
118
|
>
|
@@ -199,6 +204,10 @@ const QueryEditorHeaderContent = observer(() => {
|
|
199
204
|
),
|
200
205
|
);
|
201
206
|
};
|
207
|
+
const toggleLightDarkTheme = (): void =>
|
208
|
+
applicationStore.TEMPORARY__setIsLightThemeEnabled(
|
209
|
+
!applicationStore.TEMPORARY__isLightThemeEnabled,
|
210
|
+
);
|
202
211
|
const saveQuery = (): void => {
|
203
212
|
editorStore.queryBuilderState
|
204
213
|
.saveQuery(async (lambda: RawLambda) => {
|
@@ -227,6 +236,20 @@ const QueryEditorHeaderContent = observer(() => {
|
|
227
236
|
>
|
228
237
|
<ExternalLinkSquareIcon />
|
229
238
|
</button>
|
239
|
+
{applicationStore.config.options.TEMPORARY__enableThemeSwitcher && (
|
240
|
+
<button
|
241
|
+
className="query-editor__header__action query-editor__header__action--simple btn--dark"
|
242
|
+
tabIndex={-1}
|
243
|
+
title="Toggle Light/Dark Theme"
|
244
|
+
onClick={toggleLightDarkTheme}
|
245
|
+
>
|
246
|
+
{applicationStore.TEMPORARY__isLightThemeEnabled ? (
|
247
|
+
<EmptyLightBulbIcon />
|
248
|
+
) : (
|
249
|
+
<LightBulbIcon />
|
250
|
+
)}
|
251
|
+
</button>
|
252
|
+
)}
|
230
253
|
<button
|
231
254
|
className="query-editor__header__action btn--dark"
|
232
255
|
tabIndex={-1}
|
@@ -256,9 +279,24 @@ export const QueryEditor = observer(() => {
|
|
256
279
|
);
|
257
280
|
}, [editorStore, applicationStore]);
|
258
281
|
|
282
|
+
useEffect(() => {
|
283
|
+
document.body.classList.toggle(
|
284
|
+
'light-theme',
|
285
|
+
applicationStore.TEMPORARY__isLightThemeEnabled,
|
286
|
+
);
|
287
|
+
}, [applicationStore.TEMPORARY__isLightThemeEnabled]);
|
288
|
+
|
259
289
|
return (
|
260
290
|
<DndProvider backend={HTML5Backend}>
|
261
|
-
<div
|
291
|
+
<div
|
292
|
+
className={clsx([
|
293
|
+
'query-editor ',
|
294
|
+
{
|
295
|
+
'query-editor--light':
|
296
|
+
applicationStore.TEMPORARY__isLightThemeEnabled,
|
297
|
+
},
|
298
|
+
])}
|
299
|
+
>
|
262
300
|
<div className="query-editor__header">
|
263
301
|
<button
|
264
302
|
className="query-editor__header__back-btn btn--dark"
|
@@ -50,6 +50,8 @@ import {
|
|
50
50
|
EntityMappedProperty,
|
51
51
|
Enumeration,
|
52
52
|
DerivedProperty,
|
53
|
+
Property,
|
54
|
+
Association,
|
53
55
|
} from '@finos/legend-graph';
|
54
56
|
import type { QueryBuilderState } from './QueryBuilderState.js';
|
55
57
|
import {
|
@@ -342,7 +344,7 @@ export const getQueryBuilderPropertyNodeData = (
|
|
342
344
|
property: AbstractProperty,
|
343
345
|
parentNode: QueryBuilderExplorerTreeNodeData,
|
344
346
|
modelCoverageAnalysisResult: MappingModelCoverageAnalysisResult,
|
345
|
-
): QueryBuilderExplorerTreePropertyNodeData => {
|
347
|
+
): QueryBuilderExplorerTreePropertyNodeData | undefined => {
|
346
348
|
const mappingNodeData = generatePropertyNodeMappingData(
|
347
349
|
property,
|
348
350
|
parentNode.mappingData,
|
@@ -353,6 +355,21 @@ export const getQueryBuilderPropertyNodeData = (
|
|
353
355
|
parentNode.isPartOfDerivedPropertyBranch ||
|
354
356
|
(parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
355
357
|
parentNode.property instanceof DerivedProperty);
|
358
|
+
// NOTE: in case of association, to avoid infinite exploration path
|
359
|
+
// we will prune it, on the other hand, in circular composition case
|
360
|
+
// A has property of type B and B has property of type A
|
361
|
+
// we will allow users to explore as deeply as they wish
|
362
|
+
// See https://github.com/finos/legend-studio/issues/1172
|
363
|
+
if (
|
364
|
+
property instanceof Property &&
|
365
|
+
parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
366
|
+
parentNode.property instanceof Property &&
|
367
|
+
property._OWNER instanceof Association &&
|
368
|
+
parentNode.property._OWNER instanceof Association &&
|
369
|
+
parentNode.property._OWNER === property._OWNER
|
370
|
+
) {
|
371
|
+
return undefined;
|
372
|
+
}
|
356
373
|
const propertyNode = new QueryBuilderExplorerTreePropertyNodeData(
|
357
374
|
`${
|
358
375
|
parentNode instanceof QueryBuilderExplorerTreeRootNodeData
|
@@ -455,8 +472,10 @@ const getQueryBuilderTreeData = (
|
|
455
472
|
treeRootNode,
|
456
473
|
modelCoverageAnalysisResult,
|
457
474
|
);
|
458
|
-
|
459
|
-
|
475
|
+
if (propertyTreeNodeData) {
|
476
|
+
addUniqueEntry(treeRootNode.childrenIds, propertyTreeNodeData.id);
|
477
|
+
nodes.set(propertyTreeNodeData.id, propertyTreeNodeData);
|
478
|
+
}
|
460
479
|
});
|
461
480
|
rootClass._subclasses.forEach((subclass) => {
|
462
481
|
const subTypeTreeNodeData = getQueryBuilderSubTypeNodeData(
|