@finos/legend-application-query 13.4.0 → 13.4.2
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/__lib__/DSL_DataSpace_LegendQueryDocumentation.d.ts +19 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryDocumentation.d.ts.map +1 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryDocumentation.js +20 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryDocumentation.js.map +1 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryNavigation.d.ts +53 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryNavigation.d.ts.map +1 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryNavigation.js +59 -0
- package/lib/__lib__/DSL_DataSpace_LegendQueryNavigation.js.map +1 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.js +14 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
- package/lib/components/LegendQueryWebApplication.d.ts.map +1 -1
- package/lib/components/LegendQueryWebApplication.js +18 -10
- package/lib/components/LegendQueryWebApplication.js.map +1 -1
- package/lib/components/QueryEditor.d.ts.map +1 -1
- package/lib/components/QueryEditor.js +47 -18
- package/lib/components/QueryEditor.js.map +1 -1
- package/lib/components/data-space/DataSpaceQueryCreator.d.ts +19 -0
- package/lib/components/data-space/DataSpaceQueryCreator.d.ts.map +1 -0
- package/lib/components/data-space/DataSpaceQueryCreator.js +43 -0
- package/lib/components/data-space/DataSpaceQueryCreator.js.map +1 -0
- package/lib/components/data-space/DataSpaceQuerySetup.d.ts +21 -0
- package/lib/components/data-space/DataSpaceQuerySetup.d.ts.map +1 -0
- package/lib/components/data-space/DataSpaceQuerySetup.js +64 -0
- package/lib/components/data-space/DataSpaceQuerySetup.js.map +1 -0
- package/lib/components/data-space/DataSpaceTemplateQueryCreator.d.ts +19 -0
- package/lib/components/data-space/DataSpaceTemplateQueryCreator.d.ts.map +1 -0
- package/lib/components/data-space/DataSpaceTemplateQueryCreator.js +39 -0
- package/lib/components/data-space/DataSpaceTemplateQueryCreator.js.map +1 -0
- package/lib/components/data-space/QueryDataSpaceUtil.d.ts +19 -0
- package/lib/components/data-space/QueryDataSpaceUtil.d.ts.map +1 -0
- package/lib/components/data-space/QueryDataSpaceUtil.js +25 -0
- package/lib/components/data-space/QueryDataSpaceUtil.js.map +1 -0
- package/lib/index.css +1 -1
- package/lib/package.json +2 -1
- package/lib/stores/LegendQueryApplicationPlugin.d.ts +0 -16
- package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
- package/lib/stores/QueryEditorStore.d.ts +2 -0
- package/lib/stores/QueryEditorStore.d.ts.map +1 -1
- package/lib/stores/QueryEditorStore.js +96 -11
- package/lib/stores/QueryEditorStore.js.map +1 -1
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts +37 -0
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +1 -0
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +132 -0
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +1 -0
- package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts +51 -0
- package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts.map +1 -0
- package/lib/stores/data-space/DataSpaceQuerySetupState.js +107 -0
- package/lib/stores/data-space/DataSpaceQuerySetupState.js.map +1 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts +36 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +104 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -0
- package/package.json +5 -4
- package/src/__lib__/DSL_DataSpace_LegendQueryDocumentation.ts +19 -0
- package/src/__lib__/DSL_DataSpace_LegendQueryNavigation.ts +123 -0
- package/src/components/Core_LegendQueryApplicationPlugin.tsx +18 -0
- package/src/components/LegendQueryWebApplication.tsx +48 -12
- package/src/components/QueryEditor.tsx +112 -24
- package/src/components/data-space/DataSpaceQueryCreator.tsx +99 -0
- package/src/components/data-space/DataSpaceQuerySetup.tsx +165 -0
- package/src/components/data-space/DataSpaceTemplateQueryCreator.tsx +82 -0
- package/src/components/data-space/QueryDataSpaceUtil.ts +34 -0
- package/src/stores/LegendQueryApplicationPlugin.ts +0 -22
- package/src/stores/QueryEditorStore.ts +187 -12
- package/src/stores/data-space/DataSpaceQueryCreatorStore.ts +286 -0
- package/src/stores/data-space/DataSpaceQuerySetupState.ts +208 -0
- package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +204 -0
- package/tsconfig.json +10 -1
@@ -0,0 +1,99 @@
|
|
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 { observer, useLocalObservable } from 'mobx-react-lite';
|
18
|
+
import { useApplicationStore } from '@finos/legend-application';
|
19
|
+
import { useParams } from '@finos/legend-application/browser';
|
20
|
+
import { parseGAVCoordinates } from '@finos/legend-storage';
|
21
|
+
import {
|
22
|
+
useLegendQueryApplicationStore,
|
23
|
+
useLegendQueryBaseStore,
|
24
|
+
} from '../LegendQueryFrameworkProvider.js';
|
25
|
+
import { DataSpaceQueryCreatorStore } from '../../stores/data-space/DataSpaceQueryCreatorStore.js';
|
26
|
+
import { QueryEditorStoreContext } from '../QueryEditorStoreProvider.js';
|
27
|
+
import {
|
28
|
+
DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN,
|
29
|
+
DATA_SPACE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN,
|
30
|
+
type DataSpaceQueryCreatorPathParams,
|
31
|
+
} from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
|
32
|
+
import { QueryEditor } from '../QueryEditor.js';
|
33
|
+
|
34
|
+
const DataSpaceQueryCreatorStoreProvider: React.FC<{
|
35
|
+
children: React.ReactNode;
|
36
|
+
gav: string;
|
37
|
+
dataSpacePath: string;
|
38
|
+
executionContext: string;
|
39
|
+
runtimePath: string | undefined;
|
40
|
+
classPath: string | undefined;
|
41
|
+
}> = ({
|
42
|
+
children,
|
43
|
+
gav,
|
44
|
+
dataSpacePath,
|
45
|
+
executionContext,
|
46
|
+
runtimePath,
|
47
|
+
classPath,
|
48
|
+
}) => {
|
49
|
+
const { groupId, artifactId, versionId } = parseGAVCoordinates(gav);
|
50
|
+
const applicationStore = useLegendQueryApplicationStore();
|
51
|
+
const baseStore = useLegendQueryBaseStore();
|
52
|
+
const store = useLocalObservable(
|
53
|
+
() =>
|
54
|
+
new DataSpaceQueryCreatorStore(
|
55
|
+
applicationStore,
|
56
|
+
baseStore.depotServerClient,
|
57
|
+
groupId,
|
58
|
+
artifactId,
|
59
|
+
versionId,
|
60
|
+
dataSpacePath,
|
61
|
+
executionContext,
|
62
|
+
runtimePath,
|
63
|
+
classPath,
|
64
|
+
),
|
65
|
+
);
|
66
|
+
return (
|
67
|
+
<QueryEditorStoreContext.Provider value={store}>
|
68
|
+
{children}
|
69
|
+
</QueryEditorStoreContext.Provider>
|
70
|
+
);
|
71
|
+
};
|
72
|
+
|
73
|
+
export const DataSpaceQueryCreator = observer(() => {
|
74
|
+
const applicationStore = useApplicationStore();
|
75
|
+
const parameters = useParams<DataSpaceQueryCreatorPathParams>();
|
76
|
+
const gav = parameters[DATA_SPACE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.GAV];
|
77
|
+
const dataSpacePath =
|
78
|
+
parameters[DATA_SPACE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.DATA_SPACE_PATH];
|
79
|
+
const executionContext =
|
80
|
+
parameters[DATA_SPACE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.EXECUTION_CONTEXT];
|
81
|
+
const runtimePath =
|
82
|
+
parameters[DATA_SPACE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.RUNTIME_PATH];
|
83
|
+
const classPath =
|
84
|
+
applicationStore.navigationService.navigator.getCurrentLocationParameterValue(
|
85
|
+
DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN.CLASS_PATH,
|
86
|
+
);
|
87
|
+
|
88
|
+
return (
|
89
|
+
<DataSpaceQueryCreatorStoreProvider
|
90
|
+
gav={gav}
|
91
|
+
dataSpacePath={dataSpacePath}
|
92
|
+
executionContext={executionContext}
|
93
|
+
runtimePath={runtimePath}
|
94
|
+
classPath={classPath}
|
95
|
+
>
|
96
|
+
<QueryEditor />
|
97
|
+
</DataSpaceQueryCreatorStoreProvider>
|
98
|
+
);
|
99
|
+
});
|
@@ -0,0 +1,165 @@
|
|
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 { observer, useLocalObservable } from 'mobx-react-lite';
|
18
|
+
import { useApplicationStore } from '@finos/legend-application';
|
19
|
+
import { useEffect, useRef } from 'react';
|
20
|
+
import { flowResult } from 'mobx';
|
21
|
+
import { QueryBuilderClassSelector } from '@finos/legend-query-builder';
|
22
|
+
import {
|
23
|
+
CustomSelectorInput,
|
24
|
+
SearchIcon,
|
25
|
+
type SelectComponent,
|
26
|
+
} from '@finos/legend-art';
|
27
|
+
import { DataSpaceIcon } from '@finos/legend-extension-dsl-data-space/application';
|
28
|
+
import {
|
29
|
+
useLegendQueryApplicationStore,
|
30
|
+
useLegendQueryBaseStore,
|
31
|
+
} from '../LegendQueryFrameworkProvider.js';
|
32
|
+
import {
|
33
|
+
type DataSpaceQuerySetupState,
|
34
|
+
DataSpaceQuerySetupStore,
|
35
|
+
} from '../../stores/data-space/DataSpaceQuerySetupState.js';
|
36
|
+
import { QueryEditorStoreContext } from '../QueryEditorStoreProvider.js';
|
37
|
+
import { QueryEditor } from '../QueryEditor.js';
|
38
|
+
import {
|
39
|
+
DataSpaceAdvancedSearchModal,
|
40
|
+
buildDataSpaceOption,
|
41
|
+
formatDataSpaceOptionLabel,
|
42
|
+
type DataSpaceOption,
|
43
|
+
} from '@finos/legend-extension-dsl-data-space/application-query';
|
44
|
+
|
45
|
+
const DataSpaceQuerySetupStoreProvider: React.FC<{
|
46
|
+
children: React.ReactNode;
|
47
|
+
}> = ({ children }) => {
|
48
|
+
const applicationStore = useLegendQueryApplicationStore();
|
49
|
+
const baseStore = useLegendQueryBaseStore();
|
50
|
+
const store = useLocalObservable(
|
51
|
+
() =>
|
52
|
+
new DataSpaceQuerySetupStore(
|
53
|
+
applicationStore,
|
54
|
+
baseStore.depotServerClient,
|
55
|
+
),
|
56
|
+
);
|
57
|
+
return (
|
58
|
+
<QueryEditorStoreContext.Provider value={store}>
|
59
|
+
{children}
|
60
|
+
</QueryEditorStoreContext.Provider>
|
61
|
+
);
|
62
|
+
};
|
63
|
+
|
64
|
+
export const DataSpaceQuerySetup = observer(() => (
|
65
|
+
<DataSpaceQuerySetupStoreProvider>
|
66
|
+
<QueryEditor />
|
67
|
+
</DataSpaceQuerySetupStoreProvider>
|
68
|
+
));
|
69
|
+
|
70
|
+
/**
|
71
|
+
* This setup panel supports cascading in order: Data-space -> Execution context (-> Runtime) -> Class
|
72
|
+
*
|
73
|
+
* In other words, we will only show:
|
74
|
+
* - For runtime selector: the list of compatible runtimes with the selected execution context mapping
|
75
|
+
* - For class selector: the list of compatible class with the selected execution context mapping
|
76
|
+
*
|
77
|
+
* See details on propagation/cascading in {@link DataSpaceQuerySetupState}
|
78
|
+
*/
|
79
|
+
const DataSpaceQuerySetupSetupPanelContent = observer(
|
80
|
+
(props: { queryBuilderState: DataSpaceQuerySetupState }) => {
|
81
|
+
const { queryBuilderState } = props;
|
82
|
+
const applicationStore = useApplicationStore();
|
83
|
+
const dataSpaceSearchRef = useRef<SelectComponent>(null);
|
84
|
+
// data space
|
85
|
+
const dataSpaceOptions =
|
86
|
+
queryBuilderState.dataSpaces.map(buildDataSpaceOption);
|
87
|
+
const selectedDataSpaceOption = null;
|
88
|
+
const onDataSpaceOptionChange = (option: DataSpaceOption): void => {
|
89
|
+
queryBuilderState.onDataSpaceChange(option.value);
|
90
|
+
};
|
91
|
+
|
92
|
+
const openDataSpaceAdvancedSearch = (): void =>
|
93
|
+
queryBuilderState.showAdvancedSearchPanel();
|
94
|
+
|
95
|
+
useEffect(() => {
|
96
|
+
flowResult(queryBuilderState.loadDataSpaces()).catch(
|
97
|
+
applicationStore.alertUnhandledError,
|
98
|
+
);
|
99
|
+
}, [queryBuilderState, applicationStore]);
|
100
|
+
|
101
|
+
useEffect(() => dataSpaceSearchRef.current?.focus());
|
102
|
+
|
103
|
+
return (
|
104
|
+
<>
|
105
|
+
<div className="query-builder__setup__config-group">
|
106
|
+
<div className="query-builder__setup__config-group__header">
|
107
|
+
<div className="query-builder__setup__config-group__header__title">
|
108
|
+
data space execution context
|
109
|
+
</div>
|
110
|
+
</div>
|
111
|
+
<div className="query-builder__setup__config-group__content">
|
112
|
+
<div className="query-builder__setup__config-group__item">
|
113
|
+
<div
|
114
|
+
className="btn--sm query-builder__setup__config-group__item__label"
|
115
|
+
title="data space"
|
116
|
+
>
|
117
|
+
<DataSpaceIcon />
|
118
|
+
</div>
|
119
|
+
<CustomSelectorInput
|
120
|
+
ref={dataSpaceSearchRef}
|
121
|
+
className="panel__content__form__section__dropdown query-builder__setup__config-group__item__selector"
|
122
|
+
options={dataSpaceOptions}
|
123
|
+
isLoading={queryBuilderState.loadDataSpacesState.isInProgress}
|
124
|
+
onChange={onDataSpaceOptionChange}
|
125
|
+
value={selectedDataSpaceOption}
|
126
|
+
placeholder="Search for data space..."
|
127
|
+
escapeClearsValue={true}
|
128
|
+
darkMode={
|
129
|
+
!applicationStore.layoutService
|
130
|
+
.TEMPORARY__isLightColorThemeEnabled
|
131
|
+
}
|
132
|
+
formatOptionLabel={formatDataSpaceOptionLabel}
|
133
|
+
/>
|
134
|
+
<button
|
135
|
+
tabIndex={-1}
|
136
|
+
className="query-builder__setup__data-space-searcher__btn btn--dark"
|
137
|
+
onClick={openDataSpaceAdvancedSearch}
|
138
|
+
title="Open advanced search for data space..."
|
139
|
+
>
|
140
|
+
<SearchIcon />
|
141
|
+
</button>
|
142
|
+
{queryBuilderState.advancedSearchState && (
|
143
|
+
<DataSpaceAdvancedSearchModal
|
144
|
+
searchState={queryBuilderState.advancedSearchState}
|
145
|
+
onClose={() => queryBuilderState.hideAdvancedSearchPanel()}
|
146
|
+
/>
|
147
|
+
)}
|
148
|
+
</div>
|
149
|
+
</div>
|
150
|
+
</div>
|
151
|
+
<QueryBuilderClassSelector
|
152
|
+
queryBuilderState={queryBuilderState}
|
153
|
+
classes={[]}
|
154
|
+
noMatchMessage="No compatible class found"
|
155
|
+
/>
|
156
|
+
</>
|
157
|
+
);
|
158
|
+
},
|
159
|
+
);
|
160
|
+
|
161
|
+
export const renderDataSpaceQuerySetupSetupPanelContent = (
|
162
|
+
queryBuilderState: DataSpaceQuerySetupState,
|
163
|
+
): React.ReactNode => (
|
164
|
+
<DataSpaceQuerySetupSetupPanelContent queryBuilderState={queryBuilderState} />
|
165
|
+
);
|
@@ -0,0 +1,82 @@
|
|
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 { observer, useLocalObservable } from 'mobx-react-lite';
|
18
|
+
import { useParams } from '@finos/legend-application/browser';
|
19
|
+
import { parseGAVCoordinates } from '@finos/legend-storage';
|
20
|
+
import {
|
21
|
+
useLegendQueryApplicationStore,
|
22
|
+
useLegendQueryBaseStore,
|
23
|
+
} from '../LegendQueryFrameworkProvider.js';
|
24
|
+
import { DataSpaceTemplateQueryCreatorStore } from '../../stores/data-space/DataSpaceTemplateQueryCreatorStore.js';
|
25
|
+
import { QueryEditorStoreContext } from '../QueryEditorStoreProvider.js';
|
26
|
+
import {
|
27
|
+
DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN,
|
28
|
+
type DataSpaceTemplateQueryCreatorPathParams,
|
29
|
+
} from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
|
30
|
+
import { QueryEditor } from '../QueryEditor.js';
|
31
|
+
|
32
|
+
const DataSpaceTemplateQueryCreatorStoreProvider: React.FC<{
|
33
|
+
children: React.ReactNode;
|
34
|
+
gav: string;
|
35
|
+
dataSpacePath: string;
|
36
|
+
templateQueryId: string;
|
37
|
+
}> = ({ children, gav, dataSpacePath, templateQueryId }) => {
|
38
|
+
const { groupId, artifactId, versionId } = parseGAVCoordinates(gav);
|
39
|
+
const applicationStore = useLegendQueryApplicationStore();
|
40
|
+
const baseStore = useLegendQueryBaseStore();
|
41
|
+
const store = useLocalObservable(
|
42
|
+
() =>
|
43
|
+
new DataSpaceTemplateQueryCreatorStore(
|
44
|
+
applicationStore,
|
45
|
+
baseStore.depotServerClient,
|
46
|
+
groupId,
|
47
|
+
artifactId,
|
48
|
+
versionId,
|
49
|
+
dataSpacePath,
|
50
|
+
templateQueryId,
|
51
|
+
),
|
52
|
+
);
|
53
|
+
return (
|
54
|
+
<QueryEditorStoreContext.Provider value={store}>
|
55
|
+
{children}
|
56
|
+
</QueryEditorStoreContext.Provider>
|
57
|
+
);
|
58
|
+
};
|
59
|
+
|
60
|
+
export const DataSpaceTemplateQueryCreator = observer(() => {
|
61
|
+
const parameters = useParams<DataSpaceTemplateQueryCreatorPathParams>();
|
62
|
+
const gav =
|
63
|
+
parameters[DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.GAV];
|
64
|
+
const dataSpacePath =
|
65
|
+
parameters[
|
66
|
+
DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.DATA_SPACE_PATH
|
67
|
+
];
|
68
|
+
const templateQueryId =
|
69
|
+
parameters[
|
70
|
+
DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.TEMPLATE_QUERY_ID
|
71
|
+
];
|
72
|
+
|
73
|
+
return (
|
74
|
+
<DataSpaceTemplateQueryCreatorStoreProvider
|
75
|
+
gav={gav}
|
76
|
+
dataSpacePath={dataSpacePath}
|
77
|
+
templateQueryId={templateQueryId}
|
78
|
+
>
|
79
|
+
<QueryEditor />
|
80
|
+
</DataSpaceTemplateQueryCreatorStoreProvider>
|
81
|
+
);
|
82
|
+
});
|
@@ -0,0 +1,34 @@
|
|
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 {
|
18
|
+
QUERY_PROFILE_PATH,
|
19
|
+
QUERY_PROFILE_TAG_DATA_SPACE,
|
20
|
+
} from '@finos/legend-extension-dsl-data-space/graph';
|
21
|
+
import { isValidFullPath, type Query } from '@finos/legend-graph';
|
22
|
+
|
23
|
+
export const getDataSpaceQueryInfo = (query: Query): string | undefined => {
|
24
|
+
const dataSpaceTaggedValue = query.taggedValues?.find(
|
25
|
+
(taggedValue) =>
|
26
|
+
taggedValue.profile === QUERY_PROFILE_PATH &&
|
27
|
+
taggedValue.tag === QUERY_PROFILE_TAG_DATA_SPACE &&
|
28
|
+
isValidFullPath(taggedValue.value),
|
29
|
+
);
|
30
|
+
return dataSpaceTaggedValue?.value;
|
31
|
+
};
|
32
|
+
|
33
|
+
export const isDataSpaceQuery = (query: Query): boolean =>
|
34
|
+
Boolean(getDataSpaceQueryInfo(query));
|
@@ -88,11 +88,6 @@ export abstract class LegendQueryApplicationPlugin extends LegendApplicationPlug
|
|
88
88
|
pluginManager.registerApplicationPlugin(this);
|
89
89
|
}
|
90
90
|
|
91
|
-
/**
|
92
|
-
* Get Redirect path for root application path
|
93
|
-
*/
|
94
|
-
getExtraRootAppRedirectPath?(): string | undefined;
|
95
|
-
|
96
91
|
/**
|
97
92
|
* Get the list of actions (configurations) for query setup.
|
98
93
|
*/
|
@@ -103,27 +98,10 @@ export abstract class LegendQueryApplicationPlugin extends LegendApplicationPlug
|
|
103
98
|
*/
|
104
99
|
getExtraQueryEditorHelpMenuActionConfigurations?(): QueryEditorHelpMenuActionConfiguration[];
|
105
100
|
|
106
|
-
/**
|
107
|
-
* Get the list of existing query editor state builders.
|
108
|
-
*/
|
109
|
-
getExtraExistingQueryEditorStateBuilders?(): ExistingQueryEditorStateBuilder[];
|
110
|
-
|
111
101
|
/**
|
112
102
|
* Get the list of query editor action renderer configurations.
|
113
103
|
*/
|
114
104
|
getExtraQueryEditorActionConfigurations?(
|
115
105
|
editorStore: QueryEditorStore,
|
116
106
|
): QueryEditorActionConfiguration[];
|
117
|
-
|
118
|
-
/**
|
119
|
-
* Get the list of query headers
|
120
|
-
*/
|
121
|
-
getExtraQueryHeaders?(): ((
|
122
|
-
editorStore: QueryEditorStore,
|
123
|
-
) => React.ReactNode | undefined)[];
|
124
|
-
|
125
|
-
/**
|
126
|
-
* Get list of new query navigation paths
|
127
|
-
*/
|
128
|
-
getExtraNewQueryNavigationPaths?(): NewQueryNavigationPath[];
|
129
107
|
}
|
@@ -62,6 +62,7 @@ import {
|
|
62
62
|
reportGraphAnalytics,
|
63
63
|
cloneQueryStereotype,
|
64
64
|
cloneQueryTaggedValue,
|
65
|
+
type PackageableRuntime,
|
65
66
|
} from '@finos/legend-graph';
|
66
67
|
import {
|
67
68
|
EXTERNAL_APPLICATION_NAVIGATION__generateStudioProjectViewUrl,
|
@@ -85,6 +86,8 @@ import {
|
|
85
86
|
VersionedProjectData,
|
86
87
|
} from '@finos/legend-server-depot';
|
87
88
|
import {
|
89
|
+
ActionAlertActionType,
|
90
|
+
ActionAlertType,
|
88
91
|
DEFAULT_TAB_SIZE,
|
89
92
|
DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH,
|
90
93
|
} from '@finos/legend-application';
|
@@ -102,6 +105,20 @@ import {
|
|
102
105
|
} from '@finos/legend-query-builder';
|
103
106
|
import { LegendQueryUserDataHelper } from '../__lib__/LegendQueryUserDataHelper.js';
|
104
107
|
import { LegendQueryTelemetryHelper } from '../__lib__/LegendQueryTelemetryHelper.js';
|
108
|
+
import {
|
109
|
+
DataSpaceProjectInfo,
|
110
|
+
DataSpaceQueryBuilderState,
|
111
|
+
type DataSpaceInfo,
|
112
|
+
} from '@finos/legend-extension-dsl-data-space/application';
|
113
|
+
import { getDataSpaceQueryInfo } from '../components/data-space/QueryDataSpaceUtil.js';
|
114
|
+
import {
|
115
|
+
DSL_DataSpace_getGraphManagerExtension,
|
116
|
+
type DataSpace,
|
117
|
+
type DataSpaceExecutionContext,
|
118
|
+
getOwnDataSpace,
|
119
|
+
retrieveAnalyticsResultCache,
|
120
|
+
} from '@finos/legend-extension-dsl-data-space/graph';
|
121
|
+
import { generateDataSpaceQueryCreatorRoute } from '../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
|
105
122
|
|
106
123
|
export const createViewProjectHandler =
|
107
124
|
(applicationStore: LegendQueryApplicationStore) =>
|
@@ -1034,6 +1051,25 @@ export class ExistingQueryUpdateState {
|
|
1034
1051
|
}
|
1035
1052
|
}
|
1036
1053
|
|
1054
|
+
const resolveExecutionContext = (
|
1055
|
+
dataSpace: DataSpace,
|
1056
|
+
queryMapping: Mapping,
|
1057
|
+
queryRuntime: PackageableRuntime,
|
1058
|
+
): DataSpaceExecutionContext | undefined => {
|
1059
|
+
const matchingExecContexts = dataSpace.executionContexts.filter(
|
1060
|
+
(ec) => ec.mapping.value === queryMapping,
|
1061
|
+
);
|
1062
|
+
if (matchingExecContexts.length > 1) {
|
1063
|
+
const matchRuntime = matchingExecContexts.find(
|
1064
|
+
(exec) => exec.defaultRuntime.value.path === queryRuntime.path,
|
1065
|
+
);
|
1066
|
+
// TODO: we will safely do this for now. Long term we should save exec context key into query store
|
1067
|
+
// we should make runtime/mapping optional
|
1068
|
+
return matchRuntime ?? matchingExecContexts[0];
|
1069
|
+
}
|
1070
|
+
return matchingExecContexts[0];
|
1071
|
+
};
|
1072
|
+
|
1037
1073
|
export class ExistingQueryEditorStore extends QueryEditorStore {
|
1038
1074
|
private queryId: string;
|
1039
1075
|
private _lightQuery?: LightQuery | undefined;
|
@@ -1113,6 +1149,154 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
|
|
1113
1149
|
);
|
1114
1150
|
}
|
1115
1151
|
|
1152
|
+
async buildDataspaceBuilderState(
|
1153
|
+
query: Query,
|
1154
|
+
): Promise<DataSpaceQueryBuilderState | undefined> {
|
1155
|
+
const dataSpacePath = getDataSpaceQueryInfo(query);
|
1156
|
+
if (dataSpacePath) {
|
1157
|
+
const dataSpace = getOwnDataSpace(
|
1158
|
+
dataSpacePath,
|
1159
|
+
this.graphManagerState.graph,
|
1160
|
+
);
|
1161
|
+
const mapping = query.mapping.value;
|
1162
|
+
const matchingExecutionContext = resolveExecutionContext(
|
1163
|
+
dataSpace,
|
1164
|
+
mapping,
|
1165
|
+
query.runtime.value,
|
1166
|
+
);
|
1167
|
+
if (!matchingExecutionContext) {
|
1168
|
+
// if a matching execution context is not found, it means this query is not
|
1169
|
+
// properly created from a data space, therefore, we cannot support this case
|
1170
|
+
return undefined;
|
1171
|
+
}
|
1172
|
+
let dataSpaceAnalysisResult;
|
1173
|
+
try {
|
1174
|
+
const project = StoreProjectData.serialization.fromJson(
|
1175
|
+
await this.depotServerClient.getProject(
|
1176
|
+
query.groupId,
|
1177
|
+
query.artifactId,
|
1178
|
+
),
|
1179
|
+
);
|
1180
|
+
dataSpaceAnalysisResult = await DSL_DataSpace_getGraphManagerExtension(
|
1181
|
+
this.graphManagerState.graphManager,
|
1182
|
+
).retrieveDataSpaceAnalysisFromCache(() =>
|
1183
|
+
retrieveAnalyticsResultCache(
|
1184
|
+
project,
|
1185
|
+
query.versionId,
|
1186
|
+
dataSpace.path,
|
1187
|
+
this.depotServerClient,
|
1188
|
+
),
|
1189
|
+
);
|
1190
|
+
} catch {
|
1191
|
+
// do nothing
|
1192
|
+
}
|
1193
|
+
const projectInfo = new DataSpaceProjectInfo(
|
1194
|
+
query.groupId,
|
1195
|
+
query.artifactId,
|
1196
|
+
query.versionId,
|
1197
|
+
createViewProjectHandler(this.applicationStore),
|
1198
|
+
createViewSDLCProjectHandler(
|
1199
|
+
this.applicationStore,
|
1200
|
+
this.depotServerClient,
|
1201
|
+
),
|
1202
|
+
);
|
1203
|
+
const sourceInfo = {
|
1204
|
+
groupId: projectInfo.groupId,
|
1205
|
+
artifactId: projectInfo.artifactId,
|
1206
|
+
versionId: projectInfo.versionId,
|
1207
|
+
dataSpace: dataSpace.path,
|
1208
|
+
};
|
1209
|
+
const dataSpaceQueryBuilderState = new DataSpaceQueryBuilderState(
|
1210
|
+
this.applicationStore,
|
1211
|
+
this.graphManagerState,
|
1212
|
+
this.depotServerClient,
|
1213
|
+
dataSpace,
|
1214
|
+
matchingExecutionContext,
|
1215
|
+
(dataSpaceInfo: DataSpaceInfo) => {
|
1216
|
+
if (dataSpaceInfo.defaultExecutionContext) {
|
1217
|
+
const proceed = (): void =>
|
1218
|
+
this.applicationStore.navigationService.navigator.goToLocation(
|
1219
|
+
generateDataSpaceQueryCreatorRoute(
|
1220
|
+
guaranteeNonNullable(dataSpaceInfo.groupId),
|
1221
|
+
guaranteeNonNullable(dataSpaceInfo.artifactId),
|
1222
|
+
LATEST_VERSION_ALIAS, //always default to latest
|
1223
|
+
dataSpaceInfo.path,
|
1224
|
+
guaranteeNonNullable(dataSpaceInfo.defaultExecutionContext),
|
1225
|
+
undefined,
|
1226
|
+
undefined,
|
1227
|
+
),
|
1228
|
+
);
|
1229
|
+
const updateQueryAndProceed = async (): Promise<void> => {
|
1230
|
+
try {
|
1231
|
+
await flowResult(
|
1232
|
+
this.updateState.updateQuery(undefined, undefined),
|
1233
|
+
);
|
1234
|
+
proceed();
|
1235
|
+
} catch (error) {
|
1236
|
+
assertErrorThrown(error);
|
1237
|
+
this.applicationStore.logService.error(
|
1238
|
+
LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
|
1239
|
+
error,
|
1240
|
+
);
|
1241
|
+
this.applicationStore.notificationService.notifyError(error);
|
1242
|
+
}
|
1243
|
+
};
|
1244
|
+
if (
|
1245
|
+
!query.isCurrentUserQuery ||
|
1246
|
+
!this.queryBuilderState?.changeDetectionState.hasChanged
|
1247
|
+
) {
|
1248
|
+
proceed();
|
1249
|
+
} else {
|
1250
|
+
this.applicationStore.alertService.setActionAlertInfo({
|
1251
|
+
message: `To change the data space, you need to save the current query
|
1252
|
+
to proceed`,
|
1253
|
+
type: ActionAlertType.CAUTION,
|
1254
|
+
actions: [
|
1255
|
+
{
|
1256
|
+
label: 'Save query and Proceed',
|
1257
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
1258
|
+
handler: () => {
|
1259
|
+
updateQueryAndProceed().catch(
|
1260
|
+
this.applicationStore.alertUnhandledError,
|
1261
|
+
);
|
1262
|
+
},
|
1263
|
+
},
|
1264
|
+
{
|
1265
|
+
label: 'Abort',
|
1266
|
+
type: ActionAlertActionType.PROCEED,
|
1267
|
+
default: true,
|
1268
|
+
},
|
1269
|
+
],
|
1270
|
+
});
|
1271
|
+
}
|
1272
|
+
} else {
|
1273
|
+
this.applicationStore.notificationService.notifyWarning(
|
1274
|
+
`Can't switch data space: default execution context not specified`,
|
1275
|
+
);
|
1276
|
+
}
|
1277
|
+
},
|
1278
|
+
true,
|
1279
|
+
dataSpaceAnalysisResult,
|
1280
|
+
undefined,
|
1281
|
+
undefined,
|
1282
|
+
undefined,
|
1283
|
+
projectInfo,
|
1284
|
+
this.applicationStore.config.options.queryBuilderConfig,
|
1285
|
+
sourceInfo,
|
1286
|
+
);
|
1287
|
+
const mappingModelCoverageAnalysisResult =
|
1288
|
+
dataSpaceAnalysisResult?.executionContextsIndex.get(
|
1289
|
+
matchingExecutionContext.name,
|
1290
|
+
)?.mappingModelCoverageAnalysisResult;
|
1291
|
+
if (mappingModelCoverageAnalysisResult) {
|
1292
|
+
dataSpaceQueryBuilderState.explorerState.mappingModelCoverageAnalysisResult =
|
1293
|
+
mappingModelCoverageAnalysisResult;
|
1294
|
+
}
|
1295
|
+
return dataSpaceQueryBuilderState;
|
1296
|
+
}
|
1297
|
+
return undefined;
|
1298
|
+
}
|
1299
|
+
|
1116
1300
|
async initializeQueryBuilderState(
|
1117
1301
|
stopWatch: StopWatch,
|
1118
1302
|
): Promise<QueryBuilderState> {
|
@@ -1125,18 +1309,6 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
|
|
1125
1309
|
this.applicationStore.userDataService,
|
1126
1310
|
query.id,
|
1127
1311
|
);
|
1128
|
-
let queryBuilderState: QueryBuilderState | undefined;
|
1129
|
-
const existingQueryEditorStateBuilders = this.applicationStore.pluginManager
|
1130
|
-
.getApplicationPlugins()
|
1131
|
-
.flatMap(
|
1132
|
-
(plugin) => plugin.getExtraExistingQueryEditorStateBuilders?.() ?? [],
|
1133
|
-
);
|
1134
|
-
for (const builder of existingQueryEditorStateBuilders) {
|
1135
|
-
queryBuilderState = await builder(query, this);
|
1136
|
-
if (queryBuilderState) {
|
1137
|
-
break;
|
1138
|
-
}
|
1139
|
-
}
|
1140
1312
|
|
1141
1313
|
// if no extension found, fall back to basic `class -> mapping -> runtime` mode
|
1142
1314
|
const projectInfo = this.getProjectInfo();
|
@@ -1145,6 +1317,9 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
|
|
1145
1317
|
artifactId: projectInfo.artifactId,
|
1146
1318
|
versionId: projectInfo.versionId,
|
1147
1319
|
};
|
1320
|
+
let queryBuilderState: QueryBuilderState | undefined =
|
1321
|
+
await this.buildDataspaceBuilderState(query);
|
1322
|
+
|
1148
1323
|
queryBuilderState =
|
1149
1324
|
queryBuilderState ??
|
1150
1325
|
new ClassQueryBuilderState(
|