@finos/legend-extension-dsl-data-space 6.1.11 → 6.1.12

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 (70) hide show
  1. package/lib/DSLDataSpace_Const.d.ts +2 -0
  2. package/lib/DSLDataSpace_Const.d.ts.map +1 -1
  3. package/lib/DSLDataSpace_Const.js +2 -0
  4. package/lib/DSLDataSpace_Const.js.map +1 -1
  5. package/lib/components/DSLDataSpace_Icon.d.ts +18 -0
  6. package/lib/components/DSLDataSpace_Icon.d.ts.map +1 -0
  7. package/lib/components/DSLDataSpace_Icon.js +19 -0
  8. package/lib/components/DSLDataSpace_Icon.js.map +1 -0
  9. package/lib/components/query/DSLDataSpace_LegendQueryApplicationPlugin.d.ts +3 -2
  10. package/lib/components/query/DSLDataSpace_LegendQueryApplicationPlugin.d.ts.map +1 -1
  11. package/lib/components/query/DSLDataSpace_LegendQueryApplicationPlugin.js +99 -8
  12. package/lib/components/query/DSLDataSpace_LegendQueryApplicationPlugin.js.map +1 -1
  13. package/lib/components/query/DataSpaceQueryBuilder.d.ts +18 -0
  14. package/lib/components/query/DataSpaceQueryBuilder.d.ts.map +1 -0
  15. package/lib/components/query/DataSpaceQueryBuilder.js +126 -0
  16. package/lib/components/query/DataSpaceQueryBuilder.js.map +1 -0
  17. package/lib/components/query/{DataSpaceQueryEditor.d.ts → DataSpaceQueryCreator.d.ts} +2 -2
  18. package/lib/components/query/DataSpaceQueryCreator.d.ts.map +1 -0
  19. package/lib/components/query/{DataSpaceQueryEditor.js → DataSpaceQueryCreator.js} +11 -11
  20. package/lib/components/query/DataSpaceQueryCreator.js.map +1 -0
  21. package/lib/components/query/DataSpaceQuerySetup.d.ts.map +1 -1
  22. package/lib/components/query/DataSpaceQuerySetup.js +6 -8
  23. package/lib/components/query/DataSpaceQuerySetup.js.map +1 -1
  24. package/lib/components/studio/DSLDataSpace_LegendStudioApplicationPlugin.d.ts.map +1 -1
  25. package/lib/components/studio/DSLDataSpace_LegendStudioApplicationPlugin.js +2 -2
  26. package/lib/components/studio/DSLDataSpace_LegendStudioApplicationPlugin.js.map +1 -1
  27. package/lib/index.css +2 -2
  28. package/lib/index.css.map +1 -1
  29. package/lib/package.json +6 -6
  30. package/lib/stores/query/DSLDataSpace_LegendQueryRouter.d.ts +11 -8
  31. package/lib/stores/query/DSLDataSpace_LegendQueryRouter.d.ts.map +1 -1
  32. package/lib/stores/query/DSLDataSpace_LegendQueryRouter.js +15 -11
  33. package/lib/stores/query/DSLDataSpace_LegendQueryRouter.js.map +1 -1
  34. package/lib/stores/query/DataSpaceInfo.d.ts +31 -0
  35. package/lib/stores/query/DataSpaceInfo.d.ts.map +1 -0
  36. package/lib/stores/query/DataSpaceInfo.js +34 -0
  37. package/lib/stores/query/DataSpaceInfo.js.map +1 -0
  38. package/lib/stores/query/DataSpaceQueryBuilderState.d.ts +52 -0
  39. package/lib/stores/query/DataSpaceQueryBuilderState.d.ts.map +1 -0
  40. package/lib/stores/query/DataSpaceQueryBuilderState.js +112 -0
  41. package/lib/stores/query/DataSpaceQueryBuilderState.js.map +1 -0
  42. package/lib/stores/query/{DataSpaceQueryEditorStore.d.ts → DataSpaceQueryCreatorStore.d.ts} +6 -4
  43. package/lib/stores/query/DataSpaceQueryCreatorStore.d.ts.map +1 -0
  44. package/lib/stores/query/DataSpaceQueryCreatorStore.js +113 -0
  45. package/lib/stores/query/DataSpaceQueryCreatorStore.js.map +1 -0
  46. package/lib/stores/query/DataSpaceQuerySetupState.d.ts +5 -12
  47. package/lib/stores/query/DataSpaceQuerySetupState.d.ts.map +1 -1
  48. package/lib/stores/query/DataSpaceQuerySetupState.js +9 -19
  49. package/lib/stores/query/DataSpaceQuerySetupState.js.map +1 -1
  50. package/package.json +16 -16
  51. package/src/DSLDataSpace_Const.ts +3 -0
  52. package/src/components/DSLDataSpace_Icon.tsx +23 -0
  53. package/src/components/query/DSLDataSpace_LegendQueryApplicationPlugin.tsx +170 -8
  54. package/src/components/query/DataSpaceQueryBuilder.tsx +344 -0
  55. package/src/components/query/{DataSpaceQueryEditor.tsx → DataSpaceQueryCreator.tsx} +13 -13
  56. package/src/components/query/DataSpaceQuerySetup.tsx +10 -14
  57. package/src/components/studio/DSLDataSpace_LegendStudioApplicationPlugin.tsx +2 -6
  58. package/src/stores/query/DSLDataSpace_LegendQueryRouter.ts +17 -15
  59. package/src/stores/query/DataSpaceInfo.ts +57 -0
  60. package/src/stores/query/DataSpaceQueryBuilderState.ts +178 -0
  61. package/src/stores/query/DataSpaceQueryCreatorStore.ts +241 -0
  62. package/src/stores/query/DataSpaceQuerySetupState.ts +18 -32
  63. package/tsconfig.json +7 -3
  64. package/tsconfig.package.json +1 -1
  65. package/lib/components/query/DataSpaceQueryEditor.d.ts.map +0 -1
  66. package/lib/components/query/DataSpaceQueryEditor.js.map +0 -1
  67. package/lib/stores/query/DataSpaceQueryEditorStore.d.ts.map +0 -1
  68. package/lib/stores/query/DataSpaceQueryEditorStore.js +0 -98
  69. package/lib/stores/query/DataSpaceQueryEditorStore.js.map +0 -1
  70. package/src/stores/query/DataSpaceQueryEditorStore.ts +0 -173
