@finos/legend-application-studio 28.18.137 → 28.18.139

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 (29) hide show
  1. package/lib/__lib__/LegendStudioEvent.d.ts +2 -1
  2. package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioEvent.js +2 -0
  4. package/lib/__lib__/LegendStudioEvent.js.map +1 -1
  5. package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.d.ts.map +1 -1
  6. package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.js +27 -6
  7. package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.js.map +1 -1
  8. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -1
  9. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +34 -15
  10. package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -1
  11. package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
  12. package/lib/components/editor/side-bar/CreateNewElementModal.js +6 -5
  13. package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
  14. package/lib/index.css +2 -2
  15. package/lib/index.css.map +1 -1
  16. package/lib/package.json +1 -1
  17. package/lib/stores/editor/NewElementState.js +1 -1
  18. package/lib/stores/editor/NewElementState.js.map +1 -1
  19. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +4 -3
  20. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -1
  21. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +41 -10
  22. package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -1
  23. package/package.json +6 -6
  24. package/src/__lib__/LegendStudioEvent.ts +3 -0
  25. package/src/components/editor/editor-group/dataProduct/DataPoductEditor.tsx +111 -20
  26. package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +101 -34
  27. package/src/components/editor/side-bar/CreateNewElementModal.tsx +5 -22
  28. package/src/stores/editor/NewElementState.ts +1 -1
  29. package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +72 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application-studio",
3
- "version": "28.18.137",
3
+ "version": "28.18.139",
4
4
  "description": "Legend Studio application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -47,11 +47,11 @@
