@finos/legend-application-studio 28.21.4 → 28.21.6

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 (100) hide show
  1. package/lib/__lib__/LegendStudioEvent.d.ts +4 -1
  2. package/lib/__lib__/LegendStudioEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioEvent.js +3 -0
  4. package/lib/__lib__/LegendStudioEvent.js.map +1 -1
  5. package/lib/__lib__/LegendStudioTelemetryHelper.d.ts +2 -1
  6. package/lib/__lib__/LegendStudioTelemetryHelper.d.ts.map +1 -1
  7. package/lib/__lib__/LegendStudioTelemetryHelper.js +11 -3
  8. package/lib/__lib__/LegendStudioTelemetryHelper.js.map +1 -1
  9. package/lib/__lib__/LegendStudioUserDataHelper.d.ts +41 -1
  10. package/lib/__lib__/LegendStudioUserDataHelper.d.ts.map +1 -1
  11. package/lib/__lib__/LegendStudioUserDataHelper.js +120 -1
  12. package/lib/__lib__/LegendStudioUserDataHelper.js.map +1 -1
  13. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts +1 -1
  14. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
  15. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js +3 -3
  16. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js.map +1 -1
  17. package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts +3 -0
  18. package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
  19. package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +13 -35
  20. package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
  21. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
  22. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +20 -7
  23. package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
  24. package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts.map +1 -1
  25. package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js +59 -22
  26. package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js.map +1 -1
  27. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -1
  28. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +113 -75
  29. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -1
  30. package/lib/components/editor/editor-group/testable/TestableSharedComponents.d.ts.map +1 -1
  31. package/lib/components/editor/editor-group/testable/TestableSharedComponents.js +2 -2
  32. package/lib/components/editor/editor-group/testable/TestableSharedComponents.js.map +1 -1
  33. package/lib/components/editor/side-bar/DevMetadataPanel.d.ts.map +1 -1
  34. package/lib/components/editor/side-bar/DevMetadataPanel.js +37 -6
  35. package/lib/components/editor/side-bar/DevMetadataPanel.js.map +1 -1
  36. package/lib/components/workspace-setup/RecentWorkspacesPanel.d.ts +22 -0
  37. package/lib/components/workspace-setup/RecentWorkspacesPanel.d.ts.map +1 -0
  38. package/lib/components/workspace-setup/RecentWorkspacesPanel.js +80 -0
  39. package/lib/components/workspace-setup/RecentWorkspacesPanel.js.map +1 -0
  40. package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
  41. package/lib/components/workspace-setup/WorkspaceSetup.js +61 -6
  42. package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
  43. package/lib/index.css +2 -2
  44. package/lib/index.css.map +1 -1
  45. package/lib/package.json +1 -1
  46. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  47. package/lib/stores/editor/EditorStore.js +31 -0
  48. package/lib/stores/editor/EditorStore.js.map +1 -1
  49. package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.d.ts +1 -1
  50. package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.d.ts.map +1 -1
  51. package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js +20 -48
  52. package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js.map +1 -1
  53. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts +9 -14
  54. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts.map +1 -1
  55. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js +125 -78
  56. package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js.map +1 -1
  57. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +18 -4
  58. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -1
  59. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +216 -53
  60. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -1
  61. package/lib/stores/editor/sidebar-state/ProjectOverviewState.d.ts.map +1 -1
  62. package/lib/stores/editor/sidebar-state/ProjectOverviewState.js +11 -0
  63. package/lib/stores/editor/sidebar-state/ProjectOverviewState.js.map +1 -1
  64. package/lib/stores/editor/sidebar-state/WorkspaceReviewState.d.ts.map +1 -1
  65. package/lib/stores/editor/sidebar-state/WorkspaceReviewState.js +11 -0
  66. package/lib/stores/editor/sidebar-state/WorkspaceReviewState.js.map +1 -1
  67. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts +9 -0
  68. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts.map +1 -1
  69. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js +57 -1
  70. package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js.map +1 -1
  71. package/lib/stores/project-reviewer/ProjectReviewerStore.d.ts.map +1 -1
  72. package/lib/stores/project-reviewer/ProjectReviewerStore.js +12 -0
  73. package/lib/stores/project-reviewer/ProjectReviewerStore.js.map +1 -1
  74. package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts +17 -0
  75. package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
  76. package/lib/stores/workspace-setup/WorkspaceSetupStore.js +61 -0
  77. package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
  78. package/package.json +16 -16
  79. package/src/__lib__/LegendStudioEvent.ts +3 -0
  80. package/src/__lib__/LegendStudioTelemetryHelper.ts +35 -11
  81. package/src/__lib__/LegendStudioUserDataHelper.ts +204 -1
  82. package/src/components/editor/editor-group/data-editor/EmbeddedDataEditor.tsx +4 -0
  83. package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +209 -187
  84. package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +26 -7
  85. package/src/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.tsx +149 -86
  86. package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +425 -308
  87. package/src/components/editor/editor-group/testable/TestableSharedComponents.tsx +3 -11
  88. package/src/components/editor/side-bar/DevMetadataPanel.tsx +194 -10
  89. package/src/components/workspace-setup/RecentWorkspacesPanel.tsx +161 -0
  90. package/src/components/workspace-setup/WorkspaceSetup.tsx +97 -8
  91. package/src/stores/editor/EditorStore.ts +44 -0
  92. package/src/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.ts +28 -50
  93. package/src/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.ts +164 -100
  94. package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +307 -72
  95. package/src/stores/editor/sidebar-state/ProjectOverviewState.ts +14 -0
  96. package/src/stores/editor/sidebar-state/WorkspaceReviewState.ts +14 -0
  97. package/src/stores/editor/sidebar-state/dev-metadata/DevMetadataState.ts +84 -1
  98. package/src/stores/project-reviewer/ProjectReviewerStore.ts +15 -0
  99. package/src/stores/workspace-setup/WorkspaceSetupStore.ts +93 -0
  100. package/tsconfig.json +1 -0