@@ -0,0 +1,344 @@
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
+ CustomSelectorInput,
19
+ createFilter,
20
+ PURE_RuntimeIcon,
21
+ PlayIcon,
22
+ DropdownMenu,
23
+ MoreHorizontalIcon,
24
+ MenuContentItem,
25
+ MenuContent,
26
+ MenuContentItemIcon,
27
+ CheckIcon,
28
+ MenuContentItemLabel,
29
+ } from '@finos/legend-art';
30
+ import { observer } from 'mobx-react-lite';
31
+ import { useApplicationStore } from '@finos/legend-application';
32
+ import type { DataSpaceQueryBuilderState } from '../../stores/query/DataSpaceQueryBuilderState.js';
33
+ import {
34
+ buildRuntimeValueOption,
35
+ getRuntimeOptionFormatter,
36
+ QueryBuilderClassSelector,
37
+ } from '@finos/legend-application-query';
38
+ import {
39
+ type Runtime,
40
+ getMappingCompatibleClasses,
41
+ getMappingCompatibleRuntimes,
42
+ PackageableElementExplicitReference,
43
+ RuntimePointer,
44
+ } from '@finos/legend-graph';
45
+ import type { DataSpaceInfo } from '../../stores/query/DataSpaceInfo.js';
46
+ import { generateGAVCoordinates } from '@finos/legend-server-depot';
47
+ import { useEffect, useMemo, useState } from 'react';
48
+ import { debounce, guaranteeType } from '@finos/legend-shared';
49
+ import { flowResult } from 'mobx';
50
+ import type { DataSpaceExecutionContext } from '../../graph/metamodel/pure/model/packageableElements/dataSpace/DSLDataSpace_DataSpace.js';
51
+ import { DataSpaceIcon } from '../DSLDataSpace_Icon.js';
52
+
53
+ type DataSpaceOption = {
54
+ label: string;
55
+ value: DataSpaceInfo;
56
+ };
57
+ const buildDataSpaceOption = (value: DataSpaceInfo): DataSpaceOption => ({
58
+ label: value.title ?? value.name,
59
+ value,
60
+ });
61
+
62
+ type ExecutionContextOption = {
63
+ label: string;
64
+ value: DataSpaceExecutionContext;
65
+ };
66
+ const buildExecutionContextOption = (
67
+ value: DataSpaceExecutionContext,
68
+ ): ExecutionContextOption => ({
69
+ label: value.name,
70
+ value,
71
+ });
72
+
73
+ /**
74
+ * This setup panel supports cascading in order: Data-space -> Execution context (-> Runtime) -> Class
75
+ *
76
+ * In other words, we will only show:
77
+ * - For runtime selector: the list of compatible runtimes with the selected execution context mapping
78
+ * - For class selector: the list of compatible class with the selected execution context mapping
79
+ *
80
+ * See details on propagation/cascading in {@link DataSpaceQueryBuilderState}
81
+ */
82
+ const DataSpaceQueryBuilderSetupPanelContent = observer(
83
+ (props: { queryBuilderState: DataSpaceQueryBuilderState }) => {
84
+ const { queryBuilderState } = props;
85
+ const applicationStore = useApplicationStore();
86
+ const [dataSpaceSearchText, setDataSpaceSearchText] = useState('');
87
+
88
+ // data space
89
+ const dataSpaceOptions =
90
+ queryBuilderState.dataSpaces.map(buildDataSpaceOption);
91
+ const selectedDataSpaceOption: DataSpaceOption = {
92
+ label:
93
+ queryBuilderState.dataSpace.title ?? queryBuilderState.dataSpace.name,
94
+ value: {
95
+ groupId: queryBuilderState.groupId,
96
+ artifactId: queryBuilderState.artifactId,
97
+ versionId: queryBuilderState.versionId,
98
+ title: queryBuilderState.dataSpace.title,
99
+ name: queryBuilderState.dataSpace.name,
100
+ path: queryBuilderState.dataSpace.path,
101
+ defaultExecutionContext:
102
+ queryBuilderState.dataSpace.defaultExecutionContext.name,
103
+ },
104
+ };
105
+ const onDataSpaceOptionChange = (option: DataSpaceOption): void => {
106
+ queryBuilderState.onDataSpaceChange(option.value);
107
+ };
108
+ const dataSpaceFilterOption = createFilter({
109
+ ignoreCase: true,
110
+ ignoreAccents: false,
111
+ stringify: (option: DataSpaceOption): string =>
112
+ `${option.label} - ${option.value.path}`,
113
+ });
114
+ const formatDataSpaceOptionLabel = (
115
+ option: DataSpaceOption,
116
+ ): React.ReactNode => (
117
+ <div
118
+ className="query-builder__setup__data-space__option"
119
+ title={`${option.label} - ${
120
+ option.value.path
121
+ } - ${generateGAVCoordinates(
122
+ option.value.groupId,
123
+ option.value.artifactId,
124
+ option.value.versionId,
125
+ )}`}
126
+ >
127
+ <div className="query-builder__setup__data-space__option__label">
128
+ {option.label}
129
+ </div>
130
+ <div className="query-builder__setup__data-space__option__path">
131
+ {option.value.path}
132
+ </div>
133
+ <div className="query-builder__setup__data-space__option__gav">
134
+ {generateGAVCoordinates(
135
+ option.value.groupId,
136
+ option.value.artifactId,
137
+ option.value.versionId,
138
+ )}
139
+ </div>
140
+ </div>
141
+ );
142
+
143
+ // data space search text
144
+ const debouncedLoadDataSpaces = useMemo(
145
+ () =>
146
+ debounce((input: string): void => {
147
+ flowResult(queryBuilderState.loadDataSpaces(input)).catch(
148
+ applicationStore.alertUnhandledError,
149
+ );
150
+ }, 500),
151
+ [applicationStore, queryBuilderState],
152
+ );
153
+ const onDataSpaceSearchTextChange = (value: string): void => {
154
+ if (value !== dataSpaceSearchText) {
155
+ setDataSpaceSearchText(value);
156
+ debouncedLoadDataSpaces.cancel();
157
+ debouncedLoadDataSpaces(value);
158
+ }
159
+ };
160
+
161
+ // execution context
162
+ const executionContextOptions =
163
+ queryBuilderState.dataSpace.executionContexts.map(
164
+ buildExecutionContextOption,
165
+ );
166
+ const selectedExecutionContextOption = buildExecutionContextOption(
167
+ queryBuilderState.executionContext,
168
+ );
169
+ const onExecutionContextOptionChange = (
170
+ option: ExecutionContextOption,
171
+ ): void => {
172
+ if (option.value === queryBuilderState.executionContext) {
173
+ return;
174
+ }
175
+ queryBuilderState.setExecutionContext(option.value);
176
+ queryBuilderState.propagateExecutionContextChange(option.value);
177
+ queryBuilderState.onExecutionContextChange?.(option.value);
178
+ };
179
+
180
+ // runtime
181
+ const runtimeOptions = getMappingCompatibleRuntimes(
182
+ queryBuilderState.executionContext.mapping.value,
183
+ queryBuilderState.graphManagerState.usableRuntimes,
184
+ )
185
+ .map(
186
+ (rt) =>
187
+ new RuntimePointer(PackageableElementExplicitReference.create(rt)),
188
+ )
189
+ .map(buildRuntimeValueOption);
190
+ const selectedRuntimeOption = queryBuilderState.runtimeValue
191
+ ? buildRuntimeValueOption(queryBuilderState.runtimeValue)
192
+ : null;
193
+ const changeRuntime = (option: { value: Runtime }): void => {
194
+ if (option.value === queryBuilderState.runtimeValue) {
195
+ return;
196
+ }
197
+ queryBuilderState.changeRuntime(option.value);
198
+ queryBuilderState.onRuntimeChange?.(option.value);
199
+ };
200
+ const runtimeFilterOption = createFilter({
201
+ ignoreCase: true,
202
+ ignoreAccents: false,
203
+ stringify: (option: { value: Runtime }): string =>
204
+ guaranteeType(option.value, RuntimePointer).packageableRuntime.value
205
+ .path,
206
+ });
207
+
208
+ // class
209
+ const classes = getMappingCompatibleClasses(
210
+ queryBuilderState.executionContext.mapping.value,
211
+ queryBuilderState.graphManagerState.usableClasses,
212
+ );
213
+
214
+ useEffect(() => {
215
+ flowResult(queryBuilderState.loadDataSpaces('')).catch(
216
+ applicationStore.alertUnhandledError,
217
+ );
218
+ }, [queryBuilderState, applicationStore]);
219
+
220
+ return (
221
+ <>
222
+ <div className="query-builder__setup__config-group">
223
+ <div className="query-builder__setup__config-group__header">
224
+ <div className="query-builder__setup__config-group__header__title">
225
+ data space execution context
226
+ </div>
227
+ <DropdownMenu
228
+ className="query-builder__setup__config-group__header__dropdown"
229
+ content={
230
+ <MenuContent>
231
+ <MenuContentItem
232
+ onClick={(): void =>
233
+ queryBuilderState.setShowRuntimeSelector(
234
+ !queryBuilderState.showRuntimeSelector,
235
+ )
236
+ }
237
+ >
238
+ <MenuContentItemIcon>
239
+ {queryBuilderState.showRuntimeSelector ? (
240
+ <CheckIcon />
241
+ ) : null}
242
+ </MenuContentItemIcon>
243
+ <MenuContentItemLabel>
244
+ Show Runtime Selector
245
+ </MenuContentItemLabel>
246
+ </MenuContentItem>
247
+ </MenuContent>
248
+ }
249
+ menuProps={{
250
+ anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
251
+ transformOrigin: { vertical: 'top', horizontal: 'right' },
252
+ }}
253
+ >
254
+ <button
255
+ className="query-builder__setup__config-group__header__dropdown-trigger"
256
+ title="Show Settings..."
257
+ >
258
+ <MoreHorizontalIcon />
259
+ </button>
260
+ </DropdownMenu>
261
+ </div>
262
+ <div className="query-builder__setup__config-group__content">
263
+ <div className="query-builder__setup__config-group__item">
264
+ <div
265
+ className="btn--sm query-builder__setup__config-group__item__label"
266
+ title="data space"
267
+ >
268
+ <DataSpaceIcon />
269
+ </div>
270
+ <CustomSelectorInput
271
+ className="panel__content__form__section__dropdown query-builder__setup__config-group__item__selector"
272
+ options={dataSpaceOptions}
273
+ isLoading={queryBuilderState.loadDataSpacesState.isInProgress}
274
+ onInputChange={onDataSpaceSearchTextChange}
275
+ inputValue={dataSpaceSearchText}
276
+ onChange={onDataSpaceOptionChange}
277
+ value={selectedDataSpaceOption}
278
+ placeholder="Search for data space by name..."
279
+ escapeClearsValue={true}
280
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
281
+ filterOption={dataSpaceFilterOption}
282
+ formatOptionLabel={formatDataSpaceOptionLabel}
283
+ />
284
+ </div>
285
+ <div className="query-builder__setup__config-group__item">
286
+ <div
287
+ className="btn--sm query-builder__setup__config-group__item__label"
288
+ title="execution context"
289
+ >
290
+ <PlayIcon className="query-builder__setup__data-space__icon__execution-context" />
291
+ </div>
292
+ <CustomSelectorInput
293
+ className="panel__content__form__section__dropdown query-builder__setup__config-group__item__selector"
294
+ placeholder="Choose an execution context..."
295
+ options={executionContextOptions}
296
+ disabled={executionContextOptions.length <= 1}
297
+ onChange={onExecutionContextOptionChange}
298
+ value={selectedExecutionContextOption}
299
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
300
+ />
301
+ </div>
302
+ {queryBuilderState.showRuntimeSelector && (
303
+ <div className="query-builder__setup__config-group__item">
304
+ <div
305
+ className="btn--sm query-builder__setup__config-group__item__label"
306
+ title="runtime"
307
+ >
308
+ <PURE_RuntimeIcon />
309
+ </div>
310
+ <CustomSelectorInput
311
+ className="panel__content__form__section__dropdown query-builder__setup__config-group__item__selector"
312
+ placeholder="Choose a runtime..."
313
+ noMatchMessage="No compatible runtime found for specified execution context"
314
+ options={runtimeOptions}
315
+ onChange={changeRuntime}
316
+ value={selectedRuntimeOption}
317
+ darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
318
+ filterOption={runtimeFilterOption}
319
+ formatOptionLabel={getRuntimeOptionFormatter({
320
+ darkMode: !applicationStore.TEMPORARY__isLightThemeEnabled,
321
+ })}
322
+ />
323
+ </div>
324
+ )}
325
+ </div>
326
+ </div>
327
+ <QueryBuilderClassSelector
328
+ queryBuilderState={queryBuilderState}
329
+ classes={classes}
330
+ onClassChange={queryBuilderState.onClassChange}
331
+ noMatchMessage="No compatible class found for specified execution context"
332
+ />
333
+ </>
334
+ );
335
+ },
336
+ );
337
+
338
+ export const renderDataSpaceQueryBuilderSetupPanelContent = (
339
+ queryBuilderState: DataSpaceQueryBuilderState,
340
+ ): React.ReactNode => (
341
+ <DataSpaceQueryBuilderSetupPanelContent
342
+ queryBuilderState={queryBuilderState}
343
+ />
344
+ );
@@ -23,21 +23,21 @@ import {
23
23
  } from '@finos/legend-server-depot';
