@finos/legend-extension-dsl-data-space-studio 0.1.152 → 0.1.154

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 (75) hide show
  1. package/lib/components/DSL_DataProduct_ElementDriver.d.ts +27 -0
  2. package/lib/components/DSL_DataProduct_ElementDriver.d.ts.map +1 -0
  3. package/lib/components/DSL_DataProduct_ElementDriver.js +60 -0
  4. package/lib/components/DSL_DataProduct_ElementDriver.js.map +1 -0
  5. package/lib/components/DSL_DataSpace_LegendStudioApplicationPlugin.d.ts +3 -1
  6. package/lib/components/DSL_DataSpace_LegendStudioApplicationPlugin.d.ts.map +1 -1
  7. package/lib/components/DSL_DataSpace_LegendStudioApplicationPlugin.js +30 -15
  8. package/lib/components/DSL_DataSpace_LegendStudioApplicationPlugin.js.map +1 -1
  9. package/lib/components/DSL_NewDataProductEditor.d.ts +19 -0
  10. package/lib/components/DSL_NewDataProductEditor.d.ts.map +1 -0
  11. package/lib/components/DSL_NewDataProductEditor.js +32 -0
  12. package/lib/components/DSL_NewDataProductEditor.js.map +1 -0
  13. package/lib/components/DataSpaceEditor.d.ts +1 -1
  14. package/lib/components/DataSpaceEditor.d.ts.map +1 -1
  15. package/lib/components/DataSpaceEditor.js +18 -9
  16. package/lib/components/DataSpaceEditor.js.map +1 -1
  17. package/lib/components/DataSpaceExecutionContextEditor.d.ts +37 -0
  18. package/lib/components/DataSpaceExecutionContextEditor.d.ts.map +1 -0
  19. package/lib/components/DataSpaceExecutionContextEditor.js +170 -0
  20. package/lib/components/DataSpaceExecutionContextEditor.js.map +1 -0
  21. package/lib/components/DataSpaceGeneralEditor/DataSpaceDefaultExecutionContextSection.d.ts +19 -0
  22. package/lib/components/DataSpaceGeneralEditor/DataSpaceDefaultExecutionContextSection.d.ts.map +1 -0
  23. package/lib/components/DataSpaceGeneralEditor/DataSpaceDefaultExecutionContextSection.js +138 -0
  24. package/lib/components/DataSpaceGeneralEditor/DataSpaceDefaultExecutionContextSection.js.map +1 -0
  25. package/lib/components/DataSpaceGeneralEditor/DataSpaceDiagramsSection.d.ts +19 -0
  26. package/lib/components/DataSpaceGeneralEditor/DataSpaceDiagramsSection.d.ts.map +1 -0
  27. package/lib/components/DataSpaceGeneralEditor/DataSpaceDiagramsSection.js +63 -0
  28. package/lib/components/DataSpaceGeneralEditor/DataSpaceDiagramsSection.js.map +1 -0
  29. package/lib/components/DataSpaceGeneralEditor/DataSpaceElementsSection.d.ts +19 -0
  30. package/lib/components/DataSpaceGeneralEditor/DataSpaceElementsSection.d.ts.map +1 -0
  31. package/lib/components/DataSpaceGeneralEditor/DataSpaceElementsSection.js +58 -0
  32. package/lib/components/DataSpaceGeneralEditor/DataSpaceElementsSection.js.map +1 -0
  33. package/lib/components/DataSpaceGeneralEditor/DataSpaceExecutablesSection.d.ts +19 -0
  34. package/lib/components/DataSpaceGeneralEditor/DataSpaceExecutablesSection.d.ts.map +1 -0
  35. package/lib/components/DataSpaceGeneralEditor/DataSpaceExecutablesSection.js +56 -0
  36. package/lib/components/DataSpaceGeneralEditor/DataSpaceExecutablesSection.js.map +1 -0
  37. package/lib/components/DataSpaceGeneralEditor/DataSpaceGeneralEditor.d.ts +19 -0
  38. package/lib/components/DataSpaceGeneralEditor/DataSpaceGeneralEditor.d.ts.map +1 -0
  39. package/lib/components/DataSpaceGeneralEditor/DataSpaceGeneralEditor.js +40 -0
  40. package/lib/components/DataSpaceGeneralEditor/DataSpaceGeneralEditor.js.map +1 -0
  41. package/lib/components/DataSpaceGeneralEditor/DataSpaceSupportInfoSection.d.ts +19 -0
  42. package/lib/components/DataSpaceGeneralEditor/DataSpaceSupportInfoSection.d.ts.map +1 -0
  43. package/lib/components/DataSpaceGeneralEditor/DataSpaceSupportInfoSection.js +120 -0
  44. package/lib/components/DataSpaceGeneralEditor/DataSpaceSupportInfoSection.js.map +1 -0
  45. package/lib/index.css +2 -2
  46. package/lib/index.css.map +1 -1
  47. package/lib/package.json +3 -2
  48. package/lib/stores/DataSpaceEditorState.d.ts +18 -2
  49. package/lib/stores/DataSpaceEditorState.d.ts.map +1 -1
  50. package/lib/stores/DataSpaceEditorState.js +55 -3
  51. package/lib/stores/DataSpaceEditorState.js.map +1 -1
  52. package/lib/stores/DataSpaceExecutionContextState.d.ts +37 -0
  53. package/lib/stores/DataSpaceExecutionContextState.d.ts.map +1 -0
  54. package/lib/stores/DataSpaceExecutionContextState.js +87 -0
  55. package/lib/stores/DataSpaceExecutionContextState.js.map +1 -0
  56. package/lib/stores/studio/DSL_DataSpace_GraphModifierHelper.d.ts +34 -3
  57. package/lib/stores/studio/DSL_DataSpace_GraphModifierHelper.d.ts.map +1 -1
  58. package/lib/stores/studio/DSL_DataSpace_GraphModifierHelper.js +128 -2
  59. package/lib/stores/studio/DSL_DataSpace_GraphModifierHelper.js.map +1 -1
  60. package/package.json +10 -9
  61. package/src/components/DSL_DataProduct_ElementDriver.tsx +82 -0
  62. package/src/components/DSL_DataSpace_LegendStudioApplicationPlugin.tsx +35 -19
  63. package/src/components/DSL_NewDataProductEditor.tsx +57 -0
  64. package/src/components/DataSpaceEditor.tsx +54 -33
  65. package/src/components/DataSpaceExecutionContextEditor.tsx +692 -0
  66. package/src/components/DataSpaceGeneralEditor/DataSpaceDefaultExecutionContextSection.tsx +393 -0
  67. package/src/components/DataSpaceGeneralEditor/DataSpaceDiagramsSection.tsx +144 -0
  68. package/src/components/DataSpaceGeneralEditor/DataSpaceElementsSection.tsx +128 -0
  69. package/src/components/DataSpaceGeneralEditor/DataSpaceExecutablesSection.tsx +108 -0
  70. package/src/components/DataSpaceGeneralEditor/DataSpaceGeneralEditor.tsx +76 -0
  71. package/src/components/DataSpaceGeneralEditor/DataSpaceSupportInfoSection.tsx +276 -0
  72. package/src/stores/DataSpaceEditorState.ts +92 -4
  73. package/src/stores/DataSpaceExecutionContextState.ts +135 -0
  74. package/src/stores/studio/DSL_DataSpace_GraphModifierHelper.ts +278 -3
  75. package/tsconfig.json +11 -1
