@finos/legend-application-studio 28.4.3 → 28.5.0
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/editor-group/service-editor/testable/ServiceTestsEditor.d.ts +2 -3
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js +9 -9
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js.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/element-editor-state/service/testable/ServiceTestEditorState.d.ts +5 -5
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js +19 -8
- package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.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 +7 -7
- 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/editor-group/service-editor/testable/ServiceTestsEditor.tsx +13 -14
- 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/element-editor-state/service/testable/ServiceTestEditorState.ts +31 -10
- 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
@@ -984,7 +984,8 @@ export const GrammarTextEditor = observer(() => {
|
|
984
984
|
(plugin) =>
|
985
985
|
(
|
986
986
|
plugin as DSL_LegendStudioApplicationPlugin_Extension
|
987
|
-
).
|
987
|
+
).getExtraGrammarTextEditorAutoFoldingElementCreatorKeywords?.() ??
|
988
|
+
[],
|
988
989
|
);
|
989
990
|
const foldingClass = editor?.getContribution('editor.contrib.folding');
|
990
991
|
|
@@ -1056,7 +1057,8 @@ export const GrammarTextEditor = observer(() => {
|
|
1056
1057
|
(plugin) =>
|
1057
1058
|
(
|
1058
1059
|
plugin as DSL_LegendStudioApplicationPlugin_Extension
|
1059
|
-
).
|
1060
|
+
).getExtraGrammarTextEditorAutoFoldingElementCreatorKeywords?.() ??
|
1061
|
+
[],
|
1060
1062
|
);
|
1061
1063
|
const foldingClass = editor.getContribution('editor.contrib.folding');
|
1062
1064
|
|
@@ -1110,7 +1112,8 @@ export const GrammarTextEditor = observer(() => {
|
|
1110
1112
|
(plugin) =>
|
1111
1113
|
(
|
1112
1114
|
plugin as DSL_LegendStudioApplicationPlugin_Extension
|
1113
|
-
).
|
1115
|
+
).getExtraGrammarTextEditorAutoFoldingElementCreatorKeywords?.() ??
|
1116
|
+
[],
|
1114
1117
|
);
|
1115
1118
|
const foldingClass = editor.getContribution('editor.contrib.folding');
|
1116
1119
|
|
package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx
CHANGED
@@ -97,7 +97,7 @@ import {
|
|
97
97
|
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
98
98
|
import { useEditorStore } from '../../EditorStoreProvider.js';
|
99
99
|
|
100
|
-
interface VersionOption {
|
100
|
+
export interface VersionOption {
|
101
101
|
label: string;
|
102
102
|
value: string;
|
103
103
|
}
|
@@ -43,7 +43,6 @@ import {
|
|
43
43
|
PlayIcon,
|
44
44
|
} from '@finos/legend-art';
|
45
45
|
import {
|
46
|
-
type Binding,
|
47
46
|
type ValueSpecification,
|
48
47
|
PrimitiveInstanceValue,
|
49
48
|
PrimitiveType,
|
@@ -147,8 +146,8 @@ export const ExternalFormatParameterEditorModal = observer(
|
|
147
146
|
isReadOnly: boolean;
|
148
147
|
onClose: () => void;
|
149
148
|
updateParamValue: (val: string) => void;
|
150
|
-
|
151
|
-
|
149
|
+
contentTypeParamPair: {
|
150
|
+
contentType: string;
|
152
151
|
param: string;
|
153
152
|
};
|
154
153
|
}) => {
|
@@ -157,7 +156,7 @@ export const ExternalFormatParameterEditorModal = observer(
|
|
157
156
|
isReadOnly,
|
158
157
|
onClose,
|
159
158
|
updateParamValue,
|
160
|
-
|
159
|
+
contentTypeParamPair,
|
161
160
|
} = props;
|
162
161
|
const paramValue =
|
163
162
|
paramState.varExpression.genericType?.value.rawType === PrimitiveType.BYTE
|
@@ -190,7 +189,7 @@ export const ExternalFormatParameterEditorModal = observer(
|
|
190
189
|
updateInput={updateParamValue}
|
191
190
|
isReadOnly={isReadOnly}
|
192
191
|
language={
|
193
|
-
|
192
|
+
contentTypeParamPair.contentType ===
|
194
193
|
ContentType.APPLICATION_JSON.toString()
|
195
194
|
? CODE_EDITOR_LANGUAGE.JSON
|
196
195
|
: CODE_EDITOR_LANGUAGE.TEXT
|
@@ -215,21 +214,21 @@ const ServiceTestParameterEditor = observer(
|
|
215
214
|
isReadOnly: boolean;
|
216
215
|
paramState: ServiceValueSpecificationTestParameterState;
|
217
216
|
serviceTestState: ServiceTestState;
|
218
|
-
|
217
|
+
contentTypeParamPair:
|
219
218
|
| {
|
220
|
-
|
219
|
+
contentType: string;
|
221
220
|
param: string;
|
222
221
|
}
|
223
222
|
| undefined;
|
224
223
|
}) => {
|
225
|
-
const { serviceTestState, paramState, isReadOnly,
|
224
|
+
const { serviceTestState, paramState, isReadOnly, contentTypeParamPair } =
|
226
225
|
props;
|
227
226
|
const [showPopUp, setShowPopUp] = useState(false);
|
228
227
|
const setupState = serviceTestState.setupState;
|
229
228
|
const paramIsRequired =
|
230
229
|
paramState.varExpression.multiplicity.lowerBound > 0;
|
231
|
-
const type =
|
232
|
-
?
|
230
|
+
const type = contentTypeParamPair
|
231
|
+
? contentTypeParamPair.contentType
|
233
232
|
: paramState.varExpression.genericType?.value.rawType.name ?? 'unknown';
|
234
233
|
const paramValue =
|
235
234
|
paramState.varExpression.genericType?.value.rawType === PrimitiveType.BYTE
|
@@ -273,7 +272,7 @@ const ServiceTestParameterEditor = observer(
|
|
273
272
|
</button>
|
274
273
|
</div>
|
275
274
|
<>
|
276
|
-
{
|
275
|
+
{contentTypeParamPair ? (
|
277
276
|
<div className="service-test-editor__setup__parameter__code-editor">
|
278
277
|
<textarea
|
279
278
|
className="panel__content__form__section__textarea value-spec-editor__input"
|
@@ -295,7 +294,7 @@ const ServiceTestParameterEditor = observer(
|
|
295
294
|
isReadOnly={isReadOnly}
|
296
295
|
onClose={closePopUp}
|
297
296
|
updateParamValue={updateParamValue}
|
298
|
-
|
297
|
+
contentTypeParamPair={contentTypeParamPair}
|
299
298
|
/>
|
300
299
|
)}
|
301
300
|
<div className="service-test-editor__setup__parameter__value__actions">
|
@@ -526,8 +525,8 @@ const ServiceTestSetupEditor = observer(
|
|
526
525
|
isReadOnly={isReadOnly}
|
527
526
|
paramState={paramState}
|
528
527
|
serviceTestState={serviceTestState}
|
529
|
-
|
530
|
-
.
|
528
|
+
contentTypeParamPair={setupState
|
529
|
+
.getContentTypeWithParamFromQuery()
|
531
530
|
.find(
|
532
531
|
(pair) =>
|
533
532
|
pair.param === paramState.parameterValue.name,
|
@@ -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"
|