24
24
  import {
25
25
  LEGEND_QUERY_PATH_PARAM_TOKEN,
26
- LEGEND_QUERY_QUERY_PARAM_TOKEN,
27
26
  QueryEditor,
28
27
  QueryEditorStoreContext,
29
28
  useLegendQueryApplicationStore,
30
29
  useLegendQueryBaseStore,
31
30
  } from '@finos/legend-application-query';
32
31
  import { useParams } from 'react-router';
33
- import { DataSpaceQueryEditorStore } from '../../stores/query/DataSpaceQueryEditorStore.js';
32
+ import { DataSpaceQueryCreatorStore } from '../../stores/query/DataSpaceQueryCreatorStore.js';
34
33
  import {
35
- type DataSpaceQueryEditorPathParams,
34
+ type DataSpaceQueryCreatorPathParams,
36
35
  type DataSpaceQueryEditorQueryParams,
37
- DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN,
36
+ DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN,
37
+ DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN,
38
38
  } from '../../stores/query/DSLDataSpace_LegendQueryRouter.js';
39
39
 
40
- const DataSpaceQueryEditorStoreProvider: React.FC<{
40
+ const DataSpaceQueryCreatorStoreProvider: React.FC<{
41
41
  children: React.ReactNode;
42
42
  gav: string;
43
43
  dataSpacePath: string;
@@ -58,7 +58,7 @@ const DataSpaceQueryEditorStoreProvider: React.FC<{
58
58
  const baseStore = useLegendQueryBaseStore();
59
59
  const store = useLocalObservable(
60
60
  () =>
61
- new DataSpaceQueryEditorStore(
61
+ new DataSpaceQueryCreatorStore(
62
62
  applicationStore,
63
63
  depotServerClient,
64
64
  baseStore.pluginManager,
@@ -78,22 +78,22 @@ const DataSpaceQueryEditorStoreProvider: React.FC<{
78
78
  );
79
79
  };
80
80
 
81
- export const DataSpaceQueryEditor = observer(() => {
81
+ export const DataSpaceQueryCreator = observer(() => {
82
82
  const applicationStore = useApplicationStore();
83
- const params = useParams<DataSpaceQueryEditorPathParams>();
83
+ const params = useParams<DataSpaceQueryCreatorPathParams>();
84
84
  const gav = params[LEGEND_QUERY_PATH_PARAM_TOKEN.GAV];
85
85
  const dataSpacePath =
86
- params[DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH];
86
+ params[DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH];
87
87
  const executionContext =
88
- params[DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT];
88
+ params[DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT];
89
89
  const runtimePath = params[LEGEND_QUERY_PATH_PARAM_TOKEN.RUNTIME_PATH];
90
90
  const classPath = getQueryParameters<DataSpaceQueryEditorQueryParams>(
91
91
  applicationStore.navigator.getCurrentLocation(),
92
92
  true,
93
- )[LEGEND_QUERY_QUERY_PARAM_TOKEN.CLASS_PATH];
93
+ )[DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN.CLASS_PATH];
94
94
 
95
95
  return (
96
- <DataSpaceQueryEditorStoreProvider
96
+ <DataSpaceQueryCreatorStoreProvider
97
97
  gav={gav}
98
98
  dataSpacePath={dataSpacePath}
99
99
  executionContext={executionContext}
@@ -101,6 +101,6 @@ export const DataSpaceQueryEditor = observer(() => {
101
101
  classPath={classPath}
102
102
  >
103
103
  <QueryEditor />
104
- </DataSpaceQueryEditorStoreProvider>
104
+ </DataSpaceQueryCreatorStoreProvider>
105
105
  );
106
106
  });
@@ -34,16 +34,14 @@ import { debounce } from '@finos/legend-shared';
34
34
  import { flowResult } from 'mobx';
35
35
  import { observer } from 'mobx-react-lite';
36
36
  import { useEffect, useMemo, useRef, useState } from 'react';
37
- import type {
38
- DataSpaceQuerySetupState,
39
- DataSpaceContext,
40
- } from '../../stores/query/DataSpaceQuerySetupState.js';
37
+ import type { DataSpaceQuerySetupState } from '../../stores/query/DataSpaceQuerySetupState.js';
41
38
  import { DataSpaceViewer } from '../DataSpaceViewer.js';
39
+ import type { DataSpaceInfo } from '../../stores/query/DataSpaceInfo.js';
42
40
 
43
- type DataSpaceOption = { label: string; value: DataSpaceContext };
44
- const buildDataSpaceOption = (value: DataSpaceContext): DataSpaceOption => ({
41
+ type DataSpaceOption = { label: string; value: DataSpaceInfo };
42
+ const buildDataSpaceOption = (value: DataSpaceInfo): DataSpaceOption => ({
45
43
  label: value.title ?? value.name,
46
- value: value,
44
+ value,
47
45
  });
48
46
 
49
47
  export const DataspaceQuerySetup = observer(
@@ -75,17 +73,15 @@ export const DataspaceQuerySetup = observer(
75
73
  querySetupState.setCurrentDataSpace(undefined);
76
74
  };
77
75
 
78
- // query
76
+ // data space
79
77
  const dataSpaceOptions =
80
78
  querySetupState.dataSpaces.map(buildDataSpaceOption);
81
79
  const selectedDataSpaceOption = querySetupState.currentDataSpace
82
80
  ? buildDataSpaceOption(querySetupState.currentDataSpace)
83
81
  : null;
84
82
  const onDataSpaceOptionChange = (option: DataSpaceOption | null): void => {
85
- if (option?.value !== querySetupState.currentDataSpace) {
86
- querySetupState.setCurrentDataSpace(option?.value);
87
- querySetupState.setDataSpaceViewerState(undefined);
88
- }
83
+ querySetupState.setCurrentDataSpace(option?.value);
84
+ querySetupState.setDataSpaceViewerState(undefined);
89
85
  };
90
86
  const filterOption = createFilter({
91
87
  ignoreCase: true,
@@ -93,7 +89,7 @@ export const DataspaceQuerySetup = observer(
93
89
  stringify: (option: DataSpaceOption): string =>
94
90
  `${option.label} - ${option.value.path}`,
95
91
  });
96
- const formatQueryOptionLabel = (
92
+ const formatDataSpaceOptionLabel = (
97
93
  option: DataSpaceOption,
98
94
  ): React.ReactNode => (
99
95
  <div
@@ -201,7 +197,7 @@ export const DataspaceQuerySetup = observer(
201
197
  escapeClearsValue={true}
202
198
  darkMode={true}
203
199
  filterOption={filterOption}
204
- formatOptionLabel={formatQueryOptionLabel}
200
+ formatOptionLabel={formatDataSpaceOptionLabel}
205
201
  />
206
202
  <button
207
203
  className={clsx('query-setup__data-space__use-snapshot-btn', {
@@ -33,7 +33,6 @@ import {
33
33
  UnsupportedElementEditorState,
34
34
  LegendStudioApplicationPlugin,
35
35
  } from '@finos/legend-application-studio';
36
- import { SquareIcon } from '@finos/legend-art';
37
36
  import {
38
37
  PackageableElementExplicitReference,
39
38
  stub_Mapping,
@@ -51,6 +50,7 @@ import {
51
50
  } from '../../graphManager/DSLDataSpace_PureGraphManagerPlugin.js';
52
51
  import { SIMPLE_DATA_SPACE_SNIPPET } from './DSLDataSpace_CodeSnippets.js';
53
52
  import type { DocumentationEntry } from '@finos/legend-application';
53
+ import { DataSpaceIcon } from '../DSLDataSpace_Icon.js';
54
54
 
55
55
  const DATA_SPACE_ELEMENT_TYPE = 'DATA SPACE';
56
56
  const DATA_SPACE_ELEMENT_PROJECT_EXPLORER_DND_TYPE =
@@ -90,11 +90,7 @@ export class DSLDataSpace_LegendStudioApplicationPlugin
90
90
  return [
91
91
  (type: string): React.ReactNode | undefined => {
92
92
  if (type === DATA_SPACE_ELEMENT_TYPE) {
93
- return (
94
- <div className="icon icon--data-space">
95
- <SquareIcon />
96
- </div>
97
- );
93
+ return <DataSpaceIcon />;
98
94
  }
99
95
  return undefined;
100
96
  },
@@ -15,32 +15,33 @@
15
15
  */
16
16
 
17
17
  import { generateExtensionUrlPattern } from '@finos/legend-application';
18
- import {
19
- LEGEND_QUERY_PATH_PARAM_TOKEN,
20
- LEGEND_QUERY_QUERY_PARAM_TOKEN,
21
- } from '@finos/legend-application-query';
18
+ import { LEGEND_QUERY_PATH_PARAM_TOKEN } from '@finos/legend-application-query';
22
19
  import { generateGAVCoordinates } from '@finos/legend-server-depot';
23
20
  import { generatePath } from 'react-router';
24
21
 
25
- export enum DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN {
22
+ export enum DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN {
26
23
  DATA_SPACE_PATH = 'dataSpacePath',
27
24
  EXECUTION_CONTEXT = 'executionContext',
28
25
  }
29
26
 
30
- export interface DataSpaceQueryEditorPathParams {
27
+ export enum DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN {
28
+ CLASS_PATH = 'class',
29
+ }
30
+
31
+ export interface DataSpaceQueryCreatorPathParams {
31
32
  [LEGEND_QUERY_PATH_PARAM_TOKEN.GAV]: string;
32
- [DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH]: string;
33
- [DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT]: string;
33
+ [DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH]: string;
34
+ [DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT]: string;
34
35
  [LEGEND_QUERY_PATH_PARAM_TOKEN.RUNTIME_PATH]?: string;
35
36
  }
36
37
 
37
38
  export interface DataSpaceQueryEditorQueryParams {
38
- [LEGEND_QUERY_QUERY_PARAM_TOKEN.CLASS_PATH]?: string;
39
+ [DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN.CLASS_PATH]?: string;
39
40
  }
40
41
 
41
- export const DATA_SPACE_QUERY_EDITOR_ROUTE_PATTERN = `/dataspace/:${LEGEND_QUERY_PATH_PARAM_TOKEN.GAV}/:${DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH}/:${DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT}/:${LEGEND_QUERY_PATH_PARAM_TOKEN.RUNTIME_PATH}?`;
42
+ export const CREATE_QUERY_FROM_DATA_SPACE_ROUTE_PATTERN = `/create-from-dataspace/:${LEGEND_QUERY_PATH_PARAM_TOKEN.GAV}/:${DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH}/:${DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT}/:${LEGEND_QUERY_PATH_PARAM_TOKEN.RUNTIME_PATH}?`;
42
43
 
43
- export const generateDataSpaceQueryEditorRoute = (
44
+ export const generateDataSpaceQueryCreatorRoute = (
44
45
  groupId: string,
45
46
  artifactId: string,
46
47
  versionId: string,
@@ -50,20 +51,21 @@ export const generateDataSpaceQueryEditorRoute = (
50
51
  classPath?: string | undefined,
51
52
  ): string =>
52
53
  `${generatePath(
53
- generateExtensionUrlPattern(DATA_SPACE_QUERY_EDITOR_ROUTE_PATTERN),
54
+ generateExtensionUrlPattern(CREATE_QUERY_FROM_DATA_SPACE_ROUTE_PATTERN),
54
55
  {
55
56
  [LEGEND_QUERY_PATH_PARAM_TOKEN.GAV]: generateGAVCoordinates(
56
57
  groupId,
57
58
  artifactId,
58
59
  versionId,
59
60
  ),
60
- [DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH]: dataSpacePath,
61
- [DATA_SPACE_QUERY_EDITOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT]:
61
+ [DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.DATA_SPACE_PATH]:
62
+ dataSpacePath,
63
+ [DATA_SPACE_QUERY_CREATOR_PATH_PARAM_TOKEN.EXECUTION_CONTEXT]:
62
64
  executionContextKey,
63
65
  [LEGEND_QUERY_PATH_PARAM_TOKEN.RUNTIME_PATH]: runtimePath,
64
66
  },
65
67
  )}${
66
68
  classPath
67
- ? `?${LEGEND_QUERY_QUERY_PARAM_TOKEN.CLASS_PATH}=${classPath}`
69
+ ? `?${DATA_SPACE_QUERY_CREATOR_QUERY_PARAM_TOKEN.CLASS_PATH}=${classPath}`
68
70
  : ''
69
71
  }`;
@@ -0,0 +1,57 @@
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
+ SNAPSHOT_VERSION_ALIAS,
19
+ type StoredEntity,
20
+ } from '@finos/legend-server-depot';
21
+ import { isString } from '@finos/legend-shared';
22
+ import { extractEntityNameFromPath } from '@finos/legend-storage';
23
+
24
+ export interface DataSpaceInfo {
25
+ groupId: string;
26
+ artifactId: string;
27
+ versionId: string;
28
+ title: string | undefined;
29
+ name: string;
30
+ path: string;
31
+ /**
32
+ * NOTE: technically, this should be always available, but we must not
33
+ * assume that no dataspace is marlformed, so we leave it as optional
34
+ */
35
+ defaultExecutionContext: string | undefined;
36
+ }
37
+
38
+ export const extractDataSpaceInfo = (
39
+ storedEntity: StoredEntity,
40
+ isSnapshot: boolean,
41
+ ): DataSpaceInfo => ({
42
+ groupId: storedEntity.groupId,
43
+ artifactId: storedEntity.artifactId,
44
+ versionId: isSnapshot ? SNAPSHOT_VERSION_ALIAS : storedEntity.versionId,
45
+ path: storedEntity.entity.path,
46
+ name: extractEntityNameFromPath(storedEntity.entity.path),
47
+ title: isString(storedEntity.entity.content.title)
48
+ ? storedEntity.entity.content.title
49
+ : undefined,
50
+ // NOTE: we don't want to assert the existence of this field even when it
51
+ // is required in the specification of data space, so we don't throw error here
52
+ defaultExecutionContext: isString(
53
+ storedEntity.entity.content.defaultExecutionContext,
54
+ )
55
+ ? storedEntity.entity.content.defaultExecutionContext
56
+ : undefined,
57
+ });