@finos/legend-application-query 5.1.0 → 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 +7 -34
- package/lib/components/QueryBuilderExplorerPanel.js.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFetchStructurePanel.js +77 -66
- package/lib/components/QueryBuilderFetchStructurePanel.js.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderFilterPanel.js +28 -58
- 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 -34
- package/lib/components/QueryBuilderParameterPanel.js.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderPostFilterPanel.js +33 -58
- package/lib/components/QueryBuilderPostFilterPanel.js.map +1 -1
- package/lib/components/QueryBuilderProjectionPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderProjectionPanel.js +47 -67
- 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.d.ts.map +1 -1
- package/lib/components/QueryBuilderPropertySearchPanel.js +3 -6
- 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 +28 -20
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/QueryBuilderSetupPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderSetupPanel.js +10 -11
- 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.map +1 -1
- package/lib/stores/QueryBuilderExplorerState.js +5 -0
- package/lib/stores/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/QueryBuilderFetchStructureState.d.ts +6 -0
- package/lib/stores/QueryBuilderFetchStructureState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderFetchStructureState.js +8 -0
- package/lib/stores/QueryBuilderFetchStructureState.js.map +1 -1
- package/lib/stores/QueryBuilderFilterState.d.ts +4 -9
- package/lib/stores/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderFilterState.js +6 -11
- 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/QueryBuilderPostFilterState.d.ts +4 -4
- package/lib/stores/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderPostFilterState.js +6 -6
- package/lib/stores/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.d.ts +2 -7
- package/lib/stores/QueryBuilderProjectionState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderProjectionState.js +5 -17
- package/lib/stores/QueryBuilderProjectionState.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 +6 -1
- package/lib/stores/QueryBuilderState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderState.js +9 -2
- package/lib/stores/QueryBuilderState.js.map +1 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +17 -56
- package/src/components/QueryBuilderFetchStructurePanel.tsx +93 -80
- package/src/components/QueryBuilderFilterPanel.tsx +184 -225
- package/src/components/QueryBuilderFunctionsExplorerPanel.tsx +23 -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 +21 -54
- package/src/components/QueryBuilderPostFilterPanel.tsx +202 -236
- package/src/components/QueryBuilderProjectionPanel.tsx +126 -170
- package/src/components/QueryBuilderPropertyExpressionEditor.tsx +61 -57
- package/src/components/QueryBuilderPropertySearchPanel.tsx +8 -9
- package/src/components/QueryBuilderResultModifierPanel.tsx +4 -2
- package/src/components/QueryBuilderResultPanel.tsx +71 -52
- package/src/components/QueryBuilderSetupPanel.tsx +10 -11
- package/src/components/QueryBuilderUnsupportedQueryEditor.tsx +4 -2
- package/src/components/QueryEditor.tsx +39 -1
- package/src/stores/QueryBuilderExplorerState.ts +5 -0
- package/src/stores/QueryBuilderFetchStructureState.ts +9 -0
- package/src/stores/QueryBuilderFilterState.ts +7 -12
- package/src/stores/QueryBuilderGraphFetchTreeState.ts +14 -8
- package/src/stores/QueryBuilderLambdaProcessor.ts +8 -0
- package/src/stores/QueryBuilderPostFilterState.ts +7 -7
- package/src/stores/QueryBuilderProjectionState.ts +7 -18
- package/src/stores/QueryBuilderSetupState.ts +1 -1
- package/src/stores/QueryBuilderState.ts +10 -2
- 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 +8 -1
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts +8 -1
- package/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts +8 -1
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts +8 -1
- package/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts +8 -1
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts +8 -1
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts +8 -1
- package/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts +8 -1
- package/tsconfig.json +1 -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 ||
|
@@ -186,10 +189,6 @@ const QueryBuilderTreeNodeViewer = observer(
|
|
186
189
|
node.parentId === pn.id,
|
187
190
|
);
|
188
191
|
|
189
|
-
useEffect(() => {
|
190
|
-
dragPreviewConnector(getEmptyImage(), { captureDraggingState: true });
|
191
|
-
}, [dragPreviewConnector]);
|
192
|
-
|
193
192
|
return (
|
194
193
|
<div>
|
195
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'}
|
@@ -288,6 +288,61 @@ const QueryBuilderResultContextMenu = observer(
|
|
288
288
|
}),
|
289
289
|
);
|
290
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
|
+
|
291
346
|
const QueryBuilderResultValues = observer(
|
292
347
|
(props: {
|
293
348
|
executionResult: ExecutionResult;
|
@@ -295,52 +350,11 @@ const QueryBuilderResultValues = observer(
|
|
295
350
|
}) => {
|
296
351
|
const { executionResult, queryBuilderState } = props;
|
297
352
|
if (executionResult instanceof TdsExecutionResult) {
|
298
|
-
const [cellDoubleClickedEvent, setCellDoubleClickedEvent] =
|
299
|
-
useState<CellMouseOverEvent | null>(null);
|
300
|
-
const columns = executionResult.result.columns;
|
301
|
-
const rowData = executionResult.result.rows.map((_row) => {
|
302
|
-
const row: Record<PropertyKey, unknown> = {};
|
303
|
-
const cols = executionResult.result.columns;
|
304
|
-
_row.values.forEach((value, idx) => {
|
305
|
-
// `ag-grid` shows `false` value as empty string so we have
|
306
|
-
// call `.toString()` to avoid this behavior.
|
307
|
-
// See https://github.com/finos/legend-studio/issues/1008
|
308
|
-
row[cols[idx] as string] = isBoolean(value) ? String(value) : value;
|
309
|
-
});
|
310
|
-
return row;
|
311
|
-
});
|
312
353
|
return (
|
313
|
-
<
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
queryBuilderState={queryBuilderState}
|
318
|
-
/>
|
319
|
-
}
|
320
|
-
menuProps={{ elevation: 7 }}
|
321
|
-
key={executionResult._UUID}
|
322
|
-
className={clsx(
|
323
|
-
'ag-theme-balham-dark query-builder__result__tds-grid',
|
324
|
-
)}
|
325
|
-
>
|
326
|
-
<AgGridReact
|
327
|
-
rowData={rowData}
|
328
|
-
onCellMouseOver={(event): void => {
|
329
|
-
setCellDoubleClickedEvent(event);
|
330
|
-
}}
|
331
|
-
>
|
332
|
-
{columns.map((colName) => (
|
333
|
-
<AgGridColumn
|
334
|
-
minWidth={50}
|
335
|
-
sortable={true}
|
336
|
-
resizable={true}
|
337
|
-
field={colName}
|
338
|
-
key={colName}
|
339
|
-
flex={1}
|
340
|
-
/>
|
341
|
-
))}
|
342
|
-
</AgGridReact>
|
343
|
-
</ContextMenu>
|
354
|
+
<QueryBuilderGridResult
|
355
|
+
queryBuilderState={queryBuilderState}
|
356
|
+
executionResult={executionResult}
|
357
|
+
/>
|
344
358
|
);
|
345
359
|
} else if (executionResult instanceof RawExecutionResult) {
|
346
360
|
return (
|
@@ -414,6 +428,9 @@ export const QueryBuilderResultPanel = observer(
|
|
414
428
|
],
|
415
429
|
});
|
416
430
|
};
|
431
|
+
const queryValidationIssues = queryBuilderState.validationIssues;
|
432
|
+
const isQueryValid =
|
433
|
+
!queryBuilderState.isQuerySupported() || !queryValidationIssues;
|
417
434
|
const runQuery = (): void => {
|
418
435
|
if (queryParametersState.parameterStates.length) {
|
419
436
|
queryParametersState.parameterValuesEditorState.open(
|
@@ -475,7 +492,7 @@ export const QueryBuilderResultPanel = observer(
|
|
475
492
|
type="number"
|
476
493
|
value={resultState.previewLimit}
|
477
494
|
onChange={changeLimit}
|
478
|
-
disabled={!
|
495
|
+
disabled={!isQueryValid}
|
479
496
|
/>
|
480
497
|
</div>
|
481
498
|
)}
|
@@ -484,7 +501,7 @@ export const QueryBuilderResultPanel = observer(
|
|
484
501
|
className="query-builder__result__stop-btn"
|
485
502
|
onClick={cancelQuery}
|
486
503
|
tabIndex={-1}
|
487
|
-
disabled={!
|
504
|
+
disabled={!isQueryValid}
|
488
505
|
>
|
489
506
|
<div className="btn--dark btn--caution query-builder__result__stop-btn__label">
|
490
507
|
<PauseCircleIcon className="query-builder__result__stop-btn__label__icon" />
|
@@ -499,11 +516,13 @@ export const QueryBuilderResultPanel = observer(
|
|
499
516
|
onClick={runQuery}
|
500
517
|
tabIndex={-1}
|
501
518
|
title={
|
502
|
-
|
503
|
-
?
|
519
|
+
queryValidationIssues
|
520
|
+
? `Query is not valid:\n${queryValidationIssues
|
521
|
+
.map((issue) => `\u2022 ${issue}`)
|
522
|
+
.join('\n')}`
|
504
523
|
: undefined
|
505
524
|
}
|
506
|
-
disabled={!
|
525
|
+
disabled={!isQueryValid}
|
507
526
|
>
|
508
527
|
<div className="query-builder__result__execute-btn__label">
|
509
528
|
<PlayIcon className="query-builder__result__execute-btn__label__icon" />
|
@@ -566,14 +585,14 @@ export const QueryBuilderResultPanel = observer(
|
|
566
585
|
className="query-builder__result__export__dropdown__label"
|
567
586
|
tabIndex={-1}
|
568
587
|
title="Export"
|
569
|
-
disabled={!
|
588
|
+
disabled={!isQueryValid}
|
570
589
|
>
|
571
590
|
Export
|
572
591
|
</button>
|
573
592
|
<button
|
574
593
|
className="query-builder__result__export__dropdown__trigger"
|
575
594
|
tabIndex={-1}
|
576
|
-
disabled={!
|
595
|
+
disabled={!isQueryValid}
|
577
596
|
>
|
578
597
|
<CaretDownIcon />
|
579
598
|
</button>
|
@@ -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';
|
@@ -48,6 +47,7 @@ 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,16 +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
273
|
formatOptionLabel={getPackageableElementOptionFormatter({
|
273
|
-
darkMode:
|
274
|
-
graphManagerState: queryBuilderState.graphManagerState,
|
274
|
+
darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
|
275
275
|
})}
|
276
276
|
/>
|
277
277
|
<button
|
278
|
-
className="btn--dark btn__icon--dark"
|
278
|
+
className="btn--dark btn__icon--dark query-builder__setup__milestoning"
|
279
279
|
tabIndex={-1}
|
280
280
|
onClick={(): void => setIsMilestoneEditorOpened(true)}
|
281
281
|
disabled={!isMilestonedQuery}
|
@@ -303,11 +303,10 @@ export const QueryBuilderSetupPanel = observer(
|
|
303
303
|
options={mappingOptions}
|
304
304
|
onChange={changeMapping}
|
305
305
|
value={selectedMappingOption}
|
306
|
-
darkMode={
|
306
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
307
307
|
filterOption={elementFilterOption}
|
308
308
|
formatOptionLabel={getPackageableElementOptionFormatter({
|
309
|
-
darkMode:
|
310
|
-
graphManagerState: queryBuilderState.graphManagerState,
|
309
|
+
darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
|
311
310
|
})}
|
312
311
|
/>
|
313
312
|
</div>
|
@@ -332,7 +331,7 @@ export const QueryBuilderSetupPanel = observer(
|
|
332
331
|
options={runtimeOptions}
|
333
332
|
onChange={changeRuntime}
|
334
333
|
value={selectedRuntimeOption}
|
335
|
-
darkMode={
|
334
|
+
darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
|
336
335
|
filterOption={runtimeFilterOption}
|
337
336
|
/>
|
338
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"
|
@@ -355,6 +355,11 @@ export const getQueryBuilderPropertyNodeData = (
|
|
355
355
|
parentNode.isPartOfDerivedPropertyBranch ||
|
356
356
|
(parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
357
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
|
358
363
|
if (
|
359
364
|
property instanceof Property &&
|
360
365
|
parentNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
@@ -27,6 +27,11 @@ export enum FETCH_STRUCTURE_MODE {
|
|
27
27
|
|
28
28
|
export class QueryBuilderFetchStructureState {
|
29
29
|
queryBuilderState: QueryBuilderState;
|
30
|
+
/**
|
31
|
+
* TODO?: perhaps it would eventually make sense to default to
|
32
|
+
* graph-fetch since `getAll()` naturally works for graph-fetch case
|
33
|
+
* and graph-fetch allows somewhat an empty tree
|
34
|
+
*/
|
30
35
|
fetchStructureMode = FETCH_STRUCTURE_MODE.PROJECTION;
|
31
36
|
projectionState: QueryBuilderProjectionState;
|
32
37
|
graphFetchTreeState: QueryBuilderGraphFetchTreeState;
|
@@ -63,4 +68,8 @@ export class QueryBuilderFetchStructureState {
|
|
63
68
|
isProjectionMode(): boolean {
|
64
69
|
return this.fetchStructureMode === FETCH_STRUCTURE_MODE.PROJECTION;
|
65
70
|
}
|
71
|
+
|
72
|
+
get validationIssues(): string[] | undefined {
|
73
|
+
return this.projectionState.validationIssues;
|
74
|
+
}
|
66
75
|
}
|
@@ -264,7 +264,7 @@ export abstract class QueryBuilderFilterTreeNodeData implements TreeNodeData {
|
|
264
264
|
});
|
265
265
|
}
|
266
266
|
|
267
|
-
abstract get
|
267
|
+
abstract get dragPreviewLabel(): string;
|
268
268
|
setIsOpen(val: boolean): void {
|
269
269
|
this.isOpen = val;
|
270
270
|
}
|
@@ -289,14 +289,14 @@ export class QueryBuilderFilterTreeGroupNodeData extends QueryBuilderFilterTreeN
|
|
289
289
|
setGroupOperation: action,
|
290
290
|
addChildNode: action,
|
291
291
|
removeChildNode: action,
|
292
|
-
|
292
|
+
dragPreviewLabel: computed,
|
293
293
|
});
|
294
294
|
|
295
295
|
this.groupOperation = groupOperation;
|
296
296
|
this.isOpen = true;
|
297
297
|
}
|
298
298
|
|
299
|
-
get
|
299
|
+
get dragPreviewLabel(): string {
|
300
300
|
return `${this.groupOperation.toUpperCase()} group`;
|
301
301
|
}
|
302
302
|
|
@@ -328,13 +328,13 @@ export class QueryBuilderFilterTreeConditionNodeData extends QueryBuilderFilterT
|
|
328
328
|
|
329
329
|
makeObservable(this, {
|
330
330
|
condition: observable,
|
331
|
-
|
331
|
+
dragPreviewLabel: computed,
|
332
332
|
});
|
333
333
|
|
334
334
|
this.condition = condition;
|
335
335
|
}
|
336
336
|
|
337
|
-
get
|
337
|
+
get dragPreviewLabel(): string {
|
338
338
|
return this.condition.propertyExpressionState.title;
|
339
339
|
}
|
340
340
|
}
|
@@ -344,11 +344,11 @@ export class QueryBuilderFilterTreeBlankConditionNodeData extends QueryBuilderFi
|
|
344
344
|
super(parentId);
|
345
345
|
|
346
346
|
makeObservable(this, {
|
347
|
-
|
347
|
+
dragPreviewLabel: computed,
|
348
348
|
});
|
349
349
|
}
|
350
350
|
|
351
|
-
get
|
351
|
+
get dragPreviewLabel(): string {
|
352
352
|
return '<blank>';
|
353
353
|
}
|
354
354
|
}
|
@@ -452,11 +452,6 @@ export class QueryBuilderFilterState
|
|
452
452
|
isRearrangingConditions = false;
|
453
453
|
operators: QueryBuilderFilterOperator[] = [];
|
454
454
|
private _suppressClickawayEventListener = false;
|
455
|
-
/**
|
456
|
-
* This flag is for turning on/off dnd from projection panel to filter panel,
|
457
|
-
* and will be leveraged when the concepts of workflows are introduced into query builder.
|
458
|
-
*/
|
459
|
-
allowDnDProjectionToFilter = true;
|
460
455
|
|
461
456
|
constructor(
|
462
457
|
queryBuilderState: QueryBuilderState,
|
@@ -26,6 +26,7 @@ import {
|
|
26
26
|
buildGraphFetchTreeData,
|
27
27
|
} from './QueryBuilderGraphFetchTreeUtil.js';
|
28
28
|
import type { QueryBuilderExplorerTreePropertyNodeData } from './QueryBuilderExplorerState.js';
|
29
|
+
import { assertNonNullable } from '@finos/legend-shared';
|
29
30
|
|
30
31
|
export class QueryBuilderGraphFetchTreeState {
|
31
32
|
queryBuilderState: QueryBuilderState;
|
@@ -77,14 +78,19 @@ export class QueryBuilderGraphFetchTreeState {
|
|
77
78
|
}
|
78
79
|
|
79
80
|
addProperty(node: QueryBuilderExplorerTreePropertyNodeData): void {
|
80
|
-
if (this.treeData) {
|
81
|
-
|
82
|
-
this.treeData,
|
83
|
-
this.queryBuilderState.explorerState.nonNullableTreeData,
|
84
|
-
node,
|
85
|
-
this.queryBuilderState,
|
86
|
-
);
|
87
|
-
this.setGraphFetchTree({ ...this.treeData });
|
81
|
+
if (!this.treeData) {
|
82
|
+
this.initialize();
|
88
83
|
}
|
84
|
+
assertNonNullable(
|
85
|
+
this.treeData,
|
86
|
+
`Graph-fetch tree has not been properly initialized`,
|
87
|
+
);
|
88
|
+
addQueryBuilderPropertyNode(
|
89
|
+
this.treeData,
|
90
|
+
this.queryBuilderState.explorerState.nonNullableTreeData,
|
91
|
+
node,
|
92
|
+
this.queryBuilderState,
|
93
|
+
);
|
94
|
+
this.setGraphFetchTree({ ...this.treeData });
|
89
95
|
}
|
90
96
|
}
|
@@ -693,6 +693,10 @@ export class QueryBuilderLambdaProcessor
|
|
693
693
|
(e, idx) => e.setColumnName(aliases[idx] as string),
|
694
694
|
);
|
695
695
|
|
696
|
+
this.queryBuilderState.fetchStructureState.setFetchStructureMode(
|
697
|
+
FETCH_STRUCTURE_MODE.PROJECTION,
|
698
|
+
);
|
699
|
+
|
696
700
|
return;
|
697
701
|
} else if (
|
698
702
|
matchFunctionName(
|
@@ -943,6 +947,10 @@ export class QueryBuilderLambdaProcessor
|
|
943
947
|
(e, idx) => e.setColumnName(aliases[idx] as string),
|
944
948
|
);
|
945
949
|
|
950
|
+
this.queryBuilderState.fetchStructureState.setFetchStructureMode(
|
951
|
+
FETCH_STRUCTURE_MODE.PROJECTION,
|
952
|
+
);
|
953
|
+
|
946
954
|
return;
|
947
955
|
} else if (
|
948
956
|
matchFunctionName(functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_AGG)
|
@@ -165,7 +165,7 @@ export abstract class QueryBuilderPostFilterTreeNodeData
|
|
165
165
|
});
|
166
166
|
}
|
167
167
|
|
168
|
-
abstract get
|
168
|
+
abstract get dragPreviewLabel(): string;
|
169
169
|
setIsOpen(val: boolean): void {
|
170
170
|
this.isOpen = val;
|
171
171
|
}
|
@@ -197,13 +197,13 @@ export class QueryBuilderPostFilterTreeGroupNodeData extends QueryBuilderPostFil
|
|
197
197
|
setGroupOperation: action,
|
198
198
|
addChildNode: action,
|
199
199
|
removeChildNode: action,
|
200
|
-
|
200
|
+
dragPreviewLabel: computed,
|
201
201
|
});
|
202
202
|
this.groupOperation = groupOperation;
|
203
203
|
this.isOpen = true;
|
204
204
|
}
|
205
205
|
|
206
|
-
get
|
206
|
+
get dragPreviewLabel(): string {
|
207
207
|
return `${this.groupOperation.toUpperCase()} group`;
|
208
208
|
}
|
209
209
|
|
@@ -238,13 +238,13 @@ export class QueryBuilderPostFilterTreeConditionNodeData extends QueryBuilderPos
|
|
238
238
|
|
239
239
|
makeObservable(this, {
|
240
240
|
condition: observable,
|
241
|
-
|
241
|
+
dragPreviewLabel: computed,
|
242
242
|
});
|
243
243
|
|
244
244
|
this.condition = condition;
|
245
245
|
}
|
246
246
|
|
247
|
-
get
|
247
|
+
get dragPreviewLabel(): string {
|
248
248
|
return this.condition.columnName;
|
249
249
|
}
|
250
250
|
}
|
@@ -254,11 +254,11 @@ export class QueryBuilderPostFilterTreeBlankConditionNodeData extends QueryBuild
|
|
254
254
|
super(parentId);
|
255
255
|
|
256
256
|
makeObservable(this, {
|
257
|
-
|
257
|
+
dragPreviewLabel: computed,
|
258
258
|
});
|
259
259
|
}
|
260
260
|
|
261
|
-
get
|
261
|
+
get dragPreviewLabel(): string {
|
262
262
|
return '<blank>';
|
263
263
|
}
|
264
264
|
}
|