@finos/legend-application-studio 28.4.4 → 28.5.1
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__/LegendStudioDocumentation.d.ts +1 -0
- package/lib/__lib__/LegendStudioDocumentation.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioDocumentation.js +1 -0
- package/lib/__lib__/LegendStudioDocumentation.js.map +1 -1
- package/lib/__lib__/LegendStudioNavigation.d.ts +12 -2
- package/lib/__lib__/LegendStudioNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioNavigation.js +92 -37
- package/lib/__lib__/LegendStudioNavigation.js.map +1 -1
- package/lib/components/LegendStudioWebApplication.d.ts.map +1 -1
- package/lib/components/LegendStudioWebApplication.js +6 -0
- package/lib/components/LegendStudioWebApplication.js.map +1 -1
- package/lib/components/editor/ActivityBar.js +1 -1
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/Editor.d.ts.map +1 -1
- package/lib/components/editor/Editor.js +10 -2
- package/lib/components/editor/Editor.js.map +1 -1
- package/lib/components/editor/StatusBar.d.ts.map +1 -1
- package/lib/components/editor/StatusBar.js +4 -1
- package/lib/components/editor/StatusBar.js.map +1 -1
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts.map +1 -1
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js +1 -1
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.js +6 -3
- package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts +4 -0
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
- package/lib/components/editor/side-bar/ProjectOverview.d.ts.map +1 -1
- package/lib/components/editor/side-bar/ProjectOverview.js +109 -7
- package/lib/components/editor/side-bar/ProjectOverview.js.map +1 -1
- package/lib/components/project-view/ProjectViewer.js +1 -1
- package/lib/components/project-view/ProjectViewer.js.map +1 -1
- package/lib/components/workspace-review/WorkspaceReview.js +1 -1
- package/lib/components/workspace-review/WorkspaceReview.js.map +1 -1
- package/lib/components/workspace-setup/CreateWorkspaceModal.d.ts +5 -1
- package/lib/components/workspace-setup/CreateWorkspaceModal.d.ts.map +1 -1
- package/lib/components/workspace-setup/CreateWorkspaceModal.js +34 -6
- package/lib/components/workspace-setup/CreateWorkspaceModal.js.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSelectorUtils.d.ts.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSelectorUtils.js +1 -1
- package/lib/components/workspace-setup/WorkspaceSelectorUtils.js.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts +1 -0
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.js +2 -1
- package/lib/components/workspace-setup/WorkspaceSetup.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/LegendStudioApplicationPlugin.d.ts +1 -1
- package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/editor/EditorSDLCState.d.ts +8 -2
- package/lib/stores/editor/EditorSDLCState.d.ts.map +1 -1
- package/lib/stores/editor/EditorSDLCState.js +29 -3
- package/lib/stores/editor/EditorSDLCState.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts +1 -1
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js +8 -5
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/StandardEditorMode.d.ts.map +1 -1
- package/lib/stores/editor/StandardEditorMode.js +1 -1
- package/lib/stores/editor/StandardEditorMode.js.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js +1 -1
- package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/ProjectOverviewState.d.ts +9 -3
- package/lib/stores/editor/sidebar-state/ProjectOverviewState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/ProjectOverviewState.js +71 -7
- package/lib/stores/editor/sidebar-state/ProjectOverviewState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceReviewState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceReviewState.js +6 -6
- package/lib/stores/editor/sidebar-state/WorkspaceReviewState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js +2 -2
- package/lib/stores/editor/sidebar-state/WorkspaceUpdaterState.js.map +1 -1
- package/lib/stores/workspace-review/WorkspaceReviewStore.d.ts +3 -1
- package/lib/stores/workspace-review/WorkspaceReviewStore.d.ts.map +1 -1
- package/lib/stores/workspace-review/WorkspaceReviewStore.js +13 -7
- package/lib/stores/workspace-review/WorkspaceReviewStore.js.map +1 -1
- package/lib/stores/workspace-setup/ProjectConfigurationStatus.d.ts +1 -1
- package/lib/stores/workspace-setup/ProjectConfigurationStatus.d.ts.map +1 -1
- package/lib/stores/workspace-setup/ProjectConfigurationStatus.js +2 -2
- package/lib/stores/workspace-setup/ProjectConfigurationStatus.js.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts +6 -2
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js +45 -12
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
- package/package.json +3 -3
- package/src/__lib__/LegendStudioDocumentation.ts +1 -0
- package/src/__lib__/LegendStudioNavigation.ts +106 -25
- package/src/components/LegendStudioWebApplication.tsx +6 -0
- package/src/components/editor/ActivityBar.tsx +1 -1
- package/src/components/editor/Editor.tsx +15 -2
- package/src/components/editor/StatusBar.tsx +5 -1
- package/src/components/editor/__test-utils__/EditorComponentTestUtils.tsx +1 -0
- package/src/components/editor/editor-group/GrammarTextEditor.tsx +6 -3
- package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +1 -1
- package/src/components/editor/side-bar/ProjectOverview.tsx +340 -8
- package/src/components/project-view/ProjectViewer.tsx +1 -1
- package/src/components/workspace-review/WorkspaceReview.tsx +1 -1
- package/src/components/workspace-setup/CreateWorkspaceModal.tsx +63 -4
- package/src/components/workspace-setup/WorkspaceSelectorUtils.tsx +13 -6
- package/src/components/workspace-setup/WorkspaceSetup.tsx +3 -0
- package/src/stores/LegendStudioApplicationPlugin.ts +1 -1
- package/src/stores/editor/EditorSDLCState.ts +45 -0
- package/src/stores/editor/EditorStore.ts +15 -2
- package/src/stores/editor/StandardEditorMode.ts +1 -0
- package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.ts +1 -0
- package/src/stores/editor/sidebar-state/ProjectOverviewState.ts +135 -1
- package/src/stores/editor/sidebar-state/WorkspaceReviewState.ts +6 -1
- package/src/stores/editor/sidebar-state/WorkspaceUpdaterState.ts +2 -0
- package/src/stores/workspace-review/WorkspaceReviewStore.ts +15 -1
- package/src/stores/workspace-setup/ProjectConfigurationStatus.ts +2 -0
- package/src/stores/workspace-setup/WorkspaceSetupStore.ts +71 -7
@@ -37,6 +37,7 @@ import {
|
|
37
37
|
ModalFooter,
|
38
38
|
MenuContentItem,
|
39
39
|
MenuContent,
|
40
|
+
PanelFormBooleanField,
|
40
41
|
} from '@finos/legend-art';
|
41
42
|
import { PROJECT_OVERVIEW_ACTIVITY_MODE } from '../../../stores/editor/sidebar-state/ProjectOverviewState.js';
|
42
43
|
import {
|
@@ -52,10 +53,24 @@ import {
|
|
52
53
|
NewVersionType,
|
53
54
|
WorkspaceType,
|
54
55
|
areWorkspacesEquivalent,
|
56
|
+
Review,
|
57
|
+
ReviewState,
|
58
|
+
Patch,
|
55
59
|
} from '@finos/legend-server-sdlc';
|
56
60
|
import { useEditorStore } from '../EditorStoreProvider.js';
|
57
61
|
import { useApplicationStore } from '@finos/legend-application';
|
58
62
|
import { useLegendStudioApplicationStore } from '../../LegendStudioFrameworkProvider.js';
|
63
|
+
import {
|
64
|
+
ActionState,
|
65
|
+
assertErrorThrown,
|
66
|
+
guaranteeNonNullable,
|
67
|
+
LogEvent,
|
68
|
+
} from '@finos/legend-shared';
|
69
|
+
import type { VersionOption } from '../editor-group/project-configuration-editor/ProjectDependencyEditor.js';
|
70
|
+
import { DocumentationLink } from '@finos/legend-lego/application';
|
71
|
+
import { LEGEND_STUDIO_DOCUMENTATION_KEY } from '../../../__lib__/LegendStudioDocumentation.js';
|
72
|
+
import type { PatchOption } from '../../workspace-setup/CreateWorkspaceModal.js';
|
73
|
+
import { LEGEND_STUDIO_APP_EVENT } from '../../../__lib__/LegendStudioEvent.js';
|
59
74
|
|
60
75
|
const ShareProjectModal = observer(
|
61
76
|
(props: { open: boolean; closeModal: () => void }) => {
|
@@ -180,10 +195,10 @@ const WorkspaceViewer = observer((props: { workspace: Workspace }) => {
|
|
180
195
|
const { workspace } = props;
|
181
196
|
const editorStore = useEditorStore();
|
182
197
|
const applicationStore = useApplicationStore();
|
183
|
-
const isActive =
|
184
|
-
editorStore.sdlcState.activeWorkspace,
|
185
|
-
workspace
|
186
|
-
|
198
|
+
const isActive =
|
199
|
+
areWorkspacesEquivalent(editorStore.sdlcState.activeWorkspace, workspace) &&
|
200
|
+
workspace.source ===
|
201
|
+
editorStore.sdlcState.activePatch?.patchReleaseVersionId.id;
|
187
202
|
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
|
188
203
|
useState(false);
|
189
204
|
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
@@ -210,6 +225,7 @@ const WorkspaceViewer = observer((props: { workspace: Workspace }) => {
|
|
210
225
|
applicationStore.navigationService.navigator.generateAddress(
|
211
226
|
generateEditorRoute(
|
212
227
|
workspace.projectId,
|
228
|
+
editorStore.sdlcState.activePatch?.patchReleaseVersionId.id,
|
213
229
|
workspace.workspaceId,
|
214
230
|
workspace.workspaceType,
|
215
231
|
),
|
@@ -226,9 +242,14 @@ const WorkspaceViewer = observer((props: { workspace: Workspace }) => {
|
|
226
242
|
<UserIcon />
|
227
243
|
)}
|
228
244
|
</div>
|
229
|
-
<div className="project-overview__item__link__content__name">
|
245
|
+
<div className="project-overview__item__link__content__name project-overview__workspace__viewer__label">
|
230
246
|
{workspace.workspaceId}
|
231
247
|
</div>
|
248
|
+
{workspace.source && (
|
249
|
+
<div className="project-overview__workspace__viewer__source">
|
250
|
+
{`patch/${workspace.source}`}
|
251
|
+
</div>
|
252
|
+
)}
|
232
253
|
</div>
|
233
254
|
</button>
|
234
255
|
</ContextMenu>
|
@@ -276,7 +297,7 @@ const WorkspacesViewer = observer(() => {
|
|
276
297
|
>
|
277
298
|
{workspaces.map((workspace) => (
|
278
299
|
<WorkspaceViewer
|
279
|
-
key={`${workspace.workspaceType}.${workspace.workspaceId}`}
|
300
|
+
key={`${workspace.workspaceType}.${workspace.workspaceId}.${workspace.source}`}
|
280
301
|
workspace={workspace}
|
281
302
|
/>
|
282
303
|
))}
|
@@ -324,7 +345,11 @@ const ReleaseEditor = observer(() => {
|
|
324
345
|
flowResult(projectOverviewState.fetchLatestProjectVersion()).catch(
|
325
346
|
applicationStore.alertUnhandledError,
|
326
347
|
);
|
327
|
-
}, [
|
348
|
+
}, [
|
349
|
+
applicationStore,
|
350
|
+
editorStore.sdlcState.activePatch,
|
351
|
+
projectOverviewState,
|
352
|
+
]);
|
328
353
|
|
329
354
|
return (
|
330
355
|
<div className="panel side-bar__panel project-overview__panel project-overview__release">
|
@@ -337,7 +362,11 @@ const ReleaseEditor = observer(() => {
|
|
337
362
|
</div>
|
338
363
|
<div className="panel__content project-overview__release__panel__content project-overview__release__content">
|
339
364
|
<PanelLoadingIndicator isLoading={isDispatchingAction} />
|
340
|
-
<div
|
365
|
+
<div
|
366
|
+
className={clsx(
|
367
|
+
'project-overview__release__editor project-overview__release__editor__project',
|
368
|
+
)}
|
369
|
+
>
|
341
370
|
<textarea
|
342
371
|
className="project-overview__release__editor__input input--dark"
|
343
372
|
spellCheck={false}
|
@@ -483,6 +512,306 @@ const ReleaseEditor = observer(() => {
|
|
483
512
|
);
|
484
513
|
});
|
485
514
|
|
515
|
+
const PatchEditor = observer(() => {
|
516
|
+
const editorStore = useEditorStore();
|
517
|
+
const applicationStore = useLegendStudioApplicationStore();
|
518
|
+
const projectOverviewState = editorStore.projectOverviewState;
|
519
|
+
const [versionOptions] = useState<VersionOption[]>(
|
520
|
+
editorStore.sdlcState.projectVersions.map((v) => ({
|
521
|
+
label: v.id.id,
|
522
|
+
value: v.id.id,
|
523
|
+
})),
|
524
|
+
);
|
525
|
+
const [selectedVersionOption, setSelectedVersionOption] =
|
526
|
+
useState<VersionOption | null>(null);
|
527
|
+
const patches = projectOverviewState.patches;
|
528
|
+
const [selectedPatchOption, setSelectedPatchOption] =
|
529
|
+
useState<PatchOption | null>(null);
|
530
|
+
const [workspaceName, setWorkspaceName] = useState<string>('');
|
531
|
+
const [isGroupWorkspace, setIsGroupWorkspace] = useState<boolean>(true);
|
532
|
+
const [committedReviews, setCommittedReviews] = useState<Review[]>([]);
|
533
|
+
const [fetchSelectedPatchCommittedReviews] = useState(ActionState.create());
|
534
|
+
const onPatchOptionChange = async (
|
535
|
+
val: PatchOption | null,
|
536
|
+
): Promise<void> => {
|
537
|
+
if (
|
538
|
+
(val !== null || selectedPatchOption !== null) &&
|
539
|
+
(!val || !selectedPatchOption || val.value !== selectedPatchOption.value)
|
540
|
+
) {
|
541
|
+
setSelectedPatchOption(val);
|
542
|
+
fetchSelectedPatchCommittedReviews.inProgress();
|
543
|
+
try {
|
544
|
+
if (val && val.value instanceof Patch) {
|
545
|
+
const reviews = await editorStore.sdlcServerClient.getReviews(
|
546
|
+
projectOverviewState.sdlcState.activeProject.projectId,
|
547
|
+
val.value.patchReleaseVersionId.id,
|
548
|
+
{
|
549
|
+
state: ReviewState.COMMITTED,
|
550
|
+
},
|
551
|
+
);
|
552
|
+
setCommittedReviews(
|
553
|
+
reviews.map((v) => Review.serialization.fromJson(v)),
|
554
|
+
);
|
555
|
+
} else {
|
556
|
+
setCommittedReviews([]);
|
557
|
+
}
|
558
|
+
} catch (error) {
|
559
|
+
assertErrorThrown(error);
|
560
|
+
editorStore.applicationStore.logService.error(
|
561
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
562
|
+
error,
|
563
|
+
);
|
564
|
+
} finally {
|
565
|
+
fetchSelectedPatchCommittedReviews.reset();
|
566
|
+
}
|
567
|
+
} else {
|
568
|
+
setCommittedReviews([]);
|
569
|
+
}
|
570
|
+
};
|
571
|
+
const onVersionOptionChange = (val: VersionOption | null): void => {
|
572
|
+
if (
|
573
|
+
(val !== null || selectedVersionOption !== null) &&
|
574
|
+
(!val ||
|
575
|
+
!selectedVersionOption ||
|
576
|
+
val.value !== selectedVersionOption.value)
|
577
|
+
) {
|
578
|
+
setSelectedVersionOption(val);
|
579
|
+
}
|
580
|
+
};
|
581
|
+
const createPatch = (): void => {
|
582
|
+
if (selectedVersionOption) {
|
583
|
+
flowResult(
|
584
|
+
projectOverviewState.createPatch(
|
585
|
+
selectedVersionOption.value,
|
586
|
+
workspaceName,
|
587
|
+
isGroupWorkspace ? WorkspaceType.GROUP : WorkspaceType.USER,
|
588
|
+
),
|
589
|
+
).catch(applicationStore.alertUnhandledError);
|
590
|
+
}
|
591
|
+
};
|
592
|
+
const toggleGroupWorkspace = (): void => {
|
593
|
+
setIsGroupWorkspace(!isGroupWorkspace);
|
594
|
+
};
|
595
|
+
const changeWorkspaceName: React.ChangeEventHandler<HTMLInputElement> = (
|
596
|
+
event,
|
597
|
+
) => setWorkspaceName(event.target.value);
|
598
|
+
const isDispatchingAction =
|
599
|
+
projectOverviewState.isFetchingLatestVersion ||
|
600
|
+
projectOverviewState.isFetchingCurrentProjectRevision ||
|
601
|
+
projectOverviewState.isCreatingVersion;
|
602
|
+
const { latestProjectVersion, currentProjectRevision } = projectOverviewState;
|
603
|
+
const createPatchRelease = applicationStore.guardUnhandledError(() =>
|
604
|
+
flowResult(
|
605
|
+
projectOverviewState.createPatchVersion(
|
606
|
+
guaranteeNonNullable(selectedPatchOption).label,
|
607
|
+
),
|
608
|
+
),
|
609
|
+
);
|
610
|
+
const isCurrentProjectVersionLatest =
|
611
|
+
Boolean(latestProjectVersion) &&
|
612
|
+
latestProjectVersion?.revisionId === currentProjectRevision?.id;
|
613
|
+
const canCreateVersion =
|
614
|
+
!isCurrentProjectVersionLatest &&
|
615
|
+
!isDispatchingAction &&
|
616
|
+
editorStore.sdlcServerClient.features.canCreateVersion;
|
617
|
+
const patchBlurb = `Releasing above mentioned version would delete the upstream branch created for doing this patch release. By doing so you won't be access any of the branches created for development for doing this patch release`;
|
618
|
+
|
619
|
+
useEffect(() => {
|
620
|
+
flowResult(projectOverviewState.fetchPatches()).catch(
|
621
|
+
applicationStore.alertUnhandledError,
|
622
|
+
);
|
623
|
+
}, [
|
624
|
+
applicationStore.alertUnhandledError,
|
625
|
+
applicationStore.notificationService,
|
626
|
+
editorStore.sdlcServerClient,
|
627
|
+
editorStore.sdlcState.activeProject.projectId,
|
628
|
+
|
629
|
+
projectOverviewState,
|
630
|
+
]);
|
631
|
+
|
632
|
+
return (
|
633
|
+
<div className="panel side-bar__panel project-overview__panel project-overview__patch">
|
634
|
+
<div className="panel__header">
|
635
|
+
<div className="panel__header__title">
|
636
|
+
<div className="panel__header__title__content">
|
637
|
+
Create Patch
|
638
|
+
<DocumentationLink
|
639
|
+
className="project-overview__patch__documentation"
|
640
|
+
documentationKey={LEGEND_STUDIO_DOCUMENTATION_KEY.CREATE_PATCH}
|
641
|
+
/>
|
642
|
+
</div>
|
643
|
+
</div>
|
644
|
+
</div>
|
645
|
+
<div className="panel__content project-overview__panel__content">
|
646
|
+
<div
|
647
|
+
className={clsx('project-overview__patch__create', {
|
648
|
+
'project-overview__patch__create--progress':
|
649
|
+
projectOverviewState.createPatchState.isInProgress,
|
650
|
+
})}
|
651
|
+
>
|
652
|
+
<PanelLoadingIndicator
|
653
|
+
isLoading={projectOverviewState.createPatchState.isInProgress}
|
654
|
+
/>
|
655
|
+
<div className="project-overview__patch__content__progress-msg">
|
656
|
+
{projectOverviewState.createPatchState.message}
|
657
|
+
</div>
|
658
|
+
<div className="panel__content__form">
|
659
|
+
<div className="panel__content__form__section">
|
660
|
+
<div className="panel__content__form__section__header__label">
|
661
|
+
Source Version
|
662
|
+
</div>
|
663
|
+
<CustomSelectorInput
|
664
|
+
className="project-overview__patch__source__version__selector"
|
665
|
+
options={versionOptions}
|
666
|
+
onChange={onVersionOptionChange}
|
667
|
+
value={selectedVersionOption}
|
668
|
+
placeholder={'Select source version'}
|
669
|
+
isClearable={true}
|
670
|
+
escapeClearsValue={true}
|
671
|
+
darkMode={true}
|
672
|
+
/>
|
673
|
+
</div>
|
674
|
+
</div>
|
675
|
+
<div className="panel__content__form">
|
676
|
+
<div className="panel__content__form__section">
|
677
|
+
<div className="panel__content__form__section__header__label">
|
678
|
+
Workspace Name
|
679
|
+
</div>
|
680
|
+
<input
|
681
|
+
className="panel__content__form__section__input"
|
682
|
+
title="Workspace Name"
|
683
|
+
spellCheck={false}
|
684
|
+
value={workspaceName}
|
685
|
+
placeholder="Workspace Name"
|
686
|
+
onChange={changeWorkspaceName}
|
687
|
+
/>
|
688
|
+
</div>
|
689
|
+
</div>
|
690
|
+
<div className="panel__content__form__section project-overview__patch__workspace__type__button">
|
691
|
+
<PanelFormBooleanField
|
692
|
+
name="Group Workspace"
|
693
|
+
prompt="Group workspaces can be accessed by all users in the project"
|
694
|
+
value={isGroupWorkspace}
|
695
|
+
isReadOnly={false}
|
696
|
+
update={toggleGroupWorkspace}
|
697
|
+
/>
|
698
|
+
</div>
|
699
|
+
<div className="panel__content__form__section__list__new-item__add">
|
700
|
+
<button
|
701
|
+
disabled={
|
702
|
+
projectOverviewState.createPatchState.isInProgress ||
|
703
|
+
!editorStore.sdlcServerClient.features.canCreateVersion ||
|
704
|
+
!selectedVersionOption
|
705
|
+
}
|
706
|
+
onClick={(): void => createPatch()}
|
707
|
+
className="panel__content__form__section__list__new-item__add-btn btn btn--dark project-overview__patch__create__button"
|
708
|
+
>
|
709
|
+
Create
|
710
|
+
</button>
|
711
|
+
</div>
|
712
|
+
</div>
|
713
|
+
<div className="project-overview__patch__release">
|
714
|
+
<div className="panel__header">
|
715
|
+
<div className="panel__header__title">
|
716
|
+
<div className="panel__header__title__content">Release Patch</div>
|
717
|
+
</div>
|
718
|
+
</div>
|
719
|
+
<div className="project-overview__patch__release">
|
720
|
+
<PanelLoadingIndicator isLoading={isDispatchingAction} />
|
721
|
+
<>
|
722
|
+
<div className="panel__content__form">
|
723
|
+
<div className="panel__content__form__section">
|
724
|
+
<div className="panel__content__form__section__header__label">
|
725
|
+
Patch
|
726
|
+
</div>
|
727
|
+
<CustomSelectorInput
|
728
|
+
className="project-overview__patch__source__version__selector"
|
729
|
+
options={patches.map((p) => ({
|
730
|
+
label: p.patchReleaseVersionId.id,
|
731
|
+
value: p,
|
732
|
+
}))}
|
733
|
+
onChange={onPatchOptionChange}
|
734
|
+
value={selectedPatchOption}
|
735
|
+
placeholder={'Select patch you want to release'}
|
736
|
+
isClearable={true}
|
737
|
+
escapeClearsValue={true}
|
738
|
+
darkMode={true}
|
739
|
+
/>
|
740
|
+
</div>
|
741
|
+
</div>
|
742
|
+
<div className="project-overview__patch__release__content">
|
743
|
+
{patchBlurb}
|
744
|
+
</div>
|
745
|
+
<div className="panel__content__form__section__list__new-item__add">
|
746
|
+
<button
|
747
|
+
className="panel__content__form__section__list__new-item__add-btn btn btn--dark project-overview__patch__release__button"
|
748
|
+
onClick={createPatchRelease}
|
749
|
+
disabled={!canCreateVersion && !selectedPatchOption}
|
750
|
+
title={'Create a patch release'}
|
751
|
+
>
|
752
|
+
Release
|
753
|
+
</button>
|
754
|
+
</div>
|
755
|
+
</>
|
756
|
+
</div>
|
757
|
+
</div>
|
758
|
+
|
759
|
+
<div className="project-overview__release__info">
|
760
|
+
<div className="panel project-overview__release__info__reviews">
|
761
|
+
<div className="panel__header">
|
762
|
+
<div className="panel__header__title">
|
763
|
+
<div className="panel__header__title__content">
|
764
|
+
COMMITTED REVIEWS
|
765
|
+
</div>
|
766
|
+
<div
|
767
|
+
className="side-bar__panel__title__info"
|
768
|
+
title="All committed reviews in the patch since it got created"
|
769
|
+
>
|
770
|
+
<InfoCircleIcon />
|
771
|
+
</div>
|
772
|
+
</div>
|
773
|
+
<div
|
774
|
+
className="side-bar__panel__header__changes-count"
|
775
|
+
data-testid={
|
776
|
+
LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT
|
777
|
+
}
|
778
|
+
>
|
779
|
+
{committedReviews.length}
|
780
|
+
</div>
|
781
|
+
</div>
|
782
|
+
<PanelContent>
|
783
|
+
{committedReviews.map((review) => (
|
784
|
+
<button
|
785
|
+
key={review.id}
|
786
|
+
className="side-bar__panel__item workspace-updater__review__link"
|
787
|
+
tabIndex={-1}
|
788
|
+
onClick={(): void =>
|
789
|
+
applicationStore.navigationService.navigator.visitAddress(
|
790
|
+
applicationStore.navigationService.navigator.generateAddress(
|
791
|
+
generateReviewRoute(review.projectId, review.id),
|
792
|
+
),
|
793
|
+
)
|
794
|
+
}
|
795
|
+
title="See review"
|
796
|
+
>
|
797
|
+
<div className="workspace-updater__review">
|
798
|
+
<span className="workspace-updater__review__name">
|
799
|
+
{review.title}
|
800
|
+
</span>
|
801
|
+
<span className="workspace-updater__review__info">
|
802
|
+
{review.author.name}
|
803
|
+
</span>
|
804
|
+
</div>
|
805
|
+
</button>
|
806
|
+
))}
|
807
|
+
</PanelContent>
|
808
|
+
</div>
|
809
|
+
</div>
|
810
|
+
</div>
|
811
|
+
</div>
|
812
|
+
);
|
813
|
+
});
|
814
|
+
|
486
815
|
const VersionsViewer = observer(() => {
|
487
816
|
const editorStore = useEditorStore();
|
488
817
|
const applicationStore = useLegendStudioApplicationStore();
|
@@ -815,6 +1144,7 @@ export const ProjectOverviewActivityBar = observer(() => {
|
|
815
1144
|
},
|
816
1145
|
{ mode: PROJECT_OVERVIEW_ACTIVITY_MODE.VERSIONS, title: 'Versions' },
|
817
1146
|
{ mode: PROJECT_OVERVIEW_ACTIVITY_MODE.WORKSPACES, title: 'Workspaces' },
|
1147
|
+
{ mode: PROJECT_OVERVIEW_ACTIVITY_MODE.PATCH, title: 'Patch' },
|
818
1148
|
]
|
819
1149
|
.filter((activity): activity is ProjectOverviewActivityDisplay =>
|
820
1150
|
Boolean(activity),
|
@@ -876,6 +1206,8 @@ export const ProjectOverview = observer(() => {
|
|
876
1206
|
return <VersionsViewer />;
|
877
1207
|
case PROJECT_OVERVIEW_ACTIVITY_MODE.WORKSPACES:
|
878
1208
|
return <WorkspacesViewer />;
|
1209
|
+
case PROJECT_OVERVIEW_ACTIVITY_MODE.PATCH:
|
1210
|
+
return <PatchEditor />;
|
879
1211
|
default:
|
880
1212
|
return null;
|
881
1213
|
}
|
@@ -115,7 +115,7 @@ const ProjectViewerStatusBar = observer(() => {
|
|
115
115
|
onClick={(): void =>
|
116
116
|
applicationStore.navigationService.navigator.visitAddress(
|
117
117
|
applicationStore.navigationService.navigator.generateAddress(
|
118
|
-
generateSetupRoute(projectId),
|
118
|
+
generateSetupRoute(projectId, undefined),
|
119
119
|
),
|
120
120
|
)
|
121
121
|
}
|
@@ -87,7 +87,7 @@ const WorkspaceReviewStatusBar = observer(() => {
|
|
87
87
|
onClick={(): void =>
|
88
88
|
applicationStore.navigationService.navigator.visitAddress(
|
89
89
|
applicationStore.navigationService.navigator.generateAddress(
|
90
|
-
generateSetupRoute(reviewStore.projectId),
|
90
|
+
generateSetupRoute(reviewStore.projectId, undefined),
|
91
91
|
),
|
92
92
|
)
|
93
93
|
}
|
@@ -25,14 +25,23 @@ import {
|
|
25
25
|
PanelDivider,
|
26
26
|
PanelForm,
|
27
27
|
PanelFormBooleanField,
|
28
|
+
CustomSelectorInput,
|
28
29
|
} from '@finos/legend-art';
|
29
30
|
import { flowResult } from 'mobx';
|
30
|
-
import { type Project, WorkspaceType } from '@finos/legend-server-sdlc';
|
31
|
+
import { type Project, WorkspaceType, Patch } from '@finos/legend-server-sdlc';
|
31
32
|
import { useApplicationStore } from '@finos/legend-application';
|
32
33
|
import { LEGEND_STUDIO_DOCUMENTATION_KEY } from '../../__lib__/LegendStudioDocumentation.js';
|
33
|
-
import {
|
34
|
+
import {
|
35
|
+
DEFAULT_WORKSPACE_SOURCE,
|
36
|
+
useWorkspaceSetupStore,
|
37
|
+
} from './WorkspaceSetup.js';
|
34
38
|
import { DocumentationLink } from '@finos/legend-lego/application';
|
35
39
|
|
40
|
+
export interface PatchOption {
|
41
|
+
label: string;
|
42
|
+
value: Patch | string;
|
43
|
+
}
|
44
|
+
|
36
45
|
export const CreateWorkspaceModal = observer(
|
37
46
|
(props: { selectedProject: Project }) => {
|
38
47
|
const { selectedProject } = props;
|
@@ -41,6 +50,35 @@ export const CreateWorkspaceModal = observer(
|
|
41
50
|
const workspaceNameInputRef = useRef<HTMLInputElement>(null);
|
42
51
|
const [workspaceName, setWorkspaceName] = useState('');
|
43
52
|
const [isGroupWorkspace, setIsGroupWorkspace] = useState<boolean>(true);
|
53
|
+
const [patchOptions] = useState<PatchOption[]>(
|
54
|
+
[
|
55
|
+
{
|
56
|
+
label: DEFAULT_WORKSPACE_SOURCE,
|
57
|
+
value: DEFAULT_WORKSPACE_SOURCE,
|
58
|
+
} as PatchOption,
|
59
|
+
].concat(
|
60
|
+
setupStore.patches.map((p) => ({
|
61
|
+
label: `patch/${p.patchReleaseVersionId.id}`,
|
62
|
+
value: p,
|
63
|
+
})),
|
64
|
+
),
|
65
|
+
);
|
66
|
+
const [selectedPatchOption, setSelectedPatchOption] =
|
67
|
+
useState<PatchOption | null>({
|
68
|
+
label: DEFAULT_WORKSPACE_SOURCE,
|
69
|
+
value: DEFAULT_WORKSPACE_SOURCE,
|
70
|
+
});
|
71
|
+
|
72
|
+
const onPatchOptionChange = (val: PatchOption | null): void => {
|
73
|
+
if (
|
74
|
+
(val !== null || selectedPatchOption !== null) &&
|
75
|
+
(!val ||
|
76
|
+
!selectedPatchOption ||
|
77
|
+
val.value !== selectedPatchOption.value)
|
78
|
+
) {
|
79
|
+
setSelectedPatchOption(val);
|
80
|
+
}
|
81
|
+
};
|
44
82
|
|
45
83
|
const workspaceAlreadyExists = Boolean(
|
46
84
|
setupStore.workspaces.find(
|
@@ -49,7 +87,12 @@ export const CreateWorkspaceModal = observer(
|
|
49
87
|
((workspace.workspaceType === WorkspaceType.GROUP &&
|
50
88
|
isGroupWorkspace) ||
|
51
89
|
(workspace.workspaceType === WorkspaceType.USER &&
|
52
|
-
!isGroupWorkspace))
|
90
|
+
!isGroupWorkspace)) &&
|
91
|
+
((!workspace.source &&
|
92
|
+
!(selectedPatchOption?.value instanceof Patch)) ||
|
93
|
+
(selectedPatchOption?.value instanceof Patch &&
|
94
|
+
workspace.source ===
|
95
|
+
selectedPatchOption.value.patchReleaseVersionId.id)),
|
53
96
|
),
|
54
97
|
);
|
55
98
|
const createWorkspace = (): void => {
|
@@ -60,6 +103,9 @@ export const CreateWorkspaceModal = observer(
|
|
60
103
|
flowResult(
|
61
104
|
setupStore.createWorkspace(
|
62
105
|
selectedProject.projectId,
|
106
|
+
selectedPatchOption?.value instanceof Patch
|
107
|
+
? selectedPatchOption.value.patchReleaseVersionId.id
|
108
|
+
: undefined,
|
63
109
|
workspaceName,
|
64
110
|
isGroupWorkspace ? WorkspaceType.GROUP : WorkspaceType.USER,
|
65
111
|
),
|
@@ -130,7 +176,20 @@ export const CreateWorkspaceModal = observer(
|
|
130
176
|
: ''
|
131
177
|
}
|
132
178
|
/>
|
133
|
-
|
179
|
+
<div className="workspace-setup__create-workspace-modal__form__workspace--source">
|
180
|
+
<div className="workspace-setup__create-workspace-modal__form__workspace--source__label">
|
181
|
+
Workspace Source
|
182
|
+
</div>
|
183
|
+
<CustomSelectorInput
|
184
|
+
className="workspace-setup__create-workspace-modal__form__workspace--source__selector"
|
185
|
+
options={patchOptions}
|
186
|
+
onChange={onPatchOptionChange}
|
187
|
+
value={selectedPatchOption}
|
188
|
+
isClearable={true}
|
189
|
+
escapeClearsValue={true}
|
190
|
+
darkMode={true}
|
191
|
+
/>
|
192
|
+
</div>
|
134
193
|
<PanelFormBooleanField
|
135
194
|
name="Group Workspace"
|
136
195
|
prompt="Group workspaces can be accessed by all users in the project"
|
@@ -33,13 +33,20 @@ export const formatWorkspaceOptionLabel = (
|
|
33
33
|
option: WorkspaceOption,
|
34
34
|
): React.ReactNode => (
|
35
35
|
<div className="workspace-selector__option">
|
36
|
-
<div className="workspace-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
<div className="workspace-selector__option__label">
|
37
|
+
<div className="workspace-selector__option__icon">
|
38
|
+
{option.value.workspaceType === WorkspaceType.GROUP ? (
|
39
|
+
<UsersIcon />
|
40
|
+
) : (
|
41
|
+
<UserIcon />
|
42
|
+
)}
|
43
|
+
</div>
|
44
|
+
<div className="workspace-selector__option__name">{option.label}</div>
|
45
|
+
</div>
|
46
|
+
<div className="workspace-selector__option__source">
|
47
|
+
{option.value.source && (
|
48
|
+
<div className="workspace-selector__option__source__patch">{`patch/${option.value.source}`}</div>
|
41
49
|
)}
|
42
50
|
</div>
|
43
|
-
<div className="workspace-selector__option__name">{option.label}</div>
|
44
51
|
</div>
|
45
52
|
);
|
@@ -62,6 +62,8 @@ const WorkspaceSetupStoreContext = createContext<
|
|
62
62
|
WorkspaceSetupStore | undefined
|
63
63
|
>(undefined);
|
64
64
|
|
65
|
+
export const DEFAULT_WORKSPACE_SOURCE = 'HEAD';
|
66
|
+
|
65
67
|
const WorkspaceSetupStoreProvider: React.FC<{
|
66
68
|
children: React.ReactNode;
|
67
69
|
}> = ({ children }) => {
|
@@ -175,6 +177,7 @@ export const WorkspaceSetup = withWorkspaceSetupStore(
|
|
175
177
|
applicationStore.navigationService.navigator.goToLocation(
|
176
178
|
generateEditorRoute(
|
177
179
|
setupStore.currentProject.projectId,
|
180
|
+
setupStore.currentWorkspace.source,
|
178
181
|
setupStore.currentWorkspace.workspaceId,
|
179
182
|
setupStore.currentWorkspace.workspaceType,
|
180
183
|
),
|
@@ -331,5 +331,5 @@ export interface DSL_LegendStudioApplicationPlugin_Extension
|
|
331
331
|
* Get a string of the Pure grammar element name for auto-folding the element
|
332
332
|
* (e.g. Diagram, or Text)
|
333
333
|
*/
|
334
|
-
|
334
|
+
getExtraGrammarTextEditorAutoFoldingElementCreatorKeywords?(): string[];
|
335
335
|
}
|