@@ -23,6 +23,7 @@ import {
23
23
  ContextMenu,
24
24
  CustomSelectorInput,
25
25
  Dialog,
26
+ ErrorWarnIcon,
26
27
  MenuContent,
27
28
  MenuContentItem,
28
29
  Modal,
@@ -61,7 +62,7 @@ import {
61
62
  TESTABLE_RESULT,
62
63
  getTestableResultFromTestResult,
63
64
  } from '../../../../../stores/editor/sidebar-state/testable/GlobalTestRunnerState.js';
64
- import { RelationElementEditor } from '../../data-editor/RelationElementsDataEditor.js';
65
+ import { RelationElementsDataEditor } from '../../data-editor/RelationElementsDataEditor.js';
65
66
  import { validateTestableId } from '../../../../../stores/editor/utils/TestableUtils.js';
66
67
  import { useEditorStore } from '../../../EditorStoreProvider.js';
67
68
  import { guaranteeNonNullable } from '@finos/legend-shared';
@@ -108,7 +109,7 @@ const CreateSuiteModal = observer(
108
109
  const accessPointOptions: ItemOption[] = testableState.ownAccessPoints.map(
109
110
  (ap) => ({
110
111
  value: ap.id,
111
- label: ap.title ? `${ap.title} (${ap.id})` : ap.id,
112
+ label: ap.id,
112
113
  }),
113
114
  );
114
115
  const selectedApOption =
@@ -171,9 +172,7 @@ const CreateSuiteModal = observer(
171
172
  </div>
172
173
  <div className="panel__content__form__section__header__prompt">
173
174
  Select the access point of the current DataProduct that the
174
- first test in this suite will verify. Input data will be
175
- inferred automatically from the access point&apos;s data
176
- sources.
175
+ first test in this suite will verify
177
176
  </div>
178
177
  <CustomSelectorInput
179
178
  options={accessPointOptions}
@@ -228,7 +227,7 @@ const CreateTestModal = observer(
228
227
  const accessPointOptions: ItemOption[] =
229
228
  suiteState.testableState.ownAccessPoints.map((ap) => ({
230
229
  value: ap.id,
231
- label: ap.title ? `${ap.title} (${ap.id})` : ap.id,
230
+ label: ap.id,
232
231
  }));
233
232
  const selectedApOption =
234
233
  accessPointOptions.find((o) => o.value === selectedAccessPointId) ?? null;
@@ -326,8 +325,9 @@ const ElementTestDataItem = observer(
326
325
  (props: {
327
326
  elementState: DataProductElementTestDataState;
328
327
  testDataState: DataProductTestDataState;
328
+ isReadOnly: boolean;
329
329
  }) => {
330
- const { elementState, testDataState } = props;
330
+ const { elementState, testDataState, isReadOnly } = props;
331
331
  const isActive =
332
332
  testDataState.selectedElementTestDataState === elementState;
333
333
 
@@ -346,77 +346,51 @@ const ElementTestDataItem = observer(
346
346
  tabIndex={-1}
347
347
  >
348
348
  <div className="testable-test-explorer__item__label__text">
349
- {elementState.elementName}
349
+ <span title={elementState.element.path}>
350
+ {elementState.element.name}
351
+ </span>
350
352
  </div>
353
+ {!isReadOnly && (
354
+ <div className="mapping-test-explorer__item__actions">
355
+ <button
356
+ className="mapping-test-explorer__item__action"
357
+ onClick={(e): void => {
358
+ e.stopPropagation();
359
+ testDataState.deleteElement(elementState);
360
+ }}
361
+ tabIndex={-1}
362
+ title="Delete"
363
+ >
364
+ <TimesIcon />
365
+ </button>
366
+ </div>
367
+ )}
351
368
  </div>
352
369
  </div>
353
370
  );
354
371
  },
355
372
  );
356
373
 
357
- // ──────────────────────────────────────────────────────────────────────────────
358
- // Element Test Data Editor — dataset tabs + CSV editor
359
- // ──────────────────────────────────────────────────────────────────────────────
360
-
361
374
  const ElementTestDataEditor = observer(
362
375
  (props: {
363
376
  elementState: DataProductElementTestDataState;
364
377
  isReadOnly: boolean;
365
378
  }) => {
366
379
  const { elementState, isReadOnly } = props;
367
- const configuredItems = elementState.configuredItems;
368
- const itemLabel = elementState.itemLabel;
380
+ const dataState = elementState.relationElementsDataState;
381
+
382
+ if (!dataState) {
383
+ return (
384
+ <BlankPanelContent>No relation data for this element</BlankPanelContent>
385
+ );
386
+ }
369
387
 
370
388
  return (
371
- <div className="service-test-data-editor panel">
372
- <div className="service-test-suite-editor__header">
373
- <div className="service-test-suite-editor__header__title">
374
- <div className="service-test-suite-editor__header__title__label">
375
- data
376
- </div>
377
- </div>
378
- </div>
379
- <div className="panel__content">
380
- {configuredItems.length > 0 ? (
381
- <div className="panel__content__form__section">
382
- <div className="panel__content__form__section__header__label">
383
- {itemLabel}s
384
- </div>
385
- <div className="uml-element-editor__tabs">
386
- {configuredItems.map((item) => (
387
- <div
388
- key={item.id}
389
- className={clsx('service-test-suite-editor__tab', {
390
- 'service-test-suite-editor__tab--active':
391
- item.id === elementState.selectedItemId,
392
- })}
393
- >
394
- <div
395
- className="mapping-editor__header__tab__content"
396
- onClick={(): void =>
397
- elementState.setSelectedItem(item.id)
398
- }
399
- tabIndex={-1}
400
- >
401
- <div>{item.label}</div>
402
- </div>
403
- </div>
404
- ))}
405
- </div>
406
- </div>
407
- ) : (
408
- <BlankPanelContent>No {itemLabel}s configured</BlankPanelContent>
409
- )}
410
- {elementState.relationElementState && (
411
- <div style={{ flex: 1, minHeight: 0, overflow: 'auto' }}>
412
- <RelationElementEditor
413
- relationElementState={elementState.relationElementState}
414
- isReadOnly={isReadOnly}
415
- />
416
- </div>
417
- )}
418
- </div>
419
- </div>
389
+ <RelationElementsDataEditor
390
+ dataState={dataState}
391
+ isReadOnly={isReadOnly}
392
+ hideColumnDefinitions={true}
393
+ />
420
394
  );
421
395
  },
422
396
  );
@@ -425,34 +399,126 @@ const ElementTestDataEditor = observer(
425
399
  // Test Data Editor (top panel) — always-visible elements sidebar + per-element editor
426
400
  // ──────────────────────────────────────────────────────────────────────────────
427
401
 
402
+ const AddElementModal = observer(
403
+ (props: { testDataState: DataProductTestDataState }) => {
404
+ const { testDataState } = props;
405
+ const applicationStore = testDataState.editorStore.applicationStore;
406
+ const options = testDataState.availableElementsToAdd.map((e) => ({
407
+ value: e.path,
408
+ label: e.path,
409
+ }));
410
+ const [selectedPath, setSelectedPath] = useState<string | undefined>(
411
+ options[0]?.value,
412
+ );
413
+ const close = (): void => testDataState.setShowAddElementModal(false);
414
+ const add = (): void => {
415
+ if (selectedPath) {
416
+ testDataState.addElement(selectedPath);
417
+ close();
418
+ }
419
+ };
420
+ const onChange = (val: { label: string; value: string } | null): void => {
421
+ setSelectedPath(val?.value);
422
+ };
423
+
424
+ return (
425
+ <Dialog
426
+ open={testDataState.showAddElementModal}
427
+ onClose={close}
428
+ classes={{ container: 'search-modal__container' }}
429
+ slotProps={{
430
+ paper: {
431
+ classes: { root: 'search-modal__inner-container' },
432
+ },
433
+ }}
434
+ >
435
+ <Modal
436
+ darkMode={
437
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
438
+ }
439
+ >
440
+ <ModalHeader>
441
+ <ModalTitle title="Add Element" />
442
+ </ModalHeader>
443
+ <ModalBody>
444
+ <CustomSelectorInput
445
+ className="panel__content__form__section__dropdown"
446
+ options={options}
447
+ onChange={onChange}
448
+ value={
449
+ selectedPath
450
+ ? { value: selectedPath, label: selectedPath }
451
+ : null
452
+ }
453
+ placeholder="Select element..."
454
+ darkMode={
455
+ !applicationStore.layoutService
456
+ .TEMPORARY__isLightColorThemeEnabled
457
+ }
458
+ />
459
+ </ModalBody>
460
+ <ModalFooter>
461
+ <ModalFooterButton
462
+ disabled={!selectedPath}
463
+ onClick={add}
464
+ text="Add"
465
+ />
466
+ <ModalFooterButton onClick={close} text="Close" type="secondary" />
467
+ </ModalFooter>
468
+ </Modal>
469
+ </Dialog>
470
+ );
471
+ },
472
+ );
473
+
428
474
  const DataProductTestDataEditor = observer(
429
475
  (props: { testDataState: DataProductTestDataState; isReadOnly: boolean }) => {
430
476
  const { testDataState, isReadOnly } = props;
431
477
 
478
+ const addElement = (): void => {
479
+ if (testDataState.availableElementsToAdd.length === 0) {
480
+ testDataState.editorStore.applicationStore.notificationService.notifyWarning(
481
+ 'No elements available to add',
482
+ );
483
+ return;
484
+ }
485
+ testDataState.setShowAddElementModal(true);
486
+ };
487
+
488
+ const hasTestData = testDataState.elementTestDataStates.length > 0;
489
+
432
490
  return (
433
- <div className="service-test-data-editor panel">
434
- <div className="service-test-suite-editor__header">
435
- <div className="service-test-suite-editor__header__title">
436
- <div className="service-test-suite-editor__header__title__label service-test-suite-editor__header__title__label--data">
437
- Test Data
438
- </div>
439
- </div>
440
- </div>
491
+ <div
492
+ className={clsx('service-test-data-editor panel', {
493
+ 'service-test-data-editor--no-data': !hasTestData,
494
+ })}
495
+ >
441
496
  <div className="service-test-data-editor__data">
442
497
  <ResizablePanelGroup orientation="vertical">
443
498
  {/* Left: elements list — always visible */}
444
499
  <ResizablePanel minSize={100} size={180}>
445
500
  <div className="binding-editor__header">
446
501
  <div className="binding-editor__header__title">
447
- <div className="binding-editor__header__title__label">
448
- elements
449
- </div>
502
+ <div className="panel__header__title__content">Test Data</div>
450
503
  </div>
504
+ {!isReadOnly && (
505
+ <div className="panel__header__actions">
506
+ <button
507
+ className="panel__header__action"
508
+ tabIndex={-1}
509
+ onClick={addElement}
510
+ title="Add Element"
511
+ >
512
+ <PlusIcon />
513
+ </button>
514
+ </div>
515
+ )}
451
516
  </div>
452
- {testDataState.elementTestDataStates.length === 0 ? (
453
- <BlankPanelContent>
454
- No data sources configured
455
- </BlankPanelContent>
517
+ {!hasTestData ? (
518
+ <div className="service-test-data-editor__warning">
519
+ <ErrorWarnIcon />
520
+ <span>Add an element to configure test data</span>
521
+ </div>
456
522
  ) : (
457
523
  <div>
458
524
  {testDataState.elementTestDataStates.map((elementState) => (
@@ -460,6 +526,7 @@ const DataProductTestDataEditor = observer(
460
526
  key={elementState.element.path}
461
527
  elementState={elementState}
462
528
  testDataState={testDataState}
529
+ isReadOnly={isReadOnly}
463
530
  />
464
531
  ))}
465
532
  </div>
@@ -483,6 +550,9 @@ const DataProductTestDataEditor = observer(
483
550
  </ResizablePanel>
484
551
  </ResizablePanelGroup>
485
552
  </div>
553
+ {testDataState.showAddElementModal && (
554
+ <AddElementModal testDataState={testDataState} />
555
+ )}
486
556
  </div>
487
557
  );
488
558
  },
@@ -611,13 +681,6 @@ const DataProductTestsEditor = observer(
611
681
 
612
682
  return (
613
683
  <div className="panel service-test-editor">
614
- <div className="service-test-suite-editor__header">
615
- <div className="service-test-suite-editor__header__title">
616
- <div className="service-test-suite-editor__header__title__label service-test-suite-editor__header__title__label--tests">
617
- tests
618
- </div>
619
- </div>
620
- </div>
621
684
  <div className="service-test-editor__content">
622
685
  <ResizablePanelGroup orientation="vertical">
623
686
  <ResizablePanel minSize={100} size={200}>
@@ -704,7 +767,7 @@ const DataProductTestSuiteEditor = observer(
704
767
  return (
705
768
  <div className="service-test-suite-editor">
706
769
  <ResizablePanelGroup orientation="horizontal">
707
- <ResizablePanel size={300} minSize={28}>
770
+ <ResizablePanel size={580} minSize={28}>
708
771
  <DataProductTestDataEditor
709
772
  testDataState={suiteState.testDataState}
710
773
  isReadOnly={isReadOnly}