@finos/legend-application-studio
Version:
Legend Studio application core
259 lines • 14.4 kB
JavaScript
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { action, flow, flowResult, makeObservable, observable } from 'mobx';
import { assertErrorThrown, LogEvent, ActionState, } from '@finos/legend-shared';
import { generateEditorRoute, generateSetupRoute, } from '../../../__lib__/LegendStudioNavigation.js';
import { CreateVersionCommand, ReviewState, Revision, RevisionAlias, Version, Workspace, Review, areWorkspacesEquivalent, Patch, } from '@finos/legend-server-sdlc';
import { LEGEND_STUDIO_APP_EVENT } from '../../../__lib__/LegendStudioEvent.js';
export var PROJECT_OVERVIEW_ACTIVITY_MODE;
(function (PROJECT_OVERVIEW_ACTIVITY_MODE) {
PROJECT_OVERVIEW_ACTIVITY_MODE["RELEASE"] = "RELEASE";
PROJECT_OVERVIEW_ACTIVITY_MODE["OVERVIEW"] = "OVERVIEW";
PROJECT_OVERVIEW_ACTIVITY_MODE["VERSIONS"] = "VERSIONS";
PROJECT_OVERVIEW_ACTIVITY_MODE["WORKSPACES"] = "WORKSPACES";
PROJECT_OVERVIEW_ACTIVITY_MODE["PATCH"] = "PATCH";
})(PROJECT_OVERVIEW_ACTIVITY_MODE || (PROJECT_OVERVIEW_ACTIVITY_MODE = {}));
export class ProjectOverviewState {
editorStore;
sdlcState;
activityMode = PROJECT_OVERVIEW_ACTIVITY_MODE.OVERVIEW;
releaseVersion;
committedReviewsBetweenMostRecentVersionAndProjectLatest = [];
latestProjectVersion; // `undefined` if API is not yet called, `null` if fetched but no version exists
currentProjectRevision;
projectWorkspaces = [];
patches = [];
isCreatingVersion = false;
isFetchingProjectWorkspaces = false;
isDeletingWorkspace = false;
updatingProjectState = ActionState.create();
isFetchingLatestVersion = false;
isFetchingCurrentProjectRevision = false;
createPatchState = ActionState.create();
constructor(editorStore, sdlcState) {
makeObservable(this, {
patches: observable,
activityMode: observable,
releaseVersion: observable,
committedReviewsBetweenMostRecentVersionAndProjectLatest: observable,
latestProjectVersion: observable,
currentProjectRevision: observable,
projectWorkspaces: observable,
isCreatingVersion: observable,
isFetchingProjectWorkspaces: observable,
isDeletingWorkspace: observable,
updatingProjectState: observable,
isFetchingLatestVersion: observable,
isFetchingCurrentProjectRevision: observable,
setActivityMode: action,
fetchProjectWorkspaces: flow,
deleteWorkspace: flow,
updateProject: flow,
fetchLatestProjectVersion: flow,
createVersion: flow,
createPatchVersion: flow,
createPatch: flow,
fetchPatches: flow,
});
this.editorStore = editorStore;
this.sdlcState = sdlcState;
this.releaseVersion = new CreateVersionCommand();
}
setActivityMode(activityMode) {
this.activityMode = activityMode;
}
*fetchProjectWorkspaces() {
try {
this.isFetchingProjectWorkspaces = true;
this.patches = (yield this.editorStore.sdlcServerClient.getPatches(this.sdlcState.activeProject.projectId)).map((v) => Patch.serialization.fromJson(v));
this.projectWorkspaces = (yield this.editorStore.sdlcServerClient.getWorkspaces(this.sdlcState.activeProject.projectId)).map((v) => Workspace.serialization.fromJson(v));
for (const patch of this.patches) {
this.projectWorkspaces = this.projectWorkspaces.concat((yield this.editorStore.sdlcServerClient.getWorkspaces(this.sdlcState.activeProject.projectId, patch.patchReleaseVersionId.id)).map((v) => {
const w = Workspace.serialization.fromJson(v);
w.source = patch.patchReleaseVersionId.id;
return w;
}));
}
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
}
finally {
this.isFetchingProjectWorkspaces = false;
}
}
*deleteWorkspace(workspace) {
try {
this.isDeletingWorkspace = true;
yield this.editorStore.sdlcServerClient.deleteWorkspace(this.sdlcState.activeProject.projectId, workspace);
this.projectWorkspaces = this.projectWorkspaces.filter((w) => !areWorkspacesEquivalent(workspace, w));
// redirect to home page if current workspace is deleted
if (areWorkspacesEquivalent(this.editorStore.sdlcState.activeWorkspace, workspace)) {
this.editorStore.applicationStore.notificationService.notifyWarning('Current workspace is deleted. Redirecting to workspace setup');
this.editorStore.applicationStore.navigationService.navigator.goToLocation(generateSetupRoute(this.editorStore.sdlcState.activeProject.projectId, undefined), {
ignoreBlocking: true,
});
}
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
}
finally {
this.isDeletingWorkspace = false;
}
}
*updateProject(name, description, tags) {
try {
this.updatingProjectState.inProgress();
yield this.editorStore.sdlcServerClient.updateProject(this.sdlcState.activeProject.projectId, {
name,
description,
tags,
});
this.editorStore.applicationStore.notificationService.notifySuccess(`Project '${name}' is succesfully updated`);
yield flowResult(this.sdlcState.fetchCurrentProject(this.sdlcState.activeProject.projectId));
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
finally {
this.updatingProjectState.complete();
}
}
*fetchPatches() {
try {
this.patches = (yield this.editorStore.sdlcServerClient.getPatches(this.sdlcState.activeProject.projectId)).map((v) => Patch.serialization.fromJson(v));
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
}
*fetchLatestProjectVersion() {
try {
this.isFetchingLatestVersion = true;
// fetch latest version
const version = (yield this.editorStore.sdlcServerClient.getLatestVersion(this.sdlcState.activeProject.projectId));
this.latestProjectVersion = version
? Version.serialization.fromJson(version)
: null;
// fetch current project revision and set release revision ID
this.currentProjectRevision = Revision.serialization.fromJson((yield this.editorStore.sdlcServerClient.getRevision(this.sdlcState.activeProject.projectId, undefined, RevisionAlias.CURRENT)));
this.releaseVersion.setRevisionId(this.currentProjectRevision.id);
// fetch committed reviews between most recent version and project latest
if (this.latestProjectVersion) {
const latestProjectVersionRevision = Revision.serialization.fromJson((yield this.editorStore.sdlcServerClient.getRevision(this.sdlcState.activeProject.projectId, undefined, this.latestProjectVersion.revisionId)));
// we find the review associated with the latest version revision, this usually exist, except in 2 cases:
// 1. the revision is somehow directly added to the branch by the user (in the case of `git`, user directly pushed to unprotected default branch)
// 2. the revision is the merged/comitted review revision (this usually happens for projects where fast forwarding merging is not default)
// in those case, we will get the time from the revision
const latestProjectVersionRevisionReviewObj = (yield this.editorStore.sdlcServerClient.getReviews(this.sdlcState.activeProject.projectId, undefined, {
state: ReviewState.COMMITTED,
revisionIds: [latestProjectVersionRevision.id],
limit: 1,
}))[0];
const latestProjectVersionRevisionReview = latestProjectVersionRevisionReviewObj
? Review.serialization.fromJson(latestProjectVersionRevisionReviewObj)
: undefined;
this.committedReviewsBetweenMostRecentVersionAndProjectLatest = (yield this.editorStore.sdlcServerClient.getReviews(this.sdlcState.activeProject.projectId, undefined, {
state: ReviewState.COMMITTED,
since: latestProjectVersionRevisionReview?.committedAt ??
latestProjectVersionRevision.committedAt,
}))
.map((v) => Review.serialization.fromJson(v))
.filter((review) => !latestProjectVersionRevisionReview ||
review.id !== latestProjectVersionRevisionReview.id); // make sure to exclude the base review
}
else {
this.committedReviewsBetweenMostRecentVersionAndProjectLatest = (yield this.editorStore.sdlcServerClient.getReviews(this.sdlcState.activeProject.projectId, undefined, {
state: ReviewState.COMMITTED,
})).map((v) => Review.serialization.fromJson(v));
}
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
}
finally {
this.isFetchingLatestVersion = false;
}
}
*createVersion(versionType) {
if (!this.editorStore.sdlcServerClient.features.canCreateVersion) {
this.editorStore.applicationStore.notificationService.notifyError(`Can't create version: not supported by SDLC server`);
return;
}
this.isCreatingVersion = true;
try {
this.releaseVersion.versionType = versionType;
this.releaseVersion.validate();
this.latestProjectVersion = Version.serialization.fromJson((yield this.editorStore.sdlcServerClient.createVersion(this.sdlcState.activeProject.projectId, CreateVersionCommand.serialization.toJson(this.releaseVersion))));
yield flowResult(this.fetchLatestProjectVersion());
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
finally {
this.isCreatingVersion = false;
}
}
*createPatchVersion(id) {
this.isCreatingVersion = true;
try {
const version = Version.serialization.fromJson((yield this.editorStore.sdlcServerClient.releasePatch(this.sdlcState.activeProject.projectId, id)));
this.editorStore.applicationStore.notificationService.notifySuccess(`${version.id.id} is released successfully`);
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
finally {
this.isCreatingVersion = false;
}
}
*createPatch(sourceVersion, workspaceName, workspaceType) {
if (!workspaceName) {
this.editorStore.applicationStore.notificationService.notify(`Please provide workspace name`);
}
this.createPatchState.inProgress();
this.createPatchState.setMessage(`Creating patch...`);
try {
const newPatch = Patch.serialization.fromJson((yield this.editorStore.sdlcServerClient.createPatch(this.sdlcState.activeProject.projectId, sourceVersion)));
this.editorStore.applicationStore.notificationService.notifySuccess(`Patch '${newPatch.patchReleaseVersionId.id}' is succesfully created`);
this.createPatchState.setMessage(`Creating workspace...`);
const newWorkspace = Workspace.serialization.fromJson((yield this.editorStore.sdlcServerClient.createWorkspace(this.sdlcState.activeProject.projectId, newPatch.patchReleaseVersionId.id, workspaceName, workspaceType)));
newWorkspace.source = newPatch.patchReleaseVersionId.id;
this.editorStore.applicationStore.notificationService.notifySuccess(`Workspace '${newWorkspace.workspaceId}' is succesfully created`);
this.editorStore.applicationStore.navigationService.navigator.goToLocation(generateEditorRoute(this.sdlcState.activeProject.projectId, newPatch.patchReleaseVersionId.id, workspaceName, workspaceType));
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(error);
}
finally {
this.createPatchState.reset();
}
}
}
//# sourceMappingURL=ProjectOverviewState.js.map