47
47
  "dependencies": {
48
48
  "@finos/legend-application": "16.0.48",
49
49
  "@finos/legend-art": "7.1.102",
50
- "@finos/legend-code-editor": "2.0.79",
51
- "@finos/legend-data-cube": "0.2.11",
52
- "@finos/legend-graph": "32.1.37",
53
- "@finos/legend-lego": "2.0.84",
54
- "@finos/legend-query-builder": "4.16.45",
50
+ "@finos/legend-code-editor": "2.0.81",
51
+ "@finos/legend-data-cube": "0.2.13",
52
+ "@finos/legend-graph": "32.1.39",
53
+ "@finos/legend-lego": "2.0.86",
54
+ "@finos/legend-query-builder": "4.16.47",
55
55
  "@finos/legend-server-depot": "6.0.92",
56
56
  "@finos/legend-server-sdlc": "5.3.58",
57
57
  "@finos/legend-server-showcase": "0.2.54",
@@ -77,4 +77,7 @@ export enum LEGEND_STUDIO_APP_EVENT {
77
77
  TEXT_MODE_ACTION_KEYBOARD_SHORTCUT_GO_TO_DEFINITION__LAUNCH = 'editor.text-mode.action.keyboard.shortcut.go-to-element.launch',
78
78
  TEXT_MODE_ACTION_KEYBOARD_SHORTCUT_GO_TO_DEFINITION__ERROR = 'editor.text-mode.action.keyboard.shortcut.go-to-element.error',
79
79
  TEXT_MODE_ACTION_KEYBOARD_SHORTCUT_GO_TO_DEFINITION__SUCCESS = 'editor.text-mode.action.keyboard.shortcut.go-to-element.success',
80
+
81
+ // Ingestion
82
+ INGESTION_DEPLOY_SUCCESS_URN = 'editor.ingestion.deployment.success.urn',
80
83
  }
@@ -43,6 +43,11 @@ import {
43
43
  ModalFooter,
44
44
  ModalFooterButton,
45
45
  PencilEditIcon,
46
+ PanelFormTextField,
47
+ ControlledDropdownMenu,
48
+ MenuContent,
49
+ MenuContentItem,
50
+ CaretDownIcon,
46
51
  } from '@finos/legend-art';
47
52
  import React, { useRef, useState, useEffect } from 'react';
48
53
  import { filterByType } from '@finos/legend-shared';
@@ -51,7 +56,10 @@ import { action, flowResult } from 'mobx';
51
56
  import { useAuth } from 'react-oidc-context';
52
57
  import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
53
58
  import { CodeEditor } from '@finos/legend-lego/code-editor';
54
- import type { LakehouseAccessPoint } from '@finos/legend-graph';
59
+ import {
60
+ LakehouseTargetEnv,
61
+ type LakehouseAccessPoint,
62
+ } from '@finos/legend-graph';
55
63
 
56
64
  const NewAccessPointAccessPOint = observer(
57
65
  (props: { dataProductEditorState: DataProductEditorState }) => {
@@ -225,6 +233,12 @@ export const LakehouseDataProductAcccessPointEditor = observer(
225
233
  action((accessPoint.description = event.target.value));
226
234
  };
227
235
 
236
+ const updateAccessPointTargetEnvironment = action(
237
+ (targetEnvironment: LakehouseTargetEnv) => {
238
+ accessPoint.targetEnvironment = targetEnvironment;
239
+ },
240
+ );
241
+
228
242
  return (
229
243
  <div
230
244
  className={clsx('access-point-editor', {
@@ -268,11 +282,44 @@ export const LakehouseDataProductAcccessPointEditor = observer(
268
282
  <div className="access-point-editor__info">
269
283
  <div
270
284
  className={clsx('access-point-editor__type')}
271
- title={accessPoint.targetEnvironment}
285
+ title={'Change target environment'}
272
286
  >
273
287
  <div className="access-point-editor__type__label">
274
288
  {accessPoint.targetEnvironment}
275
289
  </div>
290
+ <div
291
+ style={{
292
+ background: 'transparent',
293
+ height: '100%',
294
+ alignItems: 'center',
295
+ display: 'flex',
296
+ }}
297
+ >
298
+ <ControlledDropdownMenu
299
+ className="access-point-editor__dropdown"
300
+ content={
301
+ <MenuContent>
302
+ {Object.values(LakehouseTargetEnv).map((environment) => (
303
+ <MenuContentItem
304
+ key={environment}
305
+ className="btn__dropdown-combo__option"
306
+ onClick={() =>
307
+ updateAccessPointTargetEnvironment(environment)
308
+ }
309
+ >
310
+ {environment}
311
+ </MenuContentItem>
312
+ ))}
313
+ </MenuContent>
314
+ }
315
+ menuProps={{
316
+ anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
317
+ transformOrigin: { vertical: 'top', horizontal: 'right' },
318
+ }}
319
+ >
320
+ <CaretDownIcon />
321
+ </ControlledDropdownMenu>
322
+ </div>
276
323
  </div>
277
324
  </div>
278
325
  </div>
@@ -365,7 +412,7 @@ const DataProductDeploymentResponseModal = observer(
365
412
  className="editor-modal"
366
413
  >
367
414
  <ModalHeader>
368
- <ModalTitle title="Validation Error" />
415
+ <ModalTitle title="Data Product Deployment Response" />
369
416
  </ModalHeader>
370
417
  <ModalBody>
371
418
  <PanelContent>
@@ -430,6 +477,19 @@ export const DataProductEditor = observer(() => {
430
477
  }
431
478
  };
432
479
 
480
+ const updateDataProductTitle = action((val: string | undefined): void => {
481
+ if (val === undefined) {
482
+ return;
483
+ }
484
+ product.name = val;
485
+ });
486
+
487
+ const updateDataProductDescription = action(
488
+ (val: string | undefined): void => {
489
+ product.description = val;
490
+ },
491
+ );
492
+
433
493
  useEffect(() => {
434
494
  flowResult(dataProductEditorState.convertAccessPointsFuncObjects()).catch(
435
495
  dataProductEditorState.editorStore.applicationStore.alertUnhandledError,
@@ -459,7 +519,6 @@ export const DataProductEditor = observer(() => {
459
519
  </div>
460
520
  )}
461
521
  <div className="panel__header__title__label">data product</div>
462
- <div className="panel__header__title__content">{product.name}</div>
463
522
  </div>
464
523
  <PanelHeaderActions>
465
524
  <div className="btn__dropdown-combo btn__dropdown-combo--primary">
@@ -476,10 +535,26 @@ export const DataProductEditor = observer(() => {
476
535
  </div>
477
536
  </PanelHeaderActions>
478
537
  </div>
538
+ <div className="panel" style={{ padding: '1rem' }}>
539
+ <PanelFormTextField
540
+ name="Title"
541
+ value={product.name}
542
+ prompt="Provide a title for this Lakehouse Data Product."
543
+ update={updateDataProductTitle}
544
+ placeholder="Enter title"
545
+ />
546
+ <PanelFormTextField
547
+ name="Description"
548
+ value={product.description}
549
+ prompt="Provide a description for this Lakehouse Data Product."
550
+ update={updateDataProductDescription}
551
+ placeholder="Enter description"
552
+ />
553
+ </div>
479
554
  <div className="panel">
480
555
  <PanelHeader>
481
556
  <div className="panel__header__title">
482
- <div className="panel__header__title__content">ACCESS POINTS</div>
557
+ <div className="panel__header__title__label">access points</div>
483
558
  </div>
484
559
  <PanelHeaderActions>
485
560
  <PanelHeaderActionItem
@@ -492,22 +567,38 @@ export const DataProductEditor = observer(() => {
492
567
  </PanelHeaderActionItem>
493
568
  </PanelHeaderActions>
494
569
  </PanelHeader>
495
- <PanelContent>
496
- {accessPointStates
497
- .filter(filterByType(LakehouseAccessPointState))
498
- .map((apState) => (
499
- <LakehouseDataProductAcccessPointEditor
500
- key={apState.accessPoint.id}
501
- isReadOnly={isReadOnly}
502
- accessPointState={apState}
570
+ <div style={{ overflow: 'auto' }}>
571
+ <PanelContent>
572
+ {dataProductEditorState.accessPointGroupStates.map(
573
+ (groupState) => (
574
+ <div
575
+ key={groupState.value.id}
576
+ className="access-point-editor__group-container"
577
+ >
578
+ <div className="access-point-editor__group-container__title">
579
+ <div className="panel__header__title__content">
580
+ {groupState.value.id}
581
+ </div>
582
+ </div>
583
+ {groupState.accessPointStates
584
+ .filter(filterByType(LakehouseAccessPointState))
585
+ .map((apState) => (
586
+ <LakehouseDataProductAcccessPointEditor
587
+ key={apState.accessPoint.id}
588
+ isReadOnly={isReadOnly}
589
+ accessPointState={apState}
590
+ />
591
+ ))}
592
+ </div>
593
+ ),
594
+ )}
595
+ {!accessPointStates.length && (
596
+ <DataProductEditorSplashScreen
597
+ dataProductEditorState={dataProductEditorState}
503
598
  />
504
- ))}
505
- {!accessPointStates.length && (
506
- <DataProductEditorSplashScreen
507
- dataProductEditorState={dataProductEditorState}
508
- />
509
- )}
510
- </PanelContent>
599
+ )}
600
+ </PanelContent>
601
+ </div>
511
602
  {dataProductEditorState.accessPointModal && (
512
603
  <NewAccessPointAccessPOint
513
604
  dataProductEditorState={dataProductEditorState}
@@ -17,6 +17,8 @@
17
17
  import { observer } from 'mobx-react-lite';
18
18
  import { useEditorStore } from '../../EditorStoreProvider.js';
19
19
  import {
20
+ CheckCircleIcon,
21
+ CopyIcon,
20
22
  Dialog,
21
23
  Modal,
22
24
  ModalBody,
@@ -34,50 +36,91 @@ import {
34
36
  IngestDefinitionEditorState,
35
37
  } from '../../../../stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js';
36
38
  import { CodeEditor } from '@finos/legend-lego/code-editor';
37
- import { useEffect } from 'react';
39
+ import React, { useEffect } from 'react';
38
40
  import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
39
41
  import { flowResult } from 'mobx';
40
42
  import { useAuth } from 'react-oidc-context';
43
+ import {
44
+ type IngestDefinitionDeploymentResponse,
45
+ IngestDefinitionValidationResponse,
46
+ } from '../../../../stores/ingestion/IngestionDeploymentResponse.js';
41
47
 
42
- const IngestDepoymentModal = observer(
43
- (props: { state: IngestDefinitionEditorState }) => {
44
- const { state } = props;
48
+ const IngestValidationError = observer(
49
+ (props: {
50
+ state: IngestDefinitionEditorState;
51
+ validateResponse: IngestDefinitionValidationResponse;
52
+ }) => {
53
+ const { state, validateResponse } = props;
45
54
  const applicationStore = state.editorStore.applicationStore;
55
+ const closeModal = (): void =>
56
+ state.setValidateAndDeployResponse(undefined);
46
57
  return (
47
58
  <Dialog
48
- open={state.deploymentState.isInProgress}
49
- classes={{ container: 'search-modal__container' }}
59
+ open={true}
60
+ classes={{
61
+ root: 'editor-modal__root-container',
62
+ container: 'editor-modal__container',
63
+ paper: 'editor-modal__content',
64
+ }}
65
+ onClose={closeModal}
50
66
  >
51
67
  <Modal
52
68
  darkMode={
53
69
  !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
54
70
  }
55
- className="database-builder"
71
+ className="editor-modal"
56
72
  >
57
73
  <ModalHeader>
58
- <ModalTitle title="Deploy Ingestion" />
74
+ <ModalTitle title={'Validation Error'} />
59
75
  </ModalHeader>
60
76
  <ModalBody>
61
- <div>{state.deploymentState.message}</div>
77
+ <PanelContent>
78
+ <CodeEditor
79
+ inputValue={JSON.stringify(validateResponse, null, 2)}
80
+ isReadOnly={true}
81
+ language={CODE_EDITOR_LANGUAGE.JSON}
82
+ />
83
+ </PanelContent>
62
84
  </ModalBody>
85
+ <ModalFooter>
86
+ <ModalFooterButton
87
+ onClick={closeModal}
88
+ text="Close"
89
+ type="secondary"
90
+ />
91
+ </ModalFooter>
63
92
  </Modal>
64
93
  </Dialog>
65
94
  );
66
95
  },
67
96
  );
68
97
 
69
- const IngestValidationError = observer(
70
- (props: { state: IngestDefinitionEditorState }) => {
71
- const { state } = props;
98
+ // TODO: show full report i.e write envs etc
99
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
100
+ const IngestDeploymentResponseModal = observer(
101
+ (props: {
102
+ state: IngestDefinitionEditorState;
103
+ deploymentResponse: IngestDefinitionDeploymentResponse;
104
+ }) => {
105
+ const { state, deploymentResponse } = props;
72
106
  const applicationStore = state.editorStore.applicationStore;
73
- const validationError = state.validationError;
74
- if (!validationError) {
75
- return null;
76
- }
77
- const closeModal = (): void => state.setValError(undefined);
107
+ const closeModal = (): void =>
108
+ state.setValidateAndDeployResponse(undefined);
109
+ const copyURN = (text: string): void => {
110
+ state.editorStore.applicationStore.clipboardService
111
+ .copyTextToClipboard(text)
112
+ .then(() =>
113
+ state.editorStore.applicationStore.notificationService.notifySuccess(
114
+ 'Ingest URN copied to clipboard',
115
+ undefined,
116
+ 2500,
117
+ ),
118
+ )
119
+ .catch(state.editorStore.applicationStore.alertUnhandledError);
120
+ };
78
121
  return (
79
122
  <Dialog
80
- open={Boolean(state.validationError)}
123
+ open={true}
81
124
  classes={{
82
125
  root: 'editor-modal__root-container',
83
126
  container: 'editor-modal__container',
@@ -92,19 +135,34 @@ const IngestValidationError = observer(
92
135
  className="editor-modal"
93
136
  >
94
137
  <ModalHeader>
95
- <ModalTitle title="Validation Error" />
138
+ <ModalTitle
139
+ icon={<CheckCircleIcon />}
140
+ title="Deployment URN"
141
+ ></ModalTitle>
96
142
  </ModalHeader>
97
143
  <ModalBody>
98
144
  <PanelContent>
99
- <CodeEditor
100
- inputValue={JSON.stringify(
101
- state.validationError ?? {},
102
- null,
103
- 2,
104
- )}
105
- isReadOnly={true}
106
- language={CODE_EDITOR_LANGUAGE.JSON}
107
- />
145
+ <div>
146
+ <div>Ingestion URN</div>
147
+ <div>{deploymentResponse.ingestDefinitionUrn}</div>
148
+
149
+ <div className="data-space__viewer__quickstart__tds__query-text__actions">
150
+ <button
151
+ className="data-space__viewer__quickstart__tds__query-text__action"
152
+ tabIndex={-1}
153
+ title="Copy"
154
+ onClick={() => {
155
+ copyURN(deploymentResponse.ingestDefinitionUrn);
156
+ }}
157
+ >
158
+ <CopyIcon />
159
+ </button>
160
+ <button
161
+ className="data-space__viewer__quickstart__tds__query-text__action"
162
+ tabIndex={-1}
163
+ ></button>
164
+ </div>
165
+ </div>
108
166
  </PanelContent>
109
167
  </ModalBody>
110
168
  <ModalFooter>
@@ -153,6 +211,20 @@ export const IngestDefinitionEditor = observer(() => {
153
211
  }
154
212
  };
155
213
 
214
+ const renderDeploymentResponse = (): React.ReactNode => {
215
+ const response = ingestDefinitionEditorState.deploymentResponse;
216
+ if (response instanceof IngestDefinitionValidationResponse) {
217
+ return (
218
+ <IngestValidationError
219
+ state={ingestDefinitionEditorState}
220
+ validateResponse={response}
221
+ />
222
+ );
223
+ }
224
+
225
+ return null;
226
+ };
227
+
156
228
  const isValid = ingestDefinitionEditorState.validForDeployment;
157
229
  useEffect(() => {
158
230
  ingestDefinitionEditorState.generateElementGrammar();
@@ -202,12 +274,7 @@ export const IngestDefinitionEditor = observer(() => {
202
274
  language={CODE_EDITOR_LANGUAGE.PURE}
203
275
  />
204
276
  </PanelContent>
205
- {ingestDefinitionEditorState.deploymentState.isInProgress && (
206
- <IngestDepoymentModal state={ingestDefinitionEditorState} />
207
- )}
208
- {ingestDefinitionEditorState.validationError && (
209
- <IngestValidationError state={ingestDefinitionEditorState} />
210
- )}
277
+ {renderDeploymentResponse()}
211
278
  </PanelContent>
212
279
  </div>
213
280
  );
@@ -27,7 +27,6 @@ import {
27
27
  NewServiceDriver,
28
28
  CONNECTION_TYPE,
29
29
  type RuntimeOption,
30
- NewLakehouseDataProductDriver,
31
30
  } from '../../../stores/editor/NewElementState.js';
32
31
  import { Dialog, compareLabelFn, CustomSelectorInput } from '@finos/legend-art';
33
32
  import type { EditorStore } from '../../../stores/editor/EditorStore.js';
@@ -441,27 +440,11 @@ const NewServiceDriverEditor = observer(() => {
441
440
  });
442
441
 
443
442
  const NewLakehouseDataProductEditor = observer(() => {
444
- const editorStore = useEditorStore();
445
- const newProductDriver = editorStore.newElementState.getNewElementDriver(
446
- NewLakehouseDataProductDriver,
447
- );
448
- const handleTitleChangee: React.ChangeEventHandler<HTMLInputElement> = (
449
- event,
450
- ) => newProductDriver.setTitle(event.target.value);
451
- return (
452
- <>
453
- <div className="panel__content__form__section__header__label">Title</div>
454
- <div className="explorer__new-element-modal__driver">
455
- <input
456
- className="input--dark explorer__new-element-modal__name-input"
457
- spellCheck={false}
458
- value={newProductDriver.title}
459
- onChange={handleTitleChangee}
460
- placeholder={`Data Product Title`}
461
- />
462
- </div>
463
- </>
464
- );
443
+ // const editorStore = useEditorStore();
444
+ // const newProductDriver = editorStore.newElementState.getNewElementDriver(
445
+ // NewLakehouseDataProductDriver,
446
+ // );
447
+ return null;
465
448
  });
466
449
 
467
450
  const NewFileGenerationDriverEditor = observer(() => {
@@ -496,7 +496,7 @@ export class NewLakehouseDataProductDriver extends NewElementDriver<DataProduct>
496
496
  }
497
497
 
498
498
  override get isValid(): boolean {
499
- return Boolean(this.title);
499
+ return true;
500
500
  }
501
501
 
502
502
  setTitle(val: string) {
@@ -23,12 +23,21 @@ import {
23
23
  assertTrue,
24
24
  guaranteeNonNullable,
25
25
  guaranteeType,
26
+ LogEvent,
26
27
  removePrefix,
27
28
  type GeneratorFn,
28
29
  } from '@finos/legend-shared';
29
30
  import type { IngestionManager } from '../../../../ingestion/IngestionManager.js';
30
- import { action, flow, flowResult, makeObservable, observable } from 'mobx';
31
+ import {
32
+ action,
33
+ computed,
34
+ flow,
35
+ flowResult,
36
+ makeObservable,
37
+ observable,
38
+ } from 'mobx';
31
39
  import type {
40
+ IngestDefinitionDeploymentResponse,
32
41
  IngestDefinitionValidationResponse,
33
42
  ValidateAndDeploymentResponse,
34
43
  } from '../../../../ingestion/IngestionDeploymentResponse.js';
@@ -38,6 +47,11 @@ import {
38
47
  } from '../ElementEditorInitialConfiguration.js';
39
48
  import type { AuthContextProps } from 'react-oidc-context';
40
49
  import { EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig } from '../../../../../__lib__/LegendStudioNavigation.js';
50
+ import {
51
+ ActionAlertActionType,
52
+ ActionAlertType,
53
+ } from '@finos/legend-application';
54
+ import { LEGEND_STUDIO_APP_EVENT } from '../../../../../__lib__/LegendStudioEvent.js';
41
55
 
42
56
  const createEditorInitialConfiguration = (): EditorInitialConfiguration => {
43
57
  const config = new EditorInitialConfiguration();
@@ -63,7 +77,7 @@ export const generateUrlToDeployOnOpen = (
63
77
 
64
78
  const PARSER_SECTION = `###Lakehouse`;
65
79
  export class IngestDefinitionEditorState extends ElementEditorState {
66
- validationError: IngestDefinitionValidationResponse | undefined;
80
+ validateAndDeployResponse: ValidateAndDeploymentResponse | undefined;
67
81
  deploymentState = ActionState.create();
68
82
  deployOnOpen = false;
69
83
 
@@ -78,8 +92,9 @@ export class IngestDefinitionEditorState extends ElementEditorState {
78
92
  deploymentState: observable,
79
93
  deployOnOpen: observable,
80
94
  setDeployOnOpen: observable,
81
- validationError: observable,
82
- setValError: action,
95
+ validateAndDeployResponse: observable,
96
+ deploymentResponse: computed,
97
+ setValidateAndDeployResponse: action,
83
98
  init_with_deploy: flow,
84
99
  deploy: flow,
85
100
  });
@@ -89,12 +104,24 @@ export class IngestDefinitionEditorState extends ElementEditorState {
89
104
  }
90
105
  }
91
106
 
107
+ get deploymentResponse():
108
+ | IngestDefinitionDeploymentResponse
109
+ | IngestDefinitionValidationResponse
110
+ | undefined {
111
+ return (
112
+ this.validateAndDeployResponse?.deploymentResponse ??
113
+ this.validateAndDeployResponse?.validationResponse
114
+ );
115
+ }
116
+
92
117
  get ingestionManager(): IngestionManager | undefined {
93
118
  return this.editorStore.ingestionManager;
94
119
  }
95
120
 
96
- setValError(val: IngestDefinitionValidationResponse | undefined): void {
97
- this.validationError = val;
121
+ setValidateAndDeployResponse(
122
+ val: ValidateAndDeploymentResponse | undefined,
123
+ ): void {
124
+ this.validateAndDeployResponse = val;
98
125
  }
99
126
 
100
127
  setDeployOnOpen(value: boolean): void {
@@ -140,24 +167,57 @@ export class IngestDefinitionEditorState extends ElementEditorState {
140
167
  }),
141
168
  token,
142
169
  )) as unknown as ValidateAndDeploymentResponse;
170
+ this.editorStore.applicationStore.alertService.setBlockingAlert(
171
+ undefined,
172
+ );
143
173
  const deploymentResponse = response.deploymentResponse;
144
174
  if (deploymentResponse) {
145
- this.editorStore.applicationStore.notificationService.notifySuccess(
146
- `Ingest definition successfully deployed on ${deploymentResponse.ingestDefinitionUrn}`,
175
+ this.editorStore.applicationStore.logService.info(
176
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.INGESTION_DEPLOY_SUCCESS_URN),
177
+ deploymentResponse.ingestDefinitionUrn,
147
178
  );
179
+ this.editorStore.applicationStore.alertService.setActionAlertInfo({
180
+ title: `Ingest Definition Deployment`,
181
+ message: `Ingest definition deployed successfully. You may use URN for ingestion of Data`,
182
+ prompt: `${deploymentResponse.ingestDefinitionUrn}`,
183
+ type: ActionAlertType.STANDARD,
184
+ actions: [
185
+ {
186
+ label: 'Copy URN',
187
+ type: ActionAlertActionType.PROCEED,
188
+ handler: (): void => {
189
+ this.editorStore.applicationStore.clipboardService
190
+ .copyTextToClipboard(deploymentResponse.ingestDefinitionUrn)
191
+ .then(() =>
192
+ this.editorStore.applicationStore.notificationService.notifySuccess(
193
+ 'Ingest URN copied to clipboard',
194
+ undefined,
195
+ 2500,
196
+ ),
197
+ )
198
+ .catch(this.editorStore.applicationStore.alertUnhandledError);
199
+ },
200
+ default: true,
201
+ },
202
+ {
203
+ label: 'Close',
204
+ type: ActionAlertActionType.PROCEED_WITH_CAUTION,
205
+ },
206
+ ],
207
+ });
148
208
  } else {
149
- this.setValError(response.validationResponse);
209
+ this.setValidateAndDeployResponse(response);
150
210
  }
151
211
  } catch (error) {
212
+ this.editorStore.applicationStore.alertService.setBlockingAlert(
213
+ undefined,
214
+ );
152
215
  assertErrorThrown(error);
153
216
  this.editorStore.applicationStore.notificationService.notifyError(
154
217
  `Ingest definition failed to deploy: ${error.message}`,
155
218
  );
156
219
  } finally {
157
220
  this.deploymentState.complete();
158
- this.editorStore.applicationStore.alertService.setBlockingAlert(
159
- undefined,
160
- );
161
221
  }
162
222
  }
163
223