@finos/legend-application-studio 28.19.5 → 28.19.7
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__/LegendStudioApplicationNavigationContext.d.ts +3 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js +3 -0
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
- package/lib/__lib__/LegendStudioTesting.d.ts +2 -1
- package/lib/__lib__/LegendStudioTesting.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioTesting.js +1 -0
- package/lib/__lib__/LegendStudioTesting.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.d.ts +9 -0
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.js +128 -28
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +3 -0
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/GraphEditFormModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditFormModeState.js +1 -1
- package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.d.ts.map +1 -1
- package/lib/stores/editor/GraphEditGrammarModeState.js +3 -1
- package/lib/stores/editor/GraphEditGrammarModeState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/RuntimeEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/RuntimeEditorState.js +3 -1
- package/lib/stores/editor/editor-state/element-editor-state/RuntimeEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +5 -3
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts +8 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js +27 -1
- package/lib/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js.map +1 -1
- package/package.json +15 -15
- package/src/__lib__/LegendStudioApplicationNavigationContext.ts +4 -0
- package/src/__lib__/LegendStudioTesting.ts +2 -0
- package/src/components/editor/editor-group/dataProduct/DataPoductEditor.tsx +263 -41
- package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +6 -0
- package/src/stores/editor/GraphEditFormModeState.ts +1 -0
- package/src/stores/editor/GraphEditGrammarModeState.ts +3 -0
- package/src/stores/editor/editor-state/element-editor-state/RuntimeEditorState.ts +5 -1
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +12 -3
- package/src/stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.ts +51 -0
@@ -37,6 +37,7 @@ import {
|
|
37
37
|
PlusIcon,
|
38
38
|
PanelHeaderActionItem,
|
39
39
|
RocketIcon,
|
40
|
+
ListEditor,
|
40
41
|
Modal,
|
41
42
|
ModalHeader,
|
42
43
|
ModalTitle,
|
@@ -50,21 +51,53 @@ import {
|
|
50
51
|
MenuContentItem,
|
51
52
|
CaretDownIcon,
|
52
53
|
WarningIcon,
|
54
|
+
PanelFormSection,
|
53
55
|
} from '@finos/legend-art';
|
54
|
-
import React, {
|
56
|
+
import React, {
|
57
|
+
useRef,
|
58
|
+
useState,
|
59
|
+
useEffect,
|
60
|
+
type ChangeEventHandler,
|
61
|
+
} from 'react';
|
55
62
|
import { filterByType } from '@finos/legend-shared';
|
56
63
|
import { InlineLambdaEditor } from '@finos/legend-query-builder';
|
57
64
|
import { action, flowResult } from 'mobx';
|
58
65
|
import { useAuth } from 'react-oidc-context';
|
59
66
|
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
|
60
67
|
import { CodeEditor } from '@finos/legend-lego/code-editor';
|
61
|
-
import { LakehouseTargetEnv } from '@finos/legend-graph';
|
68
|
+
import { LakehouseTargetEnv, Email } from '@finos/legend-graph';
|
62
69
|
import {
|
63
70
|
accessPointGroup_setDescription,
|
64
71
|
accessPointGroup_setName,
|
65
72
|
dataProduct_setDescription,
|
73
|
+
dataProduct_setSupportInfoIfAbsent,
|
66
74
|
dataProduct_setTitle,
|
75
|
+
supportInfo_setDocumentationUrl,
|
76
|
+
supportInfo_setWebsite,
|
77
|
+
supportInfo_setFaqUrl,
|
78
|
+
supportInfo_setSupportUrl,
|
79
|
+
supportInfo_addEmail,
|
80
|
+
supportInfo_deleteEmail,
|
67
81
|
} from '../../../../stores/graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
|
82
|
+
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
83
|
+
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
|
84
|
+
import {
|
85
|
+
ActionAlertActionType,
|
86
|
+
ActionAlertType,
|
87
|
+
useApplicationNavigationContext,
|
88
|
+
} from '@finos/legend-application';
|
89
|
+
|
90
|
+
export enum AP_GROUP_MODAL_ERRORS {
|
91
|
+
GROUP_NAME_EMPTY = 'Group Name is empty',
|
92
|
+
GROUP_NAME_EXISTS = 'Group Name already exists',
|
93
|
+
GROUP_DESCRIPTION_EMPTY = 'Group Description is empty',
|
94
|
+
AP_NAME_EMPTY = 'Access Point Name is empty',
|
95
|
+
AP_NAME_EXISTS = 'Access Point Name already exists',
|
96
|
+
AP_DESCRIPTION_EMPTY = 'Access Point Description is empty',
|
97
|
+
}
|
98
|
+
|
99
|
+
export const AP_EMPTY_DESC_WARNING =
|
100
|
+
'Describe the data this access point produces';
|
68
101
|
|
69
102
|
const NewAccessPointAccessPOint = observer(
|
70
103
|
(props: { dataProductEditorState: DataProductEditorState }) => {
|
@@ -106,15 +139,17 @@ const NewAccessPointAccessPOint = observer(
|
|
106
139
|
dataProductEditorState.accessPoints.map((e) => e.id).includes(id);
|
107
140
|
const nameErrors =
|
108
141
|
id === ''
|
109
|
-
?
|
142
|
+
? AP_GROUP_MODAL_ERRORS.AP_NAME_EMPTY
|
110
143
|
: dataProductEditorState.accessPoints
|
111
144
|
.map((e) => e.id)
|
112
145
|
.includes(id ?? '')
|
113
|
-
?
|
146
|
+
? AP_GROUP_MODAL_ERRORS.AP_NAME_EXISTS
|
114
147
|
: undefined;
|
115
148
|
|
116
149
|
const descriptionErrors =
|
117
|
-
description === ''
|
150
|
+
description === ''
|
151
|
+
? AP_GROUP_MODAL_ERRORS.AP_DESCRIPTION_EMPTY
|
152
|
+
: undefined;
|
118
153
|
return (
|
119
154
|
<Dialog
|
120
155
|
open={true}
|
@@ -156,9 +191,9 @@ const NewAccessPointAccessPOint = observer(
|
|
156
191
|
})}
|
157
192
|
ref={accessPointInputRef}
|
158
193
|
spellCheck={false}
|
159
|
-
value={id}
|
194
|
+
value={id ?? ''}
|
160
195
|
onChange={handleIdChange}
|
161
|
-
placeholder="Access Point
|
196
|
+
placeholder="Access Point Name"
|
162
197
|
error={nameErrors}
|
163
198
|
/>
|
164
199
|
</div>
|
@@ -171,7 +206,7 @@ const NewAccessPointAccessPOint = observer(
|
|
171
206
|
'input--dark': true,
|
172
207
|
})}
|
173
208
|
spellCheck={false}
|
174
|
-
value={description}
|
209
|
+
value={description ?? ''}
|
175
210
|
onChange={handleDescriptionChange}
|
176
211
|
placeholder="Access Point Description"
|
177
212
|
error={descriptionErrors}
|
@@ -228,24 +263,28 @@ const NewAccessPointGroupModal = observer(
|
|
228
263
|
|
229
264
|
const groupNameErrors =
|
230
265
|
groupName === ''
|
231
|
-
?
|
266
|
+
? AP_GROUP_MODAL_ERRORS.GROUP_NAME_EMPTY
|
232
267
|
: dataProductEditorState.accessPointGroupStates
|
233
268
|
.map((e) => e.value.id)
|
234
269
|
.includes(groupName ?? '')
|
235
|
-
?
|
270
|
+
? AP_GROUP_MODAL_ERRORS.GROUP_NAME_EXISTS
|
236
271
|
: undefined;
|
237
272
|
const groupDescriptionErrors =
|
238
|
-
groupDescription === ''
|
273
|
+
groupDescription === ''
|
274
|
+
? AP_GROUP_MODAL_ERRORS.GROUP_DESCRIPTION_EMPTY
|
275
|
+
: undefined;
|
239
276
|
const apNameErrors =
|
240
277
|
apName === ''
|
241
|
-
?
|
278
|
+
? AP_GROUP_MODAL_ERRORS.AP_NAME_EMPTY
|
242
279
|
: dataProductEditorState.accessPoints
|
243
280
|
.map((e) => e.id)
|
244
281
|
.includes(apName ?? '')
|
245
|
-
?
|
282
|
+
? AP_GROUP_MODAL_ERRORS.AP_NAME_EXISTS
|
246
283
|
: undefined;
|
247
284
|
const apDescriptionErrors =
|
248
|
-
apDescription === ''
|
285
|
+
apDescription === ''
|
286
|
+
? AP_GROUP_MODAL_ERRORS.AP_DESCRIPTION_EMPTY
|
287
|
+
: undefined;
|
249
288
|
|
250
289
|
const disableCreateButton =
|
251
290
|
!groupName ||
|
@@ -314,7 +353,7 @@ const NewAccessPointGroupModal = observer(
|
|
314
353
|
})}
|
315
354
|
ref={accessPointGroupInputRef}
|
316
355
|
spellCheck={false}
|
317
|
-
value={groupName}
|
356
|
+
value={groupName ?? ''}
|
318
357
|
onChange={handleGroupNameChange}
|
319
358
|
placeholder="Access Point Group Name"
|
320
359
|
error={groupNameErrors}
|
@@ -329,7 +368,7 @@ const NewAccessPointGroupModal = observer(
|
|
329
368
|
'input--dark': true,
|
330
369
|
})}
|
331
370
|
spellCheck={false}
|
332
|
-
value={groupDescription}
|
371
|
+
value={groupDescription ?? ''}
|
333
372
|
onChange={handleGroupDescriptionChange}
|
334
373
|
placeholder="Access Point Group Description"
|
335
374
|
error={groupDescriptionErrors}
|
@@ -348,7 +387,7 @@ const NewAccessPointGroupModal = observer(
|
|
348
387
|
'input--dark': true,
|
349
388
|
})}
|
350
389
|
spellCheck={false}
|
351
|
-
value={apName}
|
390
|
+
value={apName ?? ''}
|
352
391
|
onChange={handleApNameChange}
|
353
392
|
placeholder="Access Point Name"
|
354
393
|
error={apNameErrors}
|
@@ -361,7 +400,7 @@ const NewAccessPointGroupModal = observer(
|
|
361
400
|
'input--dark': true,
|
362
401
|
})}
|
363
402
|
spellCheck={false}
|
364
|
-
value={apDescription}
|
403
|
+
value={apDescription ?? ''}
|
365
404
|
onChange={handleApDescriptionChange}
|
366
405
|
placeholder="Access Point Description"
|
367
406
|
error={apDescriptionErrors}
|
@@ -411,7 +450,7 @@ const HoverTextArea: React.FC<HoverTextAreaProps> = ({
|
|
411
450
|
|
412
451
|
const hoverIcon = () => {
|
413
452
|
return (
|
414
|
-
<div>
|
453
|
+
<div data-testid={LEGEND_STUDIO_TEST_ID.HOVER_EDIT_ICON}>
|
415
454
|
<PencilEditIcon />
|
416
455
|
</div>
|
417
456
|
);
|
@@ -445,11 +484,10 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
445
484
|
setIsHovering(false);
|
446
485
|
};
|
447
486
|
|
448
|
-
const updateAccessPointDescription: React.ChangeEventHandler<
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
};
|
487
|
+
const updateAccessPointDescription: React.ChangeEventHandler<HTMLTextAreaElement> =
|
488
|
+
action((event) => {
|
489
|
+
accessPoint.description = event.target.value;
|
490
|
+
});
|
453
491
|
|
454
492
|
const updateAccessPointTargetEnvironment = action(
|
455
493
|
(targetEnvironment: LakehouseTargetEnv) => {
|
@@ -502,7 +540,7 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
502
540
|
onMouseOut={handleMouseOut}
|
503
541
|
>
|
504
542
|
<WarningIcon />
|
505
|
-
|
543
|
+
{AP_EMPTY_DESC_WARNING}
|
506
544
|
</div>
|
507
545
|
)}
|
508
546
|
|
@@ -673,6 +711,7 @@ const DataProductDeploymentResponseModal = observer(
|
|
673
711
|
const AccessPointGroupSection = observer(
|
674
712
|
(props: { groupState: AccessPointGroupState; isReadOnly: boolean }) => {
|
675
713
|
const { groupState, isReadOnly } = props;
|
714
|
+
const editorStore = useEditorStore();
|
676
715
|
const productEditorState = groupState.state;
|
677
716
|
const [editingDescription, setEditingDescription] = useState(false);
|
678
717
|
const [isHoveringDescription, setIsHoveringDescription] = useState(false);
|
@@ -715,6 +754,27 @@ const AccessPointGroupSection = observer(
|
|
715
754
|
}
|
716
755
|
};
|
717
756
|
|
757
|
+
const handleRemoveAccessPointGroup = (): void => {
|
758
|
+
editorStore.applicationStore.alertService.setActionAlertInfo({
|
759
|
+
message: `Deleting access point group ${groupState.value.id} will permanently remove it and all associated access points. Are you sure you want to proceed?`,
|
760
|
+
type: ActionAlertType.CAUTION,
|
761
|
+
actions: [
|
762
|
+
{
|
763
|
+
label: 'Cancel',
|
764
|
+
type: ActionAlertActionType.PROCEED,
|
765
|
+
default: true,
|
766
|
+
},
|
767
|
+
{
|
768
|
+
label: 'Proceed',
|
769
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
770
|
+
handler: (): void => {
|
771
|
+
productEditorState.deleteAccessPointGroup(groupState);
|
772
|
+
},
|
773
|
+
},
|
774
|
+
],
|
775
|
+
});
|
776
|
+
};
|
777
|
+
|
718
778
|
const openNewModal = () => {
|
719
779
|
productEditorState.setEditingGroupState(groupState);
|
720
780
|
productEditorState.setAccessPointModal(true);
|
@@ -755,7 +815,8 @@ const AccessPointGroupSection = observer(
|
|
755
815
|
<button
|
756
816
|
className="access-point-editor__generic-entry__remove-btn--group"
|
757
817
|
onClick={() => {
|
758
|
-
productEditorState.deleteAccessPointGroup(groupState);
|
818
|
+
// productEditorState.deleteAccessPointGroup(groupState);
|
819
|
+
handleRemoveAccessPointGroup();
|
759
820
|
}}
|
760
821
|
tabIndex={-1}
|
761
822
|
title="Remove Access Point Group"
|
@@ -879,9 +940,42 @@ export const DataProductEditor = observer(() => {
|
|
879
940
|
const updateDataProductTitle = (val: string | undefined): void => {
|
880
941
|
dataProduct_setTitle(product, val ?? '');
|
881
942
|
};
|
882
|
-
const updateDataProductDescription
|
883
|
-
|
943
|
+
const updateDataProductDescription: ChangeEventHandler<
|
944
|
+
HTMLTextAreaElement
|
945
|
+
> = (event) => {
|
946
|
+
dataProduct_setDescription(product, event.target.value);
|
947
|
+
};
|
948
|
+
|
949
|
+
const updateSupportInfoDocumentationUrl = (val: string | undefined): void => {
|
950
|
+
dataProduct_setSupportInfoIfAbsent(product);
|
951
|
+
if (product.supportInfo) {
|
952
|
+
supportInfo_setDocumentationUrl(product.supportInfo, val ?? '');
|
953
|
+
}
|
954
|
+
};
|
955
|
+
|
956
|
+
const updateSupportInfoWebsite = (val: string | undefined): void => {
|
957
|
+
dataProduct_setSupportInfoIfAbsent(product);
|
958
|
+
if (product.supportInfo) {
|
959
|
+
supportInfo_setWebsite(product.supportInfo, val ?? '');
|
960
|
+
}
|
961
|
+
};
|
962
|
+
|
963
|
+
const updateSupportInfoFaqUrl = (val: string | undefined): void => {
|
964
|
+
dataProduct_setSupportInfoIfAbsent(product);
|
965
|
+
if (product.supportInfo) {
|
966
|
+
supportInfo_setFaqUrl(product.supportInfo, val ?? '');
|
967
|
+
}
|
968
|
+
};
|
969
|
+
|
970
|
+
const updateSupportInfoSupportUrl = (val: string | undefined): void => {
|
971
|
+
dataProduct_setSupportInfoIfAbsent(product);
|
972
|
+
if (product.supportInfo) {
|
973
|
+
supportInfo_setSupportUrl(product.supportInfo, val ?? '');
|
974
|
+
}
|
884
975
|
};
|
976
|
+
useApplicationNavigationContext(
|
977
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.DATA_PRODUCT_EDITOR,
|
978
|
+
);
|
885
979
|
|
886
980
|
useEffect(() => {
|
887
981
|
flowResult(dataProductEditorState.convertAccessPointsFuncObjects()).catch(
|
@@ -901,6 +995,84 @@ export const DataProductEditor = observer(() => {
|
|
901
995
|
dataProductEditorState,
|
902
996
|
]);
|
903
997
|
|
998
|
+
const handleSupportInfoEmailAdd = (address: string, title: string): void => {
|
999
|
+
dataProduct_setSupportInfoIfAbsent(product);
|
1000
|
+
if (product.supportInfo) {
|
1001
|
+
supportInfo_addEmail(product.supportInfo, new Email(address, title));
|
1002
|
+
}
|
1003
|
+
};
|
1004
|
+
|
1005
|
+
const handleSupportInfoEmailRemove = (email: Email): void => {
|
1006
|
+
if (product.supportInfo) {
|
1007
|
+
supportInfo_deleteEmail(product.supportInfo, email);
|
1008
|
+
}
|
1009
|
+
};
|
1010
|
+
|
1011
|
+
const SupportEmailComponent = observer(
|
1012
|
+
(props: { item: Email }): React.ReactElement => {
|
1013
|
+
const { item } = props;
|
1014
|
+
|
1015
|
+
return (
|
1016
|
+
<div className="panel__content__form__section__list__item__rows">
|
1017
|
+
<div className="row">
|
1018
|
+
<label className="label">Address</label>
|
1019
|
+
<div className="textbox">{item.address}</div>
|
1020
|
+
</div>
|
1021
|
+
<div className="row">
|
1022
|
+
<label className="label">Title</label>
|
1023
|
+
<div className="textbox">{item.title}</div>
|
1024
|
+
</div>
|
1025
|
+
</div>
|
1026
|
+
);
|
1027
|
+
},
|
1028
|
+
);
|
1029
|
+
|
1030
|
+
const NewSupportEmailComponent = observer(
|
1031
|
+
(props: { onFinishEditing: () => void }) => {
|
1032
|
+
const { onFinishEditing } = props;
|
1033
|
+
const [address, setAddress] = useState('');
|
1034
|
+
const [title, setTitle] = useState('');
|
1035
|
+
|
1036
|
+
return (
|
1037
|
+
<div className="data-product-editor__support-info__new-email">
|
1038
|
+
<div className="panel__content__form__section__list__new-item__input">
|
1039
|
+
<input
|
1040
|
+
className="input input-group__input panel__content__form__section__input input--dark"
|
1041
|
+
type="email"
|
1042
|
+
placeholder="Enter email"
|
1043
|
+
value={address}
|
1044
|
+
onChange={(event) => {
|
1045
|
+
setAddress(event.target.value);
|
1046
|
+
}}
|
1047
|
+
/>
|
1048
|
+
</div>
|
1049
|
+
<div className="panel__content__form__section__list__new-item__input">
|
1050
|
+
<input
|
1051
|
+
className="input input-group__input panel__content__form__section__input input--dark"
|
1052
|
+
type="title"
|
1053
|
+
placeholder="Enter title"
|
1054
|
+
value={title}
|
1055
|
+
onChange={(event) => {
|
1056
|
+
setTitle(event.target.value);
|
1057
|
+
}}
|
1058
|
+
/>
|
1059
|
+
</div>
|
1060
|
+
<button
|
1061
|
+
className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
|
1062
|
+
onClick={() => {
|
1063
|
+
handleSupportInfoEmailAdd(address, title);
|
1064
|
+
setAddress('');
|
1065
|
+
setTitle('');
|
1066
|
+
onFinishEditing();
|
1067
|
+
}}
|
1068
|
+
>
|
1069
|
+
Save
|
1070
|
+
</button>
|
1071
|
+
</div>
|
1072
|
+
);
|
1073
|
+
},
|
1074
|
+
);
|
1075
|
+
|
904
1076
|
return (
|
905
1077
|
<div className="data-product-editor">
|
906
1078
|
<div className="panel">
|
@@ -936,13 +1108,69 @@ export const DataProductEditor = observer(() => {
|
|
936
1108
|
update={updateDataProductTitle}
|
937
1109
|
placeholder="Enter title"
|
938
1110
|
/>
|
939
|
-
<
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
1111
|
+
<div style={{ margin: '1rem' }}>
|
1112
|
+
<div className="panel__content__form__section__header__label">
|
1113
|
+
Description
|
1114
|
+
</div>
|
1115
|
+
<div className="panel__content__form__section__header__prompt">
|
1116
|
+
Provide a description for this Lakehouse Data Product.
|
1117
|
+
</div>
|
1118
|
+
<textarea
|
1119
|
+
className="panel__content__form__section__textarea"
|
1120
|
+
spellCheck={false}
|
1121
|
+
disabled={isReadOnly}
|
1122
|
+
value={product.description}
|
1123
|
+
onChange={updateDataProductDescription}
|
1124
|
+
style={{
|
1125
|
+
padding: '0.5rem',
|
1126
|
+
width: '45rem',
|
1127
|
+
maxWidth: '45rem !important',
|
1128
|
+
}}
|
1129
|
+
/>
|
1130
|
+
</div>
|
1131
|
+
|
1132
|
+
<PanelFormSection>
|
1133
|
+
<div className="panel__content__form__section__header__label">
|
1134
|
+
Support Information
|
1135
|
+
</div>
|
1136
|
+
<div className="panel__content__form__section__header__prompt">
|
1137
|
+
Configure support information for this Lakehouse Data Product.
|
1138
|
+
</div>
|
1139
|
+
<PanelFormTextField
|
1140
|
+
name="Documentation URL"
|
1141
|
+
value={product.supportInfo?.documentationUrl ?? ''}
|
1142
|
+
update={updateSupportInfoDocumentationUrl}
|
1143
|
+
placeholder="Enter Documentation URL"
|
1144
|
+
/>
|
1145
|
+
<PanelFormTextField
|
1146
|
+
name="Website"
|
1147
|
+
value={product.supportInfo?.website}
|
1148
|
+
update={updateSupportInfoWebsite}
|
1149
|
+
placeholder="Enter Website"
|
1150
|
+
/>
|
1151
|
+
<PanelFormTextField
|
1152
|
+
name="FAQ URL"
|
1153
|
+
value={product.supportInfo?.faqUrl}
|
1154
|
+
update={updateSupportInfoFaqUrl}
|
1155
|
+
placeholder="Enter FAQ URL"
|
1156
|
+
/>
|
1157
|
+
<PanelFormTextField
|
1158
|
+
name="Support URL"
|
1159
|
+
value={product.supportInfo?.supportUrl}
|
1160
|
+
update={updateSupportInfoSupportUrl}
|
1161
|
+
placeholder="Enter Support URL"
|
1162
|
+
/>
|
1163
|
+
<ListEditor
|
1164
|
+
title="Emails"
|
1165
|
+
items={product.supportInfo?.emails}
|
1166
|
+
keySelector={(email: Email) => email.address + email.title}
|
1167
|
+
ItemComponent={SupportEmailComponent}
|
1168
|
+
NewItemComponent={NewSupportEmailComponent}
|
1169
|
+
handleRemoveItem={handleSupportInfoEmailRemove}
|
1170
|
+
isReadOnly={isReadOnly}
|
1171
|
+
emptyMessage="No emails specified"
|
1172
|
+
/>
|
1173
|
+
</PanelFormSection>
|
946
1174
|
</div>
|
947
1175
|
<div className="panel" style={{ overflow: 'auto' }}>
|
948
1176
|
<PanelHeader>
|
@@ -983,12 +1211,6 @@ export const DataProductEditor = observer(() => {
|
|
983
1211
|
/>
|
984
1212
|
)}
|
985
1213
|
</PanelContent>
|
986
|
-
|
987
|
-
{/* {dataProductEditorState.accessPointModal && (
|
988
|
-
<NewAccessPointAccessPOint
|
989
|
-
dataProductEditorState={dataProductEditorState}
|
990
|
-
/>
|
991
|
-
)} */}
|
992
1214
|
{dataProductEditorState.accessPointGroupModal && (
|
993
1215
|
<NewAccessPointGroupModal
|
994
1216
|
dataProductEditorState={dataProductEditorState}
|
@@ -44,6 +44,8 @@ import {
|
|
44
44
|
IngestDefinitionDeploymentResponse,
|
45
45
|
IngestDefinitionValidationResponse,
|
46
46
|
} from '@finos/legend-server-lakehouse';
|
47
|
+
import { useApplicationNavigationContext } from '@finos/legend-application';
|
48
|
+
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
|
47
49
|
|
48
50
|
const IngestValidationError = observer(
|
49
51
|
(props: {
|
@@ -259,6 +261,10 @@ export const IngestDefinitionEditor = observer(() => {
|
|
259
261
|
ingestDefinitionEditorState.generateElementGrammar();
|
260
262
|
}, [ingestDefinitionEditorState]);
|
261
263
|
|
264
|
+
useApplicationNavigationContext(
|
265
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.INGEST_DEFINITION_EDITOR,
|
266
|
+
);
|
267
|
+
|
262
268
|
useEffect(() => {
|
263
269
|
if (ingestDefinitionEditorState.deployOnOpen) {
|
264
270
|
flowResult(ingestDefinitionEditorState.init_with_deploy(auth)).catch(
|
@@ -540,6 +540,7 @@ export class GraphEditFormModeState extends GraphEditorMode {
|
|
540
540
|
this.editorStore.graphState.error = error;
|
541
541
|
this.editorStore.applicationStore.notificationService.notifyWarning(
|
542
542
|
`Compilation failed: ${error.message}`,
|
543
|
+
error.trace,
|
543
544
|
);
|
544
545
|
this.editorStore.graphState.setMostRecentCompilationOutcome(
|
545
546
|
GraphCompilationOutcome.FAILED,
|
@@ -449,6 +449,7 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
|
|
449
449
|
this.editorStore.graphState.setMostRecentCompilationGraphHash(
|
450
450
|
currentGraphHash,
|
451
451
|
);
|
452
|
+
let detail: string | undefined = undefined;
|
452
453
|
if (error instanceof EngineError) {
|
453
454
|
this.editorStore.graphState.error = error;
|
454
455
|
if (error.sourceInformation) {
|
@@ -457,6 +458,7 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
|
|
457
458
|
column: error.sourceInformation.startColumn,
|
458
459
|
});
|
459
460
|
}
|
461
|
+
detail = error.trace;
|
460
462
|
}
|
461
463
|
if (
|
462
464
|
!this.editorStore.applicationStore.notificationService.notification ||
|
@@ -464,6 +466,7 @@ export class GraphEditGrammarModeState extends GraphEditorMode {
|
|
464
466
|
) {
|
465
467
|
this.editorStore.applicationStore.notificationService.notifyWarning(
|
466
468
|
`Compilation failed: ${error.message}`,
|
469
|
+
detail,
|
467
470
|
);
|
468
471
|
}
|
469
472
|
this.editorStore.graphState.setMostRecentCompilationOutcome(
|
@@ -968,7 +968,11 @@ export class LakehouseRuntimeEditorState extends EngineRuntimeEditorState {
|
|
968
968
|
token,
|
969
969
|
)) as unknown as IngestDeploymentServerConfig[] | undefined;
|
970
970
|
this.setEnvSummaries(res);
|
971
|
-
if (
|
971
|
+
if (
|
972
|
+
this.lakehouseRuntimeType === LakehouseRuntimeType.ENVIRONMENT &&
|
973
|
+
!this.runtimeValue.environment &&
|
974
|
+
this.envOptions.length
|
975
|
+
) {
|
972
976
|
this.runtimeValue.environment = this.envOptions[0]?.value;
|
973
977
|
}
|
974
978
|
}
|
package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts
CHANGED
@@ -32,7 +32,14 @@ import {
|
|
32
32
|
} from '@finos/legend-graph';
|
33
33
|
import type { EditorStore } from '../../../EditorStore.js';
|
34
34
|
import { ElementEditorState } from '../ElementEditorState.js';
|
35
|
-
import {
|
35
|
+
import {
|
36
|
+
action,
|
37
|
+
computed,
|
38
|
+
flow,
|
39
|
+
makeObservable,
|
40
|
+
observable,
|
41
|
+
runInAction,
|
42
|
+
} from 'mobx';
|
36
43
|
import {
|
37
44
|
guaranteeType,
|
38
45
|
addUniqueEntry,
|
@@ -391,8 +398,10 @@ export class DataProductEditorState extends ElementEditorState {
|
|
391
398
|
|
392
399
|
deleteAccessPointGroup(val: AccessPointGroupState): void {
|
393
400
|
const state = this.accessPointGroupStates.find((a) => a === val);
|
394
|
-
|
395
|
-
|
401
|
+
runInAction(() => {
|
402
|
+
deleteEntry(this.accessPointGroupStates, state);
|
403
|
+
dataProduct_deleteAccessPointGroup(this.product, val.value);
|
404
|
+
});
|
396
405
|
}
|
397
406
|
|
398
407
|
*deploy(token: string | undefined): GeneratorFn<void> {
|
@@ -18,8 +18,12 @@ import {
|
|
18
18
|
type AccessPoint,
|
19
19
|
type AccessPointGroup,
|
20
20
|
type DataProduct,
|
21
|
+
type Email,
|
21
22
|
observe_AccessPoint,
|
22
23
|
observe_AccessPointGroup,
|
24
|
+
observe_SupportInfo,
|
25
|
+
observe_Email,
|
26
|
+
SupportInfo,
|
23
27
|
} from '@finos/legend-graph';
|
24
28
|
import { addUniqueEntry, deleteEntry } from '@finos/legend-shared';
|
25
29
|
|
@@ -75,3 +79,50 @@ export const dataProduct_setDescription = action(
|
|
75
79
|
product.description = description;
|
76
80
|
},
|
77
81
|
);
|
82
|
+
|
83
|
+
export const dataProduct_setSupportInfoIfAbsent = action(
|
84
|
+
(product: DataProduct) => {
|
85
|
+
if (!product.supportInfo) {
|
86
|
+
product.supportInfo = observe_SupportInfo(new SupportInfo());
|
87
|
+
}
|
88
|
+
},
|
89
|
+
);
|
90
|
+
|
91
|
+
export const supportInfo_setDocumentationUrl = action(
|
92
|
+
(supportInfo: SupportInfo, documentationUrl: string) => {
|
93
|
+
supportInfo.documentationUrl = documentationUrl;
|
94
|
+
},
|
95
|
+
);
|
96
|
+
|
97
|
+
export const supportInfo_setWebsite = action(
|
98
|
+
(supportInfo: SupportInfo, website: string) => {
|
99
|
+
supportInfo.website = website;
|
100
|
+
},
|
101
|
+
);
|
102
|
+
|
103
|
+
export const supportInfo_setFaqUrl = action(
|
104
|
+
(supportInfo: SupportInfo, faqUrl: string) => {
|
105
|
+
supportInfo.faqUrl = faqUrl;
|
106
|
+
},
|
107
|
+
);
|
108
|
+
|
109
|
+
export const supportInfo_setSupportUrl = action(
|
110
|
+
(supportInfo: SupportInfo, supportUrl: string) => {
|
111
|
+
supportInfo.supportUrl = supportUrl;
|
112
|
+
},
|
113
|
+
);
|
114
|
+
|
115
|
+
export const supportInfo_addEmail = action(
|
116
|
+
(supportInfo: SupportInfo, email: Email) => {
|
117
|
+
addUniqueEntry(supportInfo.emails, observe_Email(email));
|
118
|
+
},
|
119
|
+
);
|
120
|
+
|
121
|
+
export const supportInfo_deleteEmail = action(
|
122
|
+
(supportInfo: SupportInfo, email: Email): void => {
|
123
|
+
const index = supportInfo.emails.indexOf(email);
|
124
|
+
if (index !== -1) {
|
125
|
+
supportInfo.emails.splice(index, 1);
|
126
|
+
}
|
127
|
+
},
|
128
|
+
);
|