@@ -0,0 +1,393 @@
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
+ clsx,
19
+ CustomSelectorInput,
20
+ ErrorIcon,
21
+ ExclamationTriangleIcon,
22
+ LongArrowRightIcon,
23
+ PanelDropZone,
24
+ PanelFormSection,
25
+ PencilIcon,
26
+ PURE_MappingIcon,
27
+ PURE_RuntimeIcon,
28
+ XIcon,
29
+ } from '@finos/legend-art';
30
+ import type { DataSpaceExecutionContext } from '@finos/legend-extension-dsl-data-space/graph';
31
+ import { observer } from 'mobx-react-lite';
32
+ import {
33
+ dataSpace_setDefaultExecutionContext,
34
+ dataSpace_setExecutionContextDefaultRuntime,
35
+ dataSpace_setExecutionContextMapping,
36
+ } from '../../stores/studio/DSL_DataSpace_GraphModifierHelper.js';
37
+ import {
38
+ CORE_DND_TYPE,
39
+ type ElementDragSource,
40
+ useEditorStore,
41
+ type UMLEditorElementDropTarget,
42
+ } from '@finos/legend-application-studio';
43
+ import { DataSpaceEditorState } from '../../stores/DataSpaceEditorState.js';
44
+ import {
45
+ validate_PureExecutionMapping,
46
+ Mapping,
47
+ PackageableElementExplicitReference,
48
+ PackageableRuntime,
49
+ } from '@finos/legend-graph';
50
+ import { useCallback } from 'react';
51
+ import { useDrop } from 'react-dnd';
52
+ import {
53
+ buildElementOption,
54
+ type PackageableElementOption,
55
+ } from '@finos/legend-lego/graph-editor';
56
+ import { guaranteeNonNullable } from '@finos/legend-shared';
57
+ import {
58
+ RenameModal,
59
+ NewExecutionContextModal,
60
+ } from '../DataSpaceExecutionContextEditor.js';
61
+ import type { PropsValue } from 'react-select';
62
+
63
+ export const DataSpaceDefaultExecutionContextSection = observer(() => {
64
+ const editorStore = useEditorStore();
65
+ const applicationStore = editorStore.applicationStore;
66
+
67
+ const dataSpaceState =
68
+ editorStore.tabManagerState.getCurrentEditorState(DataSpaceEditorState);
69
+ const dataSpace = dataSpaceState.dataSpace;
70
+ const executionContext = dataSpace.defaultExecutionContext;
71
+
72
+ const executionContextState = dataSpaceState.executionContextState;
73
+
74
+ // Mapping
75
+ // TODO: this is not generic error handling, as there could be other problems
76
+ // with mapping, we need to genericize this
77
+ const isMappingEmpty = validate_PureExecutionMapping(
78
+ executionContext.mapping.value,
79
+ );
80
+ const mapping = executionContext.mapping.value;
81
+ const mappingOptions =
82
+ editorStore.graphManagerState.usableMappings.map(buildElementOption);
83
+ const noMappingLabel = (
84
+ <div
85
+ className="service-execution-editor__configuration__mapping-option--empty"
86
+ title={isMappingEmpty?.messages.join('\n') ?? ''}
87
+ >
88
+ <div className="service-execution-editor__configuration__mapping-option--empty__label">
89
+ (none)
90
+ </div>
91
+ <ErrorIcon />
92
+ </div>
93
+ );
94
+ const selectedMappingOption = {
95
+ value: mapping,
96
+ label: isMappingEmpty ? noMappingLabel : mapping.path,
97
+ } as PackageableElementOption<Mapping>;
98
+ const onMappingSelectionChange = (
99
+ val: PackageableElementOption<Mapping>,
100
+ ): void => {
101
+ if (val.value !== mapping) {
102
+ dataSpace_setExecutionContextMapping(
103
+ executionContext,
104
+ PackageableElementExplicitReference.create(val.value),
105
+ );
106
+ executionContextState.autoSelectRuntimeOnMappingChange(val.value);
107
+ }
108
+ };
109
+ const visitMapping = (): void =>
110
+ editorStore.graphEditorMode.openElement(mapping);
111
+
112
+ // Runtime
113
+ const defaultRuntime = executionContext.defaultRuntime;
114
+ // NOTE: for now, only include runtime associated with the mapping
115
+ // TODO?: Should we bring the runtime compatibility check from query to here?
116
+ const runtimes = editorStore.graphManagerState.graph.runtimes.filter((rt) =>
117
+ rt.runtimeValue.mappings.map((m) => m.value).includes(mapping),
118
+ );
119
+ const runtimeOptions = runtimes.map((rt) => ({
120
+ label: rt.path,
121
+ value: PackageableElementExplicitReference.create(rt),
122
+ }));
123
+ const runtimePointerWarning = !runtimes.includes(defaultRuntime.value) // if the runtime does not belong to the chosen mapping
124
+ ? `runtime is not associated with specified mapping '${mapping.path}'`
125
+ : undefined;
126
+ const selectedRuntimeOption = {
127
+ value: defaultRuntime,
128
+ label: (
129
+ <div
130
+ className="service-execution-editor__configuration__runtime-option__pointer"
131
+ title={undefined}
132
+ >
133
+ <div
134
+ className={clsx(
135
+ 'service-execution-editor__configuration__runtime-option__pointer__label',
136
+ {
137
+ 'service-execution-editor__configuration__runtime-option__pointer__label--with-warning':
138
+ Boolean(runtimePointerWarning),
139
+ },
140
+ )}
141
+ >
142
+ {defaultRuntime.value.path}
143
+ </div>
144
+ {runtimePointerWarning && (
145
+ <div
146
+ className="service-execution-editor__configuration__runtime-option__pointer__warning"
147
+ title={runtimePointerWarning}
148
+ >
149
+ <ExclamationTriangleIcon />
150
+ </div>
151
+ )}
152
+ </div>
153
+ ),
154
+ } as unknown as PropsValue<{
155
+ label: string;
156
+ value: PackageableElementExplicitReference<PackageableRuntime>;
157
+ }>;
158
+ const onRuntimeSelectionChange = (val: {
159
+ label: string | React.ReactNode;
160
+ value: PackageableElementExplicitReference<PackageableRuntime> | undefined;
161
+ }): void => {
162
+ if (val.value?.value !== defaultRuntime.value && val.value !== undefined) {
163
+ dataSpace_setExecutionContextDefaultRuntime(executionContext, val.value);
164
+ }
165
+ };
166
+ const visitRuntime = (): void => {
167
+ editorStore.graphEditorMode.openElement(defaultRuntime.value);
168
+ };
169
+
170
+ // DnD
171
+ const handleMappingOrRuntimeDrop = useCallback(
172
+ (item: UMLEditorElementDropTarget): void => {
173
+ const element = item.data.packageableElement;
174
+ if (!dataSpaceState.isReadOnly) {
175
+ if (element instanceof Mapping) {
176
+ dataSpace_setExecutionContextMapping(
177
+ executionContext,
178
+ PackageableElementExplicitReference.create(element),
179
+ );
180
+ executionContextState.autoSelectRuntimeOnMappingChange(element);
181
+ } else if (
182
+ element instanceof PackageableRuntime &&
183
+ element.runtimeValue.mappings.map((m) => m.value).includes(mapping)
184
+ ) {
185
+ dataSpace_setExecutionContextDefaultRuntime(
186
+ executionContext,
187
+ PackageableElementExplicitReference.create(element),
188
+ );
189
+ }
190
+ }
191
+ },
192
+ [
193
+ dataSpaceState.isReadOnly,
194
+ mapping,
195
+ executionContextState,
196
+ executionContext,
197
+ ],
198
+ );
199
+ const [{ isMappingOrRuntimeDragOver }, dropConnector] = useDrop<
200
+ ElementDragSource,
201
+ void,
202
+ { isMappingOrRuntimeDragOver: boolean }
203
+ >(
204
+ () => ({
205
+ accept: [
206
+ CORE_DND_TYPE.PROJECT_EXPLORER_MAPPING,
207
+ CORE_DND_TYPE.PROJECT_EXPLORER_RUNTIME,
208
+ ],
209
+ drop: (item) => handleMappingOrRuntimeDrop(item),
210
+ collect: (monitor) => ({
211
+ isMappingOrRuntimeDragOver: monitor.isOver({ shallow: true }),
212
+ }),
213
+ }),
214
+ [handleMappingOrRuntimeDrop],
215
+ );
216
+
217
+ //multiple execution contexts
218
+ const addExecutionKey = (): void => {
219
+ executionContextState.setNewExecutionContextModal(true);
220
+ };
221
+ type ExecutionContextOption = {
222
+ label: string;
223
+ value: DataSpaceExecutionContext;
224
+ };
225
+ const buildExecutionContextOption = (
226
+ context: DataSpaceExecutionContext,
227
+ ): ExecutionContextOption => ({
228
+ label: context.name,
229
+ value: context,
230
+ });
231
+ const executionContextOptions = dataSpace.executionContexts.map(
232
+ buildExecutionContextOption,
233
+ );
234
+ const onExecutionContextChange = (option: ExecutionContextOption) => {
235
+ if (option.value !== executionContext) {
236
+ dataSpace_setDefaultExecutionContext(dataSpace, option.value);
237
+ executionContextState.setSelectedExecutionContext(option.value);
238
+ }
239
+ };
240
+ const activeExecutionContext = buildExecutionContextOption(executionContext);
241
+ const deleteExecutionContext = (): void => {
242
+ executionContextState.removeExecutionContext(executionContext);
243
+ if (
244
+ dataSpace.executionContexts.length > 0 &&
245
+ dataSpace.executionContexts[0]
246
+ ) {
247
+ dataSpace_setDefaultExecutionContext(
248
+ dataSpace,
249
+ dataSpace.executionContexts[0],
250
+ );
251
+ }
252
+ };
253
+
254
+ return (
255
+ <PanelFormSection>
256
+ <div className="panel__content__form__section__header__label">
257
+ Execution Context
258
+ </div>
259
+ <div className="panel__content__form__section__header__prompt">
260
+ Define the mapping and runtime for this Data Product.
261
+ </div>
262
+ {dataSpace.executionContexts.length > 1 && (
263
+ <div className="service-execution-editor__configuration__item">
264
+ <CustomSelectorInput
265
+ className="panel__content__form__section__dropdown service-execution-editor__configuration__item__dropdown"
266
+ disabled={dataSpaceState.isReadOnly}
267
+ options={executionContextOptions}
268
+ onChange={onExecutionContextChange}
269
+ value={activeExecutionContext}
270
+ darkMode={
271
+ !applicationStore.layoutService
272
+ .TEMPORARY__isLightColorThemeEnabled
273
+ }
274
+ />
275
+ <button
276
+ className="btn--dark btn--sm service-execution-editor__configuration__item__btn"
277
+ onClick={() =>
278
+ executionContextState.setExecutionContextToRename(
279
+ activeExecutionContext.value,
280
+ )
281
+ }
282
+ tabIndex={-1}
283
+ title="Edit Execution Context"
284
+ >
285
+ <PencilIcon />
286
+ </button>
287
+ <button
288
+ className="btn--dark btn--sm service-execution-editor__configuration__item__btn"
289
+ onClick={deleteExecutionContext}
290
+ tabIndex={-1}
291
+ title="Delete Execution Context"
292
+ >
293
+ <XIcon />
294
+ </button>
295
+ </div>
296
+ )}
297
+ {executionContextState.newExecutionContextModal && (
298
+ <NewExecutionContextModal
299
+ executionState={executionContextState}
300
+ isReadOnly={dataSpaceState.isReadOnly}
301
+ />
302
+ )}
303
+ {executionContextState.executionContextToRename && (
304
+ <RenameModal
305
+ val={executionContextState.executionContextToRename.name}
306
+ isReadOnly={dataSpaceState.isReadOnly}
307
+ showModal={true}
308
+ closeModal={(): void =>
309
+ executionContextState.setExecutionContextToRename(undefined)
310
+ }
311
+ setValue={(val: string): void =>
312
+ executionContextState.renameExecutionContext(
313
+ guaranteeNonNullable(
314
+ executionContextState.executionContextToRename,
315
+ ),
316
+ val,
317
+ )
318
+ }
319
+ executionContext={executionContextState.executionContextToRename}
320
+ />
321
+ )}
322
+
323
+ <PanelDropZone
324
+ dropTargetConnector={dropConnector}
325
+ isDragOver={isMappingOrRuntimeDragOver && !dataSpaceState.isReadOnly}
326
+ >
327
+ <div className="service-execution-editor__configuration__items">
328
+ <div className="service-execution-editor__configuration__item">
329
+ <div className="btn--sm service-execution-editor__configuration__item__label">
330
+ <PURE_MappingIcon />
331
+ </div>
332
+ <CustomSelectorInput
333
+ className="panel__content__form__section__dropdown service-execution-editor__configuration__item__dropdown"
334
+ disabled={dataSpaceState.isReadOnly}
335
+ options={mappingOptions}
336
+ onChange={onMappingSelectionChange}
337
+ value={selectedMappingOption}
338
+ darkMode={
339
+ !applicationStore.layoutService
340
+ .TEMPORARY__isLightColorThemeEnabled
341
+ }
342
+ hasError={Boolean(isMappingEmpty)}
343
+ />
344
+ <button
345
+ className="btn--dark btn--sm service-execution-editor__configuration__item__btn"
346
+ onClick={visitMapping}
347
+ tabIndex={-1}
348
+ title="See mapping"
349
+ disabled={Boolean(isMappingEmpty)}
350
+ >
351
+ <LongArrowRightIcon />
352
+ </button>
353
+ </div>
354
+ <div className="service-execution-editor__configuration__item">
355
+ <div className="btn--sm service-execution-editor__configuration__item__label">
356
+ <PURE_RuntimeIcon />
357
+ </div>
358
+ <CustomSelectorInput
359
+ className="panel__content__form__section__dropdown service-execution-editor__configuration__item__dropdown"
360
+ disabled={dataSpaceState.isReadOnly}
361
+ options={runtimeOptions}
362
+ onChange={onRuntimeSelectionChange}
363
+ value={selectedRuntimeOption}
364
+ darkMode={
365
+ !applicationStore.layoutService
366
+ .TEMPORARY__isLightColorThemeEnabled
367
+ }
368
+ />
369
+ <button
370
+ className="btn--sm btn--dark service-execution-editor__configuration__item__btn"
371
+ onClick={visitRuntime}
372
+ tabIndex={-1}
373
+ title="See runtime"
374
+ disabled={Boolean(runtimePointerWarning)}
375
+ >
376
+ <LongArrowRightIcon />
377
+ </button>
378
+ </div>
379
+ </div>
380
+ </PanelDropZone>
381
+ <div className="panel__content__form__section__list__new-item__add">
382
+ <button
383
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
384
+ // disabled={isReadOnly}
385
+ onClick={addExecutionKey}
386
+ tabIndex={-1}
387
+ >
388
+ Add Value
389
+ </button>
390
+ </div>
391
+ </PanelFormSection>
392
+ );
393
+ });
@@ -0,0 +1,144 @@
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 { useEditorStore } from '@finos/legend-application-studio';
18
+ import {
19
+ CustomSelectorInput,
20
+ ListEditor,
21
+ PanelFormTextField,
22
+ } from '@finos/legend-art';
23
+ import { DataSpaceDiagram } from '@finos/legend-extension-dsl-data-space/graph';
24
+ import { observer } from 'mobx-react-lite';
25
+ import { DataSpaceEditorState } from '../../stores/DataSpaceEditorState.js';
26
+ import { PackageableElementExplicitReference } from '@finos/legend-graph';
27
+ import { type Diagram } from '@finos/legend-extension-dsl-diagram/graph';
28
+ import {
29
+ dataSpace_addDiagram,
30
+ dataSpace_removeDiagram,
31
+ dataSpace_setDiagramTitle,
32
+ dataSpace_setDiagramDescription,
33
+ } from '../../stores/studio/DSL_DataSpace_GraphModifierHelper.js';
34
+
35
+ export const DataSpaceDiagramsSection = observer(() => {
36
+ const editorStore = useEditorStore();
37
+
38
+ const dataSpaceState =
39
+ editorStore.tabManagerState.getCurrentEditorState(DataSpaceEditorState);
40
+ const dataSpace = dataSpaceState.dataSpace;
41
+
42
+ // Event handlers
43
+ const handleAddDiagram = (option: {
44
+ label: string;
45
+ value: Diagram;
46
+ }): void => {
47
+ if (typeof option.value === 'object') {
48
+ const diagramValue = option.value;
49
+ const newDiagram = new DataSpaceDiagram();
50
+ newDiagram.title = diagramValue.name;
51
+ newDiagram.diagram =
52
+ PackageableElementExplicitReference.create(diagramValue);
53
+ dataSpace_addDiagram(dataSpace, newDiagram);
54
+ }
55
+ };
56
+
57
+ const handleRemoveDiagram = (diagram: DataSpaceDiagram): void => {
58
+ dataSpace_removeDiagram(dataSpace, diagram);
59
+ };
60
+
61
+ const handleDiagramTitleChange = (
62
+ diagram: DataSpaceDiagram,
63
+ value: string | undefined,
64
+ ): void => {
65
+ dataSpace_setDiagramTitle(diagram, value ?? '');
66
+ };
67
+
68
+ const handleDiagramDescriptionChange = (
69
+ diagram: DataSpaceDiagram,
70
+ value: string | undefined,
71
+ ): void => {
72
+ dataSpace_setDiagramDescription(diagram, value);
73
+ };
74
+
75
+ // ListEditor component renderers
76
+ const DiagramComponent = observer(
77
+ (props: { item: DataSpaceDiagram }): React.ReactElement => {
78
+ const { item } = props;
79
+
80
+ return (
81
+ <>
82
+ <div className="panel__content__form__section__list__item__content">
83
+ <div className="panel__content__form__section__header__label">
84
+ Diagram
85
+ </div>
86
+ <div className="panel__content__form__section__list__item__content__title">
87
+ {item.diagram.value.path}
88
+ </div>
89
+ </div>
90
+ <div className="panel__content__form__section__list__item__form">
91
+ <PanelFormTextField
92
+ name="Title"
93
+ value={item.title}
94
+ update={(value) => handleDiagramTitleChange(item, value)}
95
+ placeholder="Enter title"
96
+ className="dataSpace-editor__general__diagrams__title"
97
+ />
98
+ <PanelFormTextField
99
+ name="Description"
100
+ value={item.description ?? ''}
101
+ update={(value) => handleDiagramDescriptionChange(item, value)}
102
+ placeholder="Enter description"
103
+ className="dataSpace-editor__general__diagrams__description"
104
+ />
105
+ </div>
106
+ </>
107
+ );
108
+ },
109
+ );
110
+
111
+ const NewDiagramComponent = observer(
112
+ (props: { onFinishEditing: () => void }): React.ReactElement => {
113
+ const { onFinishEditing } = props;
114
+
115
+ return (
116
+ <div className="panel__content__form__section__list__new-item__input">
117
+ <CustomSelectorInput
118
+ options={dataSpaceState.getDiagramOptions()}
119
+ onChange={(event: { label: string; value: Diagram }) => {
120
+ onFinishEditing();
121
+ handleAddDiagram(event);
122
+ }}
123
+ placeholder="Select a diagram to add..."
124
+ darkMode={true}
125
+ />
126
+ </div>
127
+ );
128
+ },
129
+ );
130
+
131
+ return (
132
+ <ListEditor
133
+ title="Diagrams"
134
+ prompt="Add diagrams to include in this Data Product. Set a title and description for each diagram."
135
+ items={dataSpace.diagrams}
136
+ keySelector={(element: DataSpaceDiagram) => element.diagram.value.path}
137
+ ItemComponent={DiagramComponent}
138
+ NewItemComponent={NewDiagramComponent}
139
+ handleRemoveItem={handleRemoveDiagram}
140
+ isReadOnly={dataSpaceState.isReadOnly}
141
+ emptyMessage="No diagrams specified"
142
+ />
143
+ );
144
+ });
@@ -0,0 +1,128 @@
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 { useEditorStore } from '@finos/legend-application-studio';
18
+ import { ListEditor, Checkbox, CustomSelectorInput } from '@finos/legend-art';
19
+ import {
20
+ type DataSpaceElement,
21
+ DataSpaceElementPointer,
22
+ } from '@finos/legend-extension-dsl-data-space/graph';
23
+ import { observer } from 'mobx-react-lite';
24
+ import { DataSpaceEditorState } from '../../stores/DataSpaceEditorState.js';
25
+ import { PackageableElementExplicitReference } from '@finos/legend-graph';
26
+ import {
27
+ dataSpace_addElement,
28
+ dataSpace_removeElement,
29
+ dataSpace_setElementExclude,
30
+ } from '../../stores/studio/DSL_DataSpace_GraphModifierHelper.js';
31
+
32
+ export const DataSpaceElementsSection = observer(() => {
33
+ const editorStore = useEditorStore();
34
+
35
+ const dataSpaceState =
36
+ editorStore.tabManagerState.getCurrentEditorState(DataSpaceEditorState);
37
+ const dataSpace = dataSpaceState.dataSpace;
38
+
39
+ // Event handlers
40
+ const handleAddElement = (option: {
41
+ label: string;
42
+ value: DataSpaceElement;
43
+ }): void => {
44
+ if (typeof option.value === 'object') {
45
+ const element = option.value;
46
+ const elementPointer = new DataSpaceElementPointer();
47
+ elementPointer.element =
48
+ PackageableElementExplicitReference.create(element);
49
+ dataSpace_addElement(dataSpace, elementPointer);
50
+ }
51
+ };
52
+
53
+ const handleRemoveElement = (element: DataSpaceElementPointer): void => {
54
+ dataSpace_removeElement(dataSpace, element);
55
+ };
56
+
57
+ const handleElementExcludeChange = (
58
+ element: DataSpaceElementPointer,
59
+ event: React.ChangeEvent<HTMLInputElement>,
60
+ ): void => {
61
+ dataSpace_setElementExclude(element, event.target.checked);
62
+ };
63
+
64
+ // ListEditor component renderers
65
+ const ElementComponent = observer(
66
+ (props: { item: DataSpaceElementPointer }): React.ReactElement => {
67
+ const { item } = props;
68
+
69
+ return (
70
+ <div className="panel__content__form__section__list__item__content">
71
+ <div className="panel__content__form__section__list__item__content__label">
72
+ {item.element.value.path}
73
+ </div>
74
+ <div className="panel__content__form__section__list__item__content__actions">
75
+ <div className="panel__content__form__section__list__item__content__actions-exclude">
76
+ <Checkbox
77
+ disabled={dataSpaceState.isReadOnly}
78
+ checked={item.exclude ?? false}
79
+ onChange={(event) => handleElementExcludeChange(item, event)}
80
+ size="small"
81
+ className="panel__content__form__section__list__item__content__actions-exclude__btn"
82
+ />
83
+ <span className="panel__content__form__section__list__item__content__actions__label">
84
+ Exclude
85
+ </span>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ );
90
+ },
91
+ );
92
+
93
+ const NewElementComponent = observer(
94
+ (props: { onFinishEditing: () => void }) => {
95
+ const { onFinishEditing } = props;
96
+
97
+ return (
98
+ <div className="panel__content__form__section__list__new-item__input">
99
+ <CustomSelectorInput
100
+ options={dataSpaceState.getDataSpaceElementOptions()}
101
+ onChange={(event: { label: string; value: DataSpaceElement }) => {
102
+ onFinishEditing();
103
+ handleAddElement(event);
104
+ }}
105
+ placeholder="Select an element to add..."
106
+ darkMode={true}
107
+ />
108
+ </div>
109
+ );
110
+ },
111
+ );
112
+
113
+ return (
114
+ <ListEditor
115
+ title="Elements"
116
+ prompt="Add classes and associations to display under Models Documentation. Use the exclude checkbox to exclude certain elements from this Data Product entirely."
117
+ items={dataSpace.elements}
118
+ keySelector={(element: DataSpaceElementPointer) =>
119
+ element.element.value.path
120
+ }
121
+ ItemComponent={ElementComponent}
122
+ NewItemComponent={NewElementComponent}
123
+ handleRemoveItem={handleRemoveElement}
124
+ isReadOnly={dataSpaceState.isReadOnly}
125
+ emptyMessage="No elements specified"
126
+ />
127
+ );
128
+ });