@finos/legend-application-studio 28.19.22 → 28.19.23
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/components/editor/editor-group/dataProduct/DataPoductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.js +63 -14
- package/lib/components/editor/editor-group/dataProduct/DataPoductEditor.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/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts +2 -0
- 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 +6 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/package.json +7 -7
- package/src/components/editor/editor-group/dataProduct/DataPoductEditor.tsx +165 -14
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +8 -0
@@ -70,6 +70,7 @@ import {
|
|
70
70
|
EyeIcon,
|
71
71
|
CloseEyeIcon,
|
72
72
|
Checkbox,
|
73
|
+
BugIcon,
|
73
74
|
} from '@finos/legend-art';
|
74
75
|
import React, {
|
75
76
|
useRef,
|
@@ -90,6 +91,9 @@ import {
|
|
90
91
|
type DataProduct,
|
91
92
|
type LakehouseAccessPoint,
|
92
93
|
StereotypeExplicitReference,
|
94
|
+
type V1_DataProductArtifactAccessPointGroup,
|
95
|
+
type V1_DataProductArtifactAccessPointImplementation,
|
96
|
+
type V1_DataProductArtifactGeneration,
|
93
97
|
} from '@finos/legend-graph';
|
94
98
|
import {
|
95
99
|
accessPointGroup_setDescription,
|
@@ -162,6 +166,7 @@ const HoverTextArea: React.FC<HoverTextAreaProps> = ({
|
|
162
166
|
onMouseOver={handleMouseOver}
|
163
167
|
onMouseOut={handleMouseOut}
|
164
168
|
className={clsx(className)}
|
169
|
+
style={{ whiteSpace: 'pre-line' }}
|
165
170
|
>
|
166
171
|
{text}
|
167
172
|
</div>
|
@@ -190,7 +195,7 @@ const AccessPointTitle = observer(
|
|
190
195
|
};
|
191
196
|
const updateAccessPointName: React.ChangeEventHandler<HTMLTextAreaElement> =
|
192
197
|
action((event) => {
|
193
|
-
if (
|
198
|
+
if (event.target.value.match(/^[0-9a-zA-Z_]+$/)) {
|
194
199
|
accessPoint.id = event.target.value;
|
195
200
|
}
|
196
201
|
});
|
@@ -211,8 +216,13 @@ const AccessPointTitle = observer(
|
|
211
216
|
}}
|
212
217
|
/>
|
213
218
|
) : (
|
214
|
-
<div
|
215
|
-
|
219
|
+
<div
|
220
|
+
className="access-point-editor__name__label"
|
221
|
+
onClick={handleNameEdit}
|
222
|
+
title="Click to edit access point title"
|
223
|
+
style={{ flex: '1 1 auto' }}
|
224
|
+
>
|
225
|
+
{accessPoint.id}
|
216
226
|
</div>
|
217
227
|
);
|
218
228
|
},
|
@@ -225,7 +235,7 @@ const AccessPointClassification = observer(
|
|
225
235
|
}) => {
|
226
236
|
const { accessPoint, groupState } = props;
|
227
237
|
const applicationStore = useEditorStore().applicationStore;
|
228
|
-
const CHOOSE_CLASSIFICATION = '
|
238
|
+
const CHOOSE_CLASSIFICATION = 'Classification';
|
229
239
|
const updateAccessPointClassificationTextbox: React.ChangeEventHandler<HTMLTextAreaElement> =
|
230
240
|
action((event) => {
|
231
241
|
accessPoint.classification = event.target.value;
|
@@ -282,7 +292,15 @@ const AccessPointClassification = observer(
|
|
282
292
|
return (
|
283
293
|
<div className="access-point-editor__classification">
|
284
294
|
{classificationOptions.length > 1 ? (
|
285
|
-
<div
|
295
|
+
<div
|
296
|
+
style={{
|
297
|
+
borderWidth: 'thin',
|
298
|
+
borderColor:
|
299
|
+
currentClassification.label === CHOOSE_CLASSIFICATION
|
300
|
+
? 'var(--color-red-300)'
|
301
|
+
: 'transparent',
|
302
|
+
}}
|
303
|
+
>
|
286
304
|
<CustomSelectorInput
|
287
305
|
className="explorer__new-element-modal__driver__dropdown"
|
288
306
|
options={classificationOptions}
|
@@ -323,6 +341,62 @@ const AccessPointClassification = observer(
|
|
323
341
|
},
|
324
342
|
);
|
325
343
|
|
344
|
+
const AccessPointGenerationViewer = observer(
|
345
|
+
(props: {
|
346
|
+
accessPointState: LakehouseAccessPointState;
|
347
|
+
generationOutput: string;
|
348
|
+
}) => {
|
349
|
+
const { accessPointState, generationOutput } = props;
|
350
|
+
const editorStore = accessPointState.state.state.editorStore;
|
351
|
+
const closeDebug = (): void => {
|
352
|
+
accessPointState.setShowDebug(false);
|
353
|
+
};
|
354
|
+
|
355
|
+
return (
|
356
|
+
<Dialog
|
357
|
+
open={accessPointState.showDebug}
|
358
|
+
onClose={closeDebug}
|
359
|
+
classes={{
|
360
|
+
root: 'editor-modal__root-container',
|
361
|
+
container: 'editor-modal__container',
|
362
|
+
paper: 'editor-modal__content',
|
363
|
+
}}
|
364
|
+
>
|
365
|
+
<Modal
|
366
|
+
className="editor-modal"
|
367
|
+
darkMode={
|
368
|
+
!editorStore.applicationStore.layoutService
|
369
|
+
.TEMPORARY__isLightColorThemeEnabled
|
370
|
+
}
|
371
|
+
>
|
372
|
+
<ModalHeader
|
373
|
+
title={`${accessPointState.accessPoint.id} Plan Generation`}
|
374
|
+
/>
|
375
|
+
<ModalBody>
|
376
|
+
<div className="panel__content execution-plan-viewer__panel__content">
|
377
|
+
<CodeEditor
|
378
|
+
inputValue={generationOutput}
|
379
|
+
isReadOnly={true}
|
380
|
+
language={CODE_EDITOR_LANGUAGE.JSON}
|
381
|
+
hidePadding={true}
|
382
|
+
hideMinimap={true}
|
383
|
+
/>
|
384
|
+
</div>
|
385
|
+
</ModalBody>
|
386
|
+
<ModalFooter>
|
387
|
+
<ModalFooterButton
|
388
|
+
title="Close plan generation modal"
|
389
|
+
onClick={closeDebug}
|
390
|
+
text="Close"
|
391
|
+
type="secondary"
|
392
|
+
/>
|
393
|
+
</ModalFooter>
|
394
|
+
</Modal>
|
395
|
+
</Dialog>
|
396
|
+
);
|
397
|
+
},
|
398
|
+
);
|
399
|
+
|
326
400
|
export const LakehouseDataProductAcccessPointEditor = observer(
|
327
401
|
(props: {
|
328
402
|
accessPointState: LakehouseAccessPointState;
|
@@ -339,6 +413,7 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
339
413
|
const [editingDescription, setEditingDescription] = useState(false);
|
340
414
|
const [isHovering, setIsHovering] = useState(false);
|
341
415
|
const ref = useRef<HTMLDivElement>(null);
|
416
|
+
const [debugOutput, setDebugOutput] = useState('');
|
342
417
|
|
343
418
|
const handleDescriptionEdit = () => setEditingDescription(true);
|
344
419
|
const handleDescriptionBlur = () => {
|
@@ -361,6 +436,51 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
361
436
|
},
|
362
437
|
);
|
363
438
|
|
439
|
+
const debugPlanGeneration = async (): Promise<void> => {
|
440
|
+
try {
|
441
|
+
const generatedArtifacts =
|
442
|
+
await editorStore.graphManagerState.graphManager.generateArtifacts(
|
443
|
+
editorStore.graphManagerState.graph,
|
444
|
+
editorStore.graphEditorMode.getGraphTextInputOption(),
|
445
|
+
[groupState.state.elementPath],
|
446
|
+
);
|
447
|
+
const dataProductExtension = 'dataProduct';
|
448
|
+
const dataProductArtifact = generatedArtifacts.values.filter(
|
449
|
+
(artifact) => artifact.extension === dataProductExtension,
|
450
|
+
);
|
451
|
+
const dataProductContent =
|
452
|
+
dataProductArtifact[0]?.artifactsByExtensionElements[0]?.files[0]
|
453
|
+
?.content ?? null;
|
454
|
+
|
455
|
+
if (dataProductContent) {
|
456
|
+
const contentJson = JSON.parse(
|
457
|
+
dataProductContent,
|
458
|
+
) as V1_DataProductArtifactGeneration;
|
459
|
+
const apPlanGeneration = contentJson.accessPointGroups
|
460
|
+
.find(
|
461
|
+
(group: V1_DataProductArtifactAccessPointGroup) =>
|
462
|
+
group.id === groupState.value.id,
|
463
|
+
)
|
464
|
+
?.accessPointImplementations.find(
|
465
|
+
(
|
466
|
+
apImplementation: V1_DataProductArtifactAccessPointImplementation,
|
467
|
+
) => apImplementation.id === accessPoint.id,
|
468
|
+
);
|
469
|
+
|
470
|
+
setDebugOutput(JSON.stringify(apPlanGeneration, null, 2));
|
471
|
+
accessPointState.setShowDebug(true);
|
472
|
+
} else {
|
473
|
+
throw new Error(
|
474
|
+
'Could not find contents of this data product artifact',
|
475
|
+
);
|
476
|
+
}
|
477
|
+
} catch (error) {
|
478
|
+
editorStore.applicationStore.notificationService.notifyError(
|
479
|
+
`Failed to fetch access point plan generation: ${error}`,
|
480
|
+
);
|
481
|
+
}
|
482
|
+
};
|
483
|
+
|
364
484
|
const handleRemoveAccessPoint = (): void => {
|
365
485
|
editorStore.applicationStore.alertService.setActionAlertInfo({
|
366
486
|
message: `Are you sure you want to delete Access Point ${accessPoint.id}?`,
|
@@ -461,7 +581,19 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
461
581
|
style={{ padding: 0, margin: 0 }}
|
462
582
|
/>
|
463
583
|
<Tooltip
|
464
|
-
title=
|
584
|
+
title={
|
585
|
+
<div
|
586
|
+
style={{
|
587
|
+
maxWidth: '400px',
|
588
|
+
whiteSpace: 'normal',
|
589
|
+
wordWrap: 'break-word',
|
590
|
+
}}
|
591
|
+
>
|
592
|
+
Marking as "reproducible" means consumers can
|
593
|
+
consistently retrieve the exact historical data as it
|
594
|
+
existed at any specific Lakehouse batch.
|
595
|
+
</div>
|
596
|
+
}
|
465
597
|
arrow={true}
|
466
598
|
placement={'top'}
|
467
599
|
>
|
@@ -526,10 +658,11 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
526
658
|
placeholder="Access Point description"
|
527
659
|
onBlur={handleDescriptionBlur}
|
528
660
|
style={{
|
529
|
-
|
530
|
-
resize: 'none',
|
661
|
+
resize: 'vertical',
|
531
662
|
padding: '0.25rem',
|
532
663
|
marginLeft: '0.5rem',
|
664
|
+
marginTop: '0.5rem',
|
665
|
+
height: 'auto',
|
533
666
|
}}
|
534
667
|
/>
|
535
668
|
) : (
|
@@ -573,18 +706,36 @@ export const LakehouseDataProductAcccessPointEditor = observer(
|
|
573
706
|
</div>
|
574
707
|
</div>
|
575
708
|
<button
|
576
|
-
className="access-point-editor__generic-entry__remove-
|
709
|
+
className="access-point-editor__generic-entry__remove-btn__debug"
|
577
710
|
onClick={() => {
|
578
|
-
|
711
|
+
debugPlanGeneration().catch(
|
712
|
+
editorStore.applicationStore.alertUnhandledError,
|
713
|
+
);
|
579
714
|
}}
|
580
715
|
tabIndex={-1}
|
581
|
-
title="
|
716
|
+
title="AP Plan Generation"
|
582
717
|
>
|
583
|
-
<
|
718
|
+
<BugIcon />
|
584
719
|
</button>
|
585
720
|
</div>
|
586
721
|
</div>
|
587
722
|
</div>
|
723
|
+
<button
|
724
|
+
className="access-point-editor__generic-entry__remove-btn"
|
725
|
+
onClick={() => {
|
726
|
+
handleRemoveAccessPoint();
|
727
|
+
}}
|
728
|
+
tabIndex={-1}
|
729
|
+
title="Remove"
|
730
|
+
>
|
731
|
+
<TimesIcon />
|
732
|
+
</button>
|
733
|
+
{accessPointState.showDebug && (
|
734
|
+
<AccessPointGenerationViewer
|
735
|
+
accessPointState={accessPointState}
|
736
|
+
generationOutput={debugOutput}
|
737
|
+
/>
|
738
|
+
)}
|
588
739
|
</div>
|
589
740
|
</PanelDnDEntry>
|
590
741
|
);
|
@@ -724,7 +875,7 @@ const AccessPointGroupEditor = observer(
|
|
724
875
|
setIsHoveringName(false);
|
725
876
|
};
|
726
877
|
const updateGroupName = (val: string): void => {
|
727
|
-
if (val
|
878
|
+
if (val.match(/^[0-9a-zA-Z_]+$/)) {
|
728
879
|
accessPointGroup_setName(groupState.value, val);
|
729
880
|
}
|
730
881
|
};
|
@@ -821,8 +972,8 @@ const AccessPointGroupEditor = observer(
|
|
821
972
|
onBlur={handleDescriptionBlur}
|
822
973
|
style={{
|
823
974
|
overflow: 'hidden',
|
824
|
-
resize: 'none',
|
825
975
|
padding: '0.25rem',
|
976
|
+
height: 'auto',
|
826
977
|
}}
|
827
978
|
/>
|
828
979
|
) : (
|
package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts
CHANGED
@@ -214,14 +214,22 @@ export class LakehouseAccessPointState extends AccessPointState {
|
|
214
214
|
declare accessPoint: LakehouseAccessPoint;
|
215
215
|
lambdaState: AccessPointLambdaEditorState;
|
216
216
|
|
217
|
+
showDebug = false;
|
218
|
+
|
217
219
|
constructor(val: LakehouseAccessPoint, editorState: AccessPointGroupState) {
|
218
220
|
super(val, editorState);
|
219
221
|
makeObservable(this, {
|
220
222
|
lambdaState: observable,
|
223
|
+
showDebug: observable,
|
224
|
+
setShowDebug: action,
|
221
225
|
});
|
222
226
|
this.accessPoint = val;
|
223
227
|
this.lambdaState = new AccessPointLambdaEditorState(this);
|
224
228
|
}
|
229
|
+
|
230
|
+
setShowDebug(value: boolean): void {
|
231
|
+
this.showDebug = value;
|
232
|
+
}
|
225
233
|
}
|
226
234
|
|
227
235
|
export class AccessPointGroupState {
|