@finos/legend-application-query 13.7.205 → 13.8.0
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/__lib__/LegendQueryNavigation.d.ts +16 -10
- package/lib/__lib__/LegendQueryNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryNavigation.js +17 -12
- package/lib/__lib__/LegendQueryNavigation.js.map +1 -1
- package/lib/__lib__/LegendQueryUserDataHelper.d.ts +25 -7
- package/lib/__lib__/LegendQueryUserDataHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryUserDataHelper.js +81 -6
- package/lib/__lib__/LegendQueryUserDataHelper.js.map +1 -1
- package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts +21 -4
- package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryUserDataSpaceHelper.js +17 -0
- package/lib/__lib__/LegendQueryUserDataSpaceHelper.js.map +1 -1
- package/lib/application/LegendQueryApplicationConfig.d.ts +10 -0
- package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendQueryApplicationConfig.js +16 -0
- package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.js +7 -3
- package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
- package/lib/components/LegendQueryWebApplication.d.ts.map +1 -1
- package/lib/components/LegendQueryWebApplication.js +2 -2
- package/lib/components/LegendQueryWebApplication.js.map +1 -1
- package/lib/components/QueryEditor.d.ts.map +1 -1
- package/lib/components/QueryEditor.js +5 -2
- package/lib/components/QueryEditor.js.map +1 -1
- package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts +8 -0
- package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts.map +1 -1
- package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js +190 -8
- package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js.map +1 -1
- package/lib/components/data-product/DataProductInfo.d.ts +28 -0
- package/lib/components/data-product/DataProductInfo.d.ts.map +1 -0
- package/lib/components/data-product/DataProductInfo.js +89 -0
- package/lib/components/data-product/DataProductInfo.js.map +1 -0
- package/lib/components/{data-space/DataSpaceQueryCreator.d.ts → data-product/LegendQueryDataProductQueryBuilder.d.ts} +3 -4
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.d.ts.map +1 -0
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js +98 -0
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js.map +1 -0
- package/lib/components/data-space/DataProductQueryCreator.d.ts +36 -0
- package/lib/components/data-space/DataProductQueryCreator.d.ts.map +1 -0
- package/lib/components/data-space/DataProductQueryCreator.js +76 -0
- package/lib/components/data-space/DataProductQueryCreator.js.map +1 -0
- package/lib/index.css +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/light-mode.css +1 -1
- package/lib/package.json +2 -1
- package/lib/stores/QueryEditorStore.d.ts +46 -2
- package/lib/stores/QueryEditorStore.d.ts.map +1 -1
- package/lib/stores/QueryEditorStore.js +251 -5
- package/lib/stores/QueryEditorStore.js.map +1 -1
- package/lib/stores/data-product/query-builder/DataProductArtifactHelper.d.ts +21 -0
- package/lib/stores/data-product/query-builder/DataProductArtifactHelper.d.ts.map +1 -0
- package/lib/stores/data-product/query-builder/DataProductArtifactHelper.js +35 -0
- package/lib/stores/data-product/query-builder/DataProductArtifactHelper.js.map +1 -0
- package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.d.ts +11 -3
- package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.d.ts.map +1 -1
- package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js +50 -8
- package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js.map +1 -1
- package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts +94 -0
- package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts.map +1 -0
- package/lib/stores/data-space/DataProductQueryCreatorStore.js +388 -0
- package/lib/stores/data-space/DataProductQueryCreatorStore.js.map +1 -0
- package/lib/stores/data-space/DataProductSelectorState.d.ts +44 -0
- package/lib/stores/data-space/DataProductSelectorState.d.ts.map +1 -0
- package/lib/stores/data-space/DataProductSelectorState.js +111 -0
- package/lib/stores/data-space/DataProductSelectorState.js.map +1 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +3 -0
- package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
- package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts +1 -1
- package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts.map +1 -1
- package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js +1 -1
- package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js.map +1 -1
- package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.d.ts +4 -3
- package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.d.ts.map +1 -1
- package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js +24 -29
- package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js.map +1 -1
- package/package.json +8 -7
- package/src/__lib__/LegendQueryNavigation.ts +76 -18
- package/src/__lib__/LegendQueryUserDataHelper.ts +177 -12
- package/src/__lib__/LegendQueryUserDataSpaceHelper.ts +54 -4
- package/src/application/LegendQueryApplicationConfig.ts +31 -0
- package/src/components/Core_LegendQueryApplicationPlugin.tsx +8 -2
- package/src/components/LegendQueryWebApplication.tsx +8 -4
- package/src/components/QueryEditor.tsx +13 -0
- package/src/components/__test-utils__/QueryEditorComponentTestUtils.tsx +418 -5
- package/src/components/data-product/DataProductInfo.tsx +297 -0
- package/src/components/data-product/LegendQueryDataProductQueryBuilder.tsx +268 -0
- package/src/components/data-space/DataProductQueryCreator.tsx +167 -0
- package/src/components/data-space/DataSpaceQuerySetup.tsx +1 -1
- package/src/index.ts +6 -0
- package/src/stores/QueryEditorStore.ts +485 -2
- package/src/stores/data-product/query-builder/DataProductArtifactHelper.ts +48 -0
- package/src/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.ts +77 -16
- package/src/stores/data-space/DataProductQueryCreatorStore.ts +765 -0
- package/src/stores/data-space/DataProductSelectorState.ts +164 -0
- package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +10 -0
- package/src/stores/data-space/LegendQueryBareQueryBuilderState.ts +1 -1
- package/src/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.ts +27 -54
- package/tsconfig.json +6 -2
- package/lib/components/data-space/DataSpaceQueryCreator.d.ts.map +0 -1
- package/lib/components/data-space/DataSpaceQueryCreator.js +0 -62
- package/lib/components/data-space/DataSpaceQueryCreator.js.map +0 -1
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts +0 -92
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +0 -1
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +0 -400
- package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +0 -1
- package/src/components/data-space/DataSpaceQueryCreator.tsx +0 -119
- package/src/stores/data-space/DataSpaceQueryCreatorStore.ts +0 -697
|
@@ -0,0 +1,297 @@
|
|
|
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
|
+
Dialog,
|
|
19
|
+
Modal,
|
|
20
|
+
ModalTitle,
|
|
21
|
+
Panel,
|
|
22
|
+
PanelFullContent,
|
|
23
|
+
} from '@finos/legend-art';
|
|
24
|
+
import {
|
|
25
|
+
LATEST_VERSION_ALIAS,
|
|
26
|
+
isSnapshotVersion,
|
|
27
|
+
SNAPSHOT_VERSION_ALIAS,
|
|
28
|
+
StoreProjectData,
|
|
29
|
+
VersionedProjectData,
|
|
30
|
+
} from '@finos/legend-server-depot';
|
|
31
|
+
import { observer } from 'mobx-react-lite';
|
|
32
|
+
import { type QueryEditorStore } from '../../stores/QueryEditorStore.js';
|
|
33
|
+
import {
|
|
34
|
+
EXTERNAL_APPLICATION_NAVIGATION__generateStudioSDLCProjectViewUrl,
|
|
35
|
+
EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataProductUrl,
|
|
36
|
+
} from '../../__lib__/LegendQueryNavigation.js';
|
|
37
|
+
import { flowResult } from 'mobx';
|
|
38
|
+
import { assertErrorThrown } from '@finos/legend-shared';
|
|
39
|
+
import {
|
|
40
|
+
type DataProduct,
|
|
41
|
+
FunctionAccessPoint,
|
|
42
|
+
LakehouseAccessPoint,
|
|
43
|
+
LakehouseRuntime,
|
|
44
|
+
} from '@finos/legend-graph';
|
|
45
|
+
import {
|
|
46
|
+
type DataProductQueryBuilderState,
|
|
47
|
+
ModelAccessPointDataProductExecutionState,
|
|
48
|
+
} from '@finos/legend-query-builder';
|
|
49
|
+
import { LegendQueryDataProductQueryBuilderState } from '../../stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js';
|
|
50
|
+
|
|
51
|
+
export const QueryEditorDataProductInfoModal = observer(
|
|
52
|
+
(props: {
|
|
53
|
+
editorStore: QueryEditorStore;
|
|
54
|
+
dataProduct: DataProduct;
|
|
55
|
+
queryBuilderState: DataProductQueryBuilderState;
|
|
56
|
+
open: boolean;
|
|
57
|
+
closeModal: () => void;
|
|
58
|
+
}) => {
|
|
59
|
+
const { editorStore, dataProduct, queryBuilderState, open, closeModal } =
|
|
60
|
+
props;
|
|
61
|
+
const projectInfo = editorStore.getProjectInfo();
|
|
62
|
+
const executionState = queryBuilderState.executionState;
|
|
63
|
+
|
|
64
|
+
const visitElement = async (path: string | undefined): Promise<void> => {
|
|
65
|
+
try {
|
|
66
|
+
if (projectInfo) {
|
|
67
|
+
const project = StoreProjectData.serialization.fromJson(
|
|
68
|
+
await editorStore.depotServerClient.getProject(
|
|
69
|
+
projectInfo.groupId,
|
|
70
|
+
projectInfo.artifactId,
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
const versionId =
|
|
74
|
+
projectInfo.versionId === LATEST_VERSION_ALIAS
|
|
75
|
+
? VersionedProjectData.serialization.fromJson(
|
|
76
|
+
await editorStore.depotServerClient.getLatestVersion(
|
|
77
|
+
projectInfo.groupId,
|
|
78
|
+
projectInfo.artifactId,
|
|
79
|
+
),
|
|
80
|
+
).versionId
|
|
81
|
+
: projectInfo.versionId;
|
|
82
|
+
|
|
83
|
+
editorStore.applicationStore.navigationService.navigator.visitAddress(
|
|
84
|
+
EXTERNAL_APPLICATION_NAVIGATION__generateStudioSDLCProjectViewUrl(
|
|
85
|
+
editorStore.applicationStore.config.studioApplicationUrl,
|
|
86
|
+
project.projectId,
|
|
87
|
+
versionId,
|
|
88
|
+
path,
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
assertErrorThrown(error);
|
|
94
|
+
editorStore.applicationStore.notificationService.notifyError(
|
|
95
|
+
path
|
|
96
|
+
? `Can't visit element of path: '${path}'`
|
|
97
|
+
: `Can't visit project`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const accessPointGroup =
|
|
103
|
+
executionState instanceof ModelAccessPointDataProductExecutionState
|
|
104
|
+
? executionState.exectionValue
|
|
105
|
+
: undefined;
|
|
106
|
+
const mapping = executionState.mapping;
|
|
107
|
+
const selectedRuntime =
|
|
108
|
+
executionState instanceof ModelAccessPointDataProductExecutionState
|
|
109
|
+
? executionState.selectedRuntime
|
|
110
|
+
: undefined;
|
|
111
|
+
const accessPoints = accessPointGroup?.accessPoints ?? [];
|
|
112
|
+
const supportEmails = dataProduct.supportInfo?.emails ?? [];
|
|
113
|
+
|
|
114
|
+
const deploymentId =
|
|
115
|
+
queryBuilderState.dataProductArtifact?.dataProduct.deploymentId;
|
|
116
|
+
const versionId = projectInfo?.versionId;
|
|
117
|
+
const isSnapshotVer =
|
|
118
|
+
versionId !== undefined &&
|
|
119
|
+
(isSnapshotVersion(versionId) || versionId === SNAPSHOT_VERSION_ALIAS);
|
|
120
|
+
const marketplaceUrl = isSnapshotVer
|
|
121
|
+
? editorStore.applicationStore.config.marketplaceProductionParallelUrl
|
|
122
|
+
: editorStore.applicationStore.config.marketplaceApplicationUrl;
|
|
123
|
+
const canOpenInMarketplace =
|
|
124
|
+
queryBuilderState instanceof LegendQueryDataProductQueryBuilderState &&
|
|
125
|
+
deploymentId !== undefined &&
|
|
126
|
+
marketplaceUrl !== undefined;
|
|
127
|
+
|
|
128
|
+
const openInMarketplace = (): void => {
|
|
129
|
+
if (canOpenInMarketplace && marketplaceUrl && deploymentId) {
|
|
130
|
+
editorStore.applicationStore.navigationService.navigator.visitAddress(
|
|
131
|
+
EXTERNAL_APPLICATION_NAVIGATION__generateMarketplaceDataProductUrl(
|
|
132
|
+
marketplaceUrl,
|
|
133
|
+
dataProduct.name,
|
|
134
|
+
deploymentId,
|
|
135
|
+
),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const getAccessPointTypeLabel = (
|
|
141
|
+
ap: (typeof accessPoints)[number],
|
|
142
|
+
): string => {
|
|
143
|
+
if (ap instanceof FunctionAccessPoint) {
|
|
144
|
+
return 'Function';
|
|
145
|
+
}
|
|
146
|
+
if (ap instanceof LakehouseAccessPoint) {
|
|
147
|
+
return 'Lakehouse';
|
|
148
|
+
}
|
|
149
|
+
return 'Unknown';
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<Dialog
|
|
154
|
+
open={open}
|
|
155
|
+
onClose={closeModal}
|
|
156
|
+
classes={{ container: 'dataspace-info-modal__container' }}
|
|
157
|
+
slotProps={{
|
|
158
|
+
paper: {
|
|
159
|
+
classes: { root: 'dataspace-info-modal__inner-container' },
|
|
160
|
+
},
|
|
161
|
+
}}
|
|
162
|
+
>
|
|
163
|
+
<Modal
|
|
164
|
+
darkMode={
|
|
165
|
+
!editorStore.applicationStore.layoutService
|
|
166
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
167
|
+
}
|
|
168
|
+
className="dataspace-info-modal"
|
|
169
|
+
>
|
|
170
|
+
<div className="dataspace-info-modal__header">
|
|
171
|
+
<ModalTitle title="About Data Product" />
|
|
172
|
+
{canOpenInMarketplace && (
|
|
173
|
+
<button
|
|
174
|
+
className="btn--dark dataspace-info-modal__header__open-btn"
|
|
175
|
+
title="Open Data Product in Marketplace"
|
|
176
|
+
onClick={openInMarketplace}
|
|
177
|
+
>
|
|
178
|
+
Open Data Product
|
|
179
|
+
</button>
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<Panel>
|
|
184
|
+
<PanelFullContent>
|
|
185
|
+
{projectInfo && (
|
|
186
|
+
<div className="dataspace-info-modal__field">
|
|
187
|
+
<div className="dataspace-info-modal__field__label">
|
|
188
|
+
Project
|
|
189
|
+
</div>
|
|
190
|
+
<div
|
|
191
|
+
className="dataspace-info-modal__field__value dataspace-info-modal__field__value--linkable"
|
|
192
|
+
onClick={() => flowResult(visitElement(undefined))}
|
|
193
|
+
>
|
|
194
|
+
{`${projectInfo.groupId}:${projectInfo.artifactId}:${projectInfo.versionId}`}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
<div className="dataspace-info-modal__field">
|
|
199
|
+
<div className="dataspace-info-modal__field__label">Name</div>
|
|
200
|
+
<div className="dataspace-info-modal__field__value">
|
|
201
|
+
{dataProduct.title ?? dataProduct.name}
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
{accessPointGroup && (
|
|
205
|
+
<div className="dataspace-info-modal__field">
|
|
206
|
+
<div className="dataspace-info-modal__field__label">
|
|
207
|
+
Access Point Group
|
|
208
|
+
</div>
|
|
209
|
+
<div className="dataspace-info-modal__field__value">
|
|
210
|
+
{accessPointGroup.title ?? accessPointGroup.id}
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
)}
|
|
214
|
+
<div className="dataspace-info-modal__field">
|
|
215
|
+
<div className="dataspace-info-modal__field__label">
|
|
216
|
+
Mapping
|
|
217
|
+
</div>
|
|
218
|
+
<div
|
|
219
|
+
className="dataspace-info-modal__field__value dataspace-info-modal__field__value--linkable"
|
|
220
|
+
onClick={() => flowResult(visitElement(mapping.path))}
|
|
221
|
+
>
|
|
222
|
+
{mapping.name}
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
{selectedRuntime &&
|
|
226
|
+
selectedRuntime.runtimeValue instanceof LakehouseRuntime && (
|
|
227
|
+
<>
|
|
228
|
+
{selectedRuntime.runtimeValue.environment && (
|
|
229
|
+
<div className="dataspace-info-modal__field">
|
|
230
|
+
<div className="dataspace-info-modal__field__label">
|
|
231
|
+
Environment
|
|
232
|
+
</div>
|
|
233
|
+
<div className="dataspace-info-modal__field__value">
|
|
234
|
+
{selectedRuntime.runtimeValue.environment}
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
)}
|
|
238
|
+
{selectedRuntime.runtimeValue.warehouse && (
|
|
239
|
+
<div className="dataspace-info-modal__field">
|
|
240
|
+
<div className="dataspace-info-modal__field__label">
|
|
241
|
+
Warehouse
|
|
242
|
+
</div>
|
|
243
|
+
<div className="dataspace-info-modal__field__value">
|
|
244
|
+
{selectedRuntime.runtimeValue.warehouse}
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
248
|
+
</>
|
|
249
|
+
)}
|
|
250
|
+
{accessPoints.length > 0 && (
|
|
251
|
+
<>
|
|
252
|
+
{accessPoints.map((ap) => (
|
|
253
|
+
<div className="dataspace-info-modal__field" key={ap.id}>
|
|
254
|
+
<div className="dataspace-info-modal__field__label">
|
|
255
|
+
Access Point
|
|
256
|
+
</div>
|
|
257
|
+
<div className="dataspace-info-modal__field__value">
|
|
258
|
+
{`${ap.title ?? ap.id} (${getAccessPointTypeLabel(ap)})`}
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
))}
|
|
262
|
+
</>
|
|
263
|
+
)}
|
|
264
|
+
<div className="dataspace-info-modal__field">
|
|
265
|
+
<div className="dataspace-info-modal__field__label">
|
|
266
|
+
Configuration
|
|
267
|
+
</div>
|
|
268
|
+
<div
|
|
269
|
+
className="dataspace-info-modal__field__value dataspace-info-modal__field__value--linkable"
|
|
270
|
+
onClick={() => flowResult(visitElement(dataProduct.path))}
|
|
271
|
+
>
|
|
272
|
+
Show Data Product Configuration
|
|
273
|
+
</div>
|
|
274
|
+
</div>
|
|
275
|
+
{supportEmails.map((email) => (
|
|
276
|
+
<div
|
|
277
|
+
className="dataspace-info-modal__field"
|
|
278
|
+
key={email.address}
|
|
279
|
+
>
|
|
280
|
+
<div className="dataspace-info-modal__field__label">
|
|
281
|
+
Support Email
|
|
282
|
+
</div>
|
|
283
|
+
<a
|
|
284
|
+
className="dataspace-info-modal__field__value dataspace-info-modal__field__value--linkable"
|
|
285
|
+
href={`mailto:${email.address}`}
|
|
286
|
+
>
|
|
287
|
+
{email.address}
|
|
288
|
+
</a>
|
|
289
|
+
</div>
|
|
290
|
+
))}
|
|
291
|
+
</PanelFullContent>
|
|
292
|
+
</Panel>
|
|
293
|
+
</Modal>
|
|
294
|
+
</Dialog>
|
|
295
|
+
);
|
|
296
|
+
},
|
|
297
|
+
);
|
|
@@ -0,0 +1,268 @@
|
|
|
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 { useApplicationStore } from '@finos/legend-application';
|
|
18
|
+
import {
|
|
19
|
+
ModelAccessPointDataProductExecutionState,
|
|
20
|
+
DataProductQueryBuilderSetupFormContent,
|
|
21
|
+
} from '@finos/legend-query-builder';
|
|
22
|
+
import {
|
|
23
|
+
AnchorLinkIcon,
|
|
24
|
+
CogIcon,
|
|
25
|
+
ControlledDropdownMenu,
|
|
26
|
+
Dialog,
|
|
27
|
+
MenuContent,
|
|
28
|
+
MenuContentItem,
|
|
29
|
+
MenuContentItemIcon,
|
|
30
|
+
MenuContentItemLabel,
|
|
31
|
+
Modal,
|
|
32
|
+
ModalBody,
|
|
33
|
+
ModalFooter,
|
|
34
|
+
ModalFooterButton,
|
|
35
|
+
ModalHeader,
|
|
36
|
+
ModalHeaderActions,
|
|
37
|
+
ModalTitle,
|
|
38
|
+
MoreVerticalIcon,
|
|
39
|
+
PanelHeader,
|
|
40
|
+
PanelHeaderActionItem,
|
|
41
|
+
PanelHeaderActions,
|
|
42
|
+
TimesIcon,
|
|
43
|
+
} from '@finos/legend-art';
|
|
44
|
+
import { observer } from 'mobx-react-lite';
|
|
45
|
+
import { LakehouseRuntime } from '@finos/legend-graph';
|
|
46
|
+
import { useEffect, useState } from 'react';
|
|
47
|
+
import type { LegendQueryDataProductQueryBuilderState } from '../../stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js';
|
|
48
|
+
import { LegendQueryUserDataHelper } from '../../__lib__/LegendQueryUserDataHelper.js';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Modal for editing LakehouseRuntime configuration (environment and warehouse).
|
|
52
|
+
*/
|
|
53
|
+
const LakehouseRuntimeConfigModal = observer(
|
|
54
|
+
(props: {
|
|
55
|
+
executionState: ModelAccessPointDataProductExecutionState;
|
|
56
|
+
open: boolean;
|
|
57
|
+
onClose: () => void;
|
|
58
|
+
darkMode: boolean;
|
|
59
|
+
}) => {
|
|
60
|
+
const { executionState, open, onClose, darkMode } = props;
|
|
61
|
+
const lakehouseRuntime =
|
|
62
|
+
executionState.selectedRuntime?.runtimeValue instanceof LakehouseRuntime
|
|
63
|
+
? executionState.selectedRuntime.runtimeValue
|
|
64
|
+
: undefined;
|
|
65
|
+
const [env, setEnv] = useState(lakehouseRuntime?.environment ?? '');
|
|
66
|
+
const [warehouse, setWarehouse] = useState(
|
|
67
|
+
lakehouseRuntime?.warehouse ?? '',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// sync local state when the modal opens or the runtime changes
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (open && lakehouseRuntime) {
|
|
73
|
+
setEnv(lakehouseRuntime.environment ?? '');
|
|
74
|
+
setWarehouse(lakehouseRuntime.warehouse ?? '');
|
|
75
|
+
}
|
|
76
|
+
}, [open, lakehouseRuntime]);
|
|
77
|
+
|
|
78
|
+
const applicationStore = useApplicationStore();
|
|
79
|
+
|
|
80
|
+
const handleApply = (): void => {
|
|
81
|
+
if (lakehouseRuntime) {
|
|
82
|
+
const newEnv = env || undefined;
|
|
83
|
+
const newWarehouse = warehouse || undefined;
|
|
84
|
+
const hasChanged =
|
|
85
|
+
newEnv !== lakehouseRuntime.environment ||
|
|
86
|
+
newWarehouse !== lakehouseRuntime.warehouse;
|
|
87
|
+
lakehouseRuntime.environment = newEnv;
|
|
88
|
+
lakehouseRuntime.warehouse = newWarehouse;
|
|
89
|
+
if (hasChanged) {
|
|
90
|
+
LegendQueryUserDataHelper.persistLakehouseUserInfo(
|
|
91
|
+
applicationStore.userDataService,
|
|
92
|
+
{
|
|
93
|
+
env: newEnv,
|
|
94
|
+
snowflakeWarehouse: newWarehouse,
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
onClose();
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (!lakehouseRuntime) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<Dialog onClose={onClose} open={open}>
|
|
108
|
+
<Modal darkMode={darkMode}>
|
|
109
|
+
<ModalHeader>
|
|
110
|
+
<ModalTitle
|
|
111
|
+
icon={<CogIcon />}
|
|
112
|
+
title="Lakehouse Runtime Configuration"
|
|
113
|
+
/>
|
|
114
|
+
<ModalHeaderActions>
|
|
115
|
+
<button
|
|
116
|
+
className="modal__header__action"
|
|
117
|
+
tabIndex={-1}
|
|
118
|
+
onClick={onClose}
|
|
119
|
+
>
|
|
120
|
+
<TimesIcon />
|
|
121
|
+
</button>
|
|
122
|
+
</ModalHeaderActions>
|
|
123
|
+
</ModalHeader>
|
|
124
|
+
<ModalBody>
|
|
125
|
+
<div className="panel__content__form__section">
|
|
126
|
+
<div className="panel__content__form__section__header__label">
|
|
127
|
+
Environment
|
|
128
|
+
</div>
|
|
129
|
+
<input
|
|
130
|
+
className="panel__content__form__section__input input--dark input--small"
|
|
131
|
+
spellCheck={false}
|
|
132
|
+
value={env}
|
|
133
|
+
placeholder="(optional)"
|
|
134
|
+
onChange={(e) => setEnv(e.target.value)}
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
<div className="panel__content__form__section">
|
|
138
|
+
<div className="panel__content__form__section__header__label">
|
|
139
|
+
Warehouse
|
|
140
|
+
</div>
|
|
141
|
+
<input
|
|
142
|
+
className="panel__content__form__section__input input--dark input--small"
|
|
143
|
+
spellCheck={false}
|
|
144
|
+
value={warehouse}
|
|
145
|
+
placeholder="(optional)"
|
|
146
|
+
onChange={(e) => setWarehouse(e.target.value)}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
</ModalBody>
|
|
150
|
+
<ModalFooter>
|
|
151
|
+
<ModalFooterButton
|
|
152
|
+
text="Apply"
|
|
153
|
+
onClick={handleApply}
|
|
154
|
+
type="primary"
|
|
155
|
+
/>
|
|
156
|
+
<ModalFooterButton
|
|
157
|
+
text="Cancel"
|
|
158
|
+
onClick={onClose}
|
|
159
|
+
type="secondary"
|
|
160
|
+
/>
|
|
161
|
+
</ModalFooter>
|
|
162
|
+
</Modal>
|
|
163
|
+
</Dialog>
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const LegendDataProductQueryBuilderSetupPanelContent = observer(
|
|
169
|
+
(props: { queryBuilderState: LegendQueryDataProductQueryBuilderState }) => {
|
|
170
|
+
const { queryBuilderState } = props;
|
|
171
|
+
const applicationStore = useApplicationStore();
|
|
172
|
+
const executionState = queryBuilderState.executionState;
|
|
173
|
+
|
|
174
|
+
// lakehouse runtime config modal
|
|
175
|
+
const showLakehouseConfigButton =
|
|
176
|
+
executionState instanceof ModelAccessPointDataProductExecutionState &&
|
|
177
|
+
executionState.selectedRuntime?.runtimeValue instanceof LakehouseRuntime;
|
|
178
|
+
const [isLakehouseConfigModalOpen, setIsLakehouseConfigModalOpen] =
|
|
179
|
+
useState(false);
|
|
180
|
+
|
|
181
|
+
// auto-select first class when none is chosen
|
|
182
|
+
const classes = queryBuilderState.usableClasses;
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
if (!queryBuilderState.class && classes[0]) {
|
|
185
|
+
queryBuilderState.changeClass(classes[0]);
|
|
186
|
+
}
|
|
187
|
+
}, [classes, queryBuilderState]);
|
|
188
|
+
|
|
189
|
+
const copyDataProductLinkToClipboard = (): void => {
|
|
190
|
+
if (queryBuilderState.isProductLinkable) {
|
|
191
|
+
queryBuilderState.copyDataProductLinkToClipBoard();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<div className="query-builder__setup__config-group">
|
|
197
|
+
<PanelHeader title="properties">
|
|
198
|
+
<PanelHeaderActions>
|
|
199
|
+
<PanelHeaderActionItem
|
|
200
|
+
title="copy data product query set up link to clipboard"
|
|
201
|
+
onClick={copyDataProductLinkToClipboard}
|
|
202
|
+
disabled={!queryBuilderState.isProductLinkable}
|
|
203
|
+
>
|
|
204
|
+
<AnchorLinkIcon />
|
|
205
|
+
</PanelHeaderActionItem>
|
|
206
|
+
{showLakehouseConfigButton && (
|
|
207
|
+
<ControlledDropdownMenu
|
|
208
|
+
className="panel__header__action query-builder__setup__config-group__header__dropdown-trigger"
|
|
209
|
+
title="Show Settings..."
|
|
210
|
+
content={
|
|
211
|
+
<MenuContent>
|
|
212
|
+
<MenuContentItem
|
|
213
|
+
onClick={() => setIsLakehouseConfigModalOpen(true)}
|
|
214
|
+
>
|
|
215
|
+
<MenuContentItemIcon>
|
|
216
|
+
<CogIcon />
|
|
217
|
+
</MenuContentItemIcon>
|
|
218
|
+
<MenuContentItemLabel>
|
|
219
|
+
Lakehouse Runtime Configuration
|
|
220
|
+
</MenuContentItemLabel>
|
|
221
|
+
</MenuContentItem>
|
|
222
|
+
</MenuContent>
|
|
223
|
+
}
|
|
224
|
+
menuProps={{
|
|
225
|
+
anchorOrigin: {
|
|
226
|
+
vertical: 'bottom',
|
|
227
|
+
horizontal: 'right',
|
|
228
|
+
},
|
|
229
|
+
transformOrigin: {
|
|
230
|
+
vertical: 'top',
|
|
231
|
+
horizontal: 'right',
|
|
232
|
+
},
|
|
233
|
+
}}
|
|
234
|
+
>
|
|
235
|
+
<MoreVerticalIcon className="query-builder__icon__more-options" />
|
|
236
|
+
</ControlledDropdownMenu>
|
|
237
|
+
)}
|
|
238
|
+
</PanelHeaderActions>
|
|
239
|
+
</PanelHeader>
|
|
240
|
+
<div className="query-builder__setup__config-group__content">
|
|
241
|
+
<DataProductQueryBuilderSetupFormContent
|
|
242
|
+
queryBuilderState={queryBuilderState}
|
|
243
|
+
/>
|
|
244
|
+
</div>
|
|
245
|
+
{executionState instanceof
|
|
246
|
+
ModelAccessPointDataProductExecutionState && (
|
|
247
|
+
<LakehouseRuntimeConfigModal
|
|
248
|
+
executionState={executionState}
|
|
249
|
+
open={isLakehouseConfigModalOpen}
|
|
250
|
+
onClose={() => setIsLakehouseConfigModalOpen(false)}
|
|
251
|
+
darkMode={
|
|
252
|
+
!applicationStore.layoutService
|
|
253
|
+
.TEMPORARY__isLightColorThemeEnabled
|
|
254
|
+
}
|
|
255
|
+
/>
|
|
256
|
+
)}
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
export const renderLegendDataProductQueryBuilderSetupPanelContent = (
|
|
263
|
+
queryBuilderState: LegendQueryDataProductQueryBuilderState,
|
|
264
|
+
): React.ReactNode => (
|
|
265
|
+
<LegendDataProductQueryBuilderSetupPanelContent
|
|
266
|
+
queryBuilderState={queryBuilderState}
|
|
267
|
+
/>
|
|
268
|
+
);
|