@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.
Files changed (111) hide show
  1. package/lib/__lib__/LegendQueryNavigation.d.ts +16 -10
  2. package/lib/__lib__/LegendQueryNavigation.d.ts.map +1 -1
  3. package/lib/__lib__/LegendQueryNavigation.js +17 -12
  4. package/lib/__lib__/LegendQueryNavigation.js.map +1 -1
  5. package/lib/__lib__/LegendQueryUserDataHelper.d.ts +25 -7
  6. package/lib/__lib__/LegendQueryUserDataHelper.d.ts.map +1 -1
  7. package/lib/__lib__/LegendQueryUserDataHelper.js +81 -6
  8. package/lib/__lib__/LegendQueryUserDataHelper.js.map +1 -1
  9. package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts +21 -4
  10. package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts.map +1 -1
  11. package/lib/__lib__/LegendQueryUserDataSpaceHelper.js +17 -0
  12. package/lib/__lib__/LegendQueryUserDataSpaceHelper.js.map +1 -1
  13. package/lib/application/LegendQueryApplicationConfig.d.ts +10 -0
  14. package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
  15. package/lib/application/LegendQueryApplicationConfig.js +16 -0
  16. package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
  17. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
  18. package/lib/components/Core_LegendQueryApplicationPlugin.js +7 -3
  19. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
  20. package/lib/components/LegendQueryWebApplication.d.ts.map +1 -1
  21. package/lib/components/LegendQueryWebApplication.js +2 -2
  22. package/lib/components/LegendQueryWebApplication.js.map +1 -1
  23. package/lib/components/QueryEditor.d.ts.map +1 -1
  24. package/lib/components/QueryEditor.js +5 -2
  25. package/lib/components/QueryEditor.js.map +1 -1
  26. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts +8 -0
  27. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts.map +1 -1
  28. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js +190 -8
  29. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js.map +1 -1
  30. package/lib/components/data-product/DataProductInfo.d.ts +28 -0
  31. package/lib/components/data-product/DataProductInfo.d.ts.map +1 -0
  32. package/lib/components/data-product/DataProductInfo.js +89 -0
  33. package/lib/components/data-product/DataProductInfo.js.map +1 -0
  34. package/lib/components/{data-space/DataSpaceQueryCreator.d.ts → data-product/LegendQueryDataProductQueryBuilder.d.ts} +3 -4
  35. package/lib/components/data-product/LegendQueryDataProductQueryBuilder.d.ts.map +1 -0
  36. package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js +98 -0
  37. package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js.map +1 -0
  38. package/lib/components/data-space/DataProductQueryCreator.d.ts +36 -0
  39. package/lib/components/data-space/DataProductQueryCreator.d.ts.map +1 -0
  40. package/lib/components/data-space/DataProductQueryCreator.js +76 -0
  41. package/lib/components/data-space/DataProductQueryCreator.js.map +1 -0
  42. package/lib/index.css +1 -1
  43. package/lib/index.d.ts +1 -1
  44. package/lib/index.d.ts.map +1 -1
  45. package/lib/index.js +1 -1
  46. package/lib/index.js.map +1 -1
  47. package/lib/light-mode.css +1 -1
  48. package/lib/package.json +2 -1
  49. package/lib/stores/QueryEditorStore.d.ts +46 -2
  50. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  51. package/lib/stores/QueryEditorStore.js +251 -5
  52. package/lib/stores/QueryEditorStore.js.map +1 -1
  53. package/lib/stores/data-product/query-builder/DataProductArtifactHelper.d.ts +21 -0
  54. package/lib/stores/data-product/query-builder/DataProductArtifactHelper.d.ts.map +1 -0
  55. package/lib/stores/data-product/query-builder/DataProductArtifactHelper.js +35 -0
  56. package/lib/stores/data-product/query-builder/DataProductArtifactHelper.js.map +1 -0
  57. package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.d.ts +11 -3
  58. package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.d.ts.map +1 -1
  59. package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js +50 -8
  60. package/lib/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js.map +1 -1
  61. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts +94 -0
  62. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts.map +1 -0
  63. package/lib/stores/data-space/DataProductQueryCreatorStore.js +388 -0
  64. package/lib/stores/data-space/DataProductQueryCreatorStore.js.map +1 -0
  65. package/lib/stores/data-space/DataProductSelectorState.d.ts +44 -0
  66. package/lib/stores/data-space/DataProductSelectorState.d.ts.map +1 -0
  67. package/lib/stores/data-space/DataProductSelectorState.js +111 -0
  68. package/lib/stores/data-space/DataProductSelectorState.js.map +1 -0
  69. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  70. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +3 -0
  71. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  72. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts +1 -1
  73. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts.map +1 -1
  74. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js +1 -1
  75. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js.map +1 -1
  76. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.d.ts +4 -3
  77. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.d.ts.map +1 -1
  78. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js +24 -29
  79. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js.map +1 -1
  80. package/package.json +8 -7
  81. package/src/__lib__/LegendQueryNavigation.ts +76 -18
  82. package/src/__lib__/LegendQueryUserDataHelper.ts +177 -12
  83. package/src/__lib__/LegendQueryUserDataSpaceHelper.ts +54 -4
  84. package/src/application/LegendQueryApplicationConfig.ts +31 -0
  85. package/src/components/Core_LegendQueryApplicationPlugin.tsx +8 -2
  86. package/src/components/LegendQueryWebApplication.tsx +8 -4
  87. package/src/components/QueryEditor.tsx +13 -0
  88. package/src/components/__test-utils__/QueryEditorComponentTestUtils.tsx +418 -5
  89. package/src/components/data-product/DataProductInfo.tsx +297 -0
  90. package/src/components/data-product/LegendQueryDataProductQueryBuilder.tsx +268 -0
  91. package/src/components/data-space/DataProductQueryCreator.tsx +167 -0
  92. package/src/components/data-space/DataSpaceQuerySetup.tsx +1 -1
  93. package/src/index.ts +6 -0
  94. package/src/stores/QueryEditorStore.ts +485 -2
  95. package/src/stores/data-product/query-builder/DataProductArtifactHelper.ts +48 -0
  96. package/src/stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.ts +77 -16
  97. package/src/stores/data-space/DataProductQueryCreatorStore.ts +765 -0
  98. package/src/stores/data-space/DataProductSelectorState.ts +164 -0
  99. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +10 -0
  100. package/src/stores/data-space/LegendQueryBareQueryBuilderState.ts +1 -1
  101. package/src/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.ts +27 -54
  102. package/tsconfig.json +6 -2
  103. package/lib/components/data-space/DataSpaceQueryCreator.d.ts.map +0 -1
  104. package/lib/components/data-space/DataSpaceQueryCreator.js +0 -62
  105. package/lib/components/data-space/DataSpaceQueryCreator.js.map +0 -1
  106. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts +0 -92
  107. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +0 -1
  108. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +0 -400
  109. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +0 -1
  110. package/src/components/data-space/DataSpaceQueryCreator.tsx +0 -119
  111. 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
+ );