UNPKG

@finos/legend-application-studio

Version:
351 lines 18.2 kB
/** * 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, computed, flow, flowResult, makeObservable, observable, } from 'mobx'; import { assertErrorThrown, LogEvent, NetworkClientError, HttpStatus, guaranteeNonNullable, assertTrue, ActionState, prettyCONSTName, } from '@finos/legend-shared'; import { EDITOR_MODE, ACTIVITY_MODE } from './EditorConfig.js'; import { extractEntityNameFromPath } from '@finos/legend-storage'; import { Workflow, Project, Revision, RevisionAlias, Version, Workspace, WorkspaceAccessType, Patch, AuthorizableProjectAction, isProjectSandbox, } from '@finos/legend-server-sdlc'; import { LEGEND_STUDIO_APP_EVENT } from '../../__lib__/LegendStudioEvent.js'; export const entityDiffSorter = (a, b) => extractEntityNameFromPath(a.newPath ?? a.oldPath ?? '').localeCompare(extractEntityNameFromPath(b.newPath ?? b.oldPath ?? '')); export class EditorSDLCState { editorStore; fetchPublishedProjectVersionsState = ActionState.create(); isWorkspaceOutdated = false; isCheckingIfWorkspaceIsOutdated = false; isFetchingProjectVersions = false; isFetchingProject = false; currentProject; currentPatch; currentWorkspace; remoteWorkspaceRevision; currentRevision; workspaceWorkflows = []; projectVersions = []; projectPublishedVersions = []; authorizedActions; constructor(editorStore) { makeObservable(this, { currentProject: observable, currentPatch: observable, currentWorkspace: observable, remoteWorkspaceRevision: observable, currentRevision: observable, isWorkspaceOutdated: observable, workspaceWorkflows: observable, projectVersions: observable, isCheckingIfWorkspaceIsOutdated: observable, isFetchingProjectVersions: observable, isFetchingProject: observable, projectPublishedVersions: observable, authorizedActions: observable, activeProject: computed, activeWorkspace: computed, activeRevision: computed, activePatch: computed, activeRemoteWorkspaceRevision: computed, canCreateWorkspace: computed, canCreateVersion: computed, isWorkspaceOutOfSync: computed, isActiveProjectSandbox: computed, setCurrentProject: action, setCurrentPatch: action, setCurrentWorkspace: action, setCurrentRevision: action, setWorkspaceLatestRevision: action, fetchCurrentProject: flow, fetchCurrentWorkspace: flow, fetchProjectVersions: flow, checkIfCurrentWorkspaceIsInConflictResolutionMode: flow, fetchRemoteWorkspaceRevision: flow, fetchCurrentRevision: flow, fetchCurrentPatch: flow, checkIfWorkspaceIsOutdated: flow, buildWorkspaceLatestRevisionEntityHashesIndex: flow, buildWorkspaceBaseRevisionEntityHashesIndex: flow, buildProjectLatestRevisionEntityHashesIndex: flow, fetchWorkspaceWorkflows: flow, fetchPublishedProjectVersions: flow, fetchAuthorizedActions: flow, }); this.editorStore = editorStore; } get activeProject() { return guaranteeNonNullable(this.currentProject, `Active project has not been properly set`); } get isActiveProjectSandbox() { return Boolean(this.currentProject && isProjectSandbox(this.currentProject)); } get activeWorkspace() { return guaranteeNonNullable(this.currentWorkspace, `Active workspace has not been properly set`); } get activePatch() { return this.currentPatch; } get activeRevision() { return guaranteeNonNullable(this.currentRevision, `Active revision has not been properly set`); } get activeRemoteWorkspaceRevision() { return guaranteeNonNullable(this.remoteWorkspaceRevision, `Active workspace latest revision has not been properly set`); } get isWorkspaceOutOfSync() { return this.activeRemoteWorkspaceRevision.id !== this.activeRevision.id; } get canCreateWorkspace() { return this.userCanPerformAction(AuthorizableProjectAction.CREATE_WORKSPACE); } get canCreateVersion() { return this.userCanPerformAction(AuthorizableProjectAction.CREATE_VERSION); } unAuthorizedActionMessage(_action) { return `Your are not entitled to perform the action: ${prettyCONSTName(_action)}`; } userCanPerformAction(authorizedAction) { return Boolean(this.authorizedActions === undefined || this.authorizedActions.includes(authorizedAction)); } setCurrentProject(val) { this.currentProject = val; } setCurrentPatch(val) { this.currentPatch = val; } setCurrentWorkspace(val) { this.currentWorkspace = val; } setCurrentRevision(val) { this.currentRevision = val; } setWorkspaceLatestRevision(val) { this.remoteWorkspaceRevision = val; } handleChangeDetectionRefreshIssue(error) { if (!this.currentProject || !this.currentWorkspace || (error instanceof NetworkClientError && error.response.status === HttpStatus.NOT_FOUND)) { this.editorStore.applicationStore.alertService.setBlockingAlert({ message: 'Current project or workspace no longer exists', prompt: 'Please refresh the application', }); } else { this.editorStore.applicationStore.alertService.setBlockingAlert({ message: error.message, }); } } *fetchCurrentProject(projectId, options) { try { this.isFetchingProject = true; this.currentProject = Project.serialization.fromJson((yield this.editorStore.sdlcServerClient.getProject(projectId))); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error); if (!options?.suppressNotification) { this.editorStore.applicationStore.notificationService.notifyError(error); } } finally { this.isFetchingProject = false; } } *fetchCurrentPatch(projectId, patchReleaseVersionId, options) { if (patchReleaseVersionId) { try { this.currentPatch = Patch.serialization.fromJson((yield this.editorStore.sdlcServerClient.getPatch(projectId, patchReleaseVersionId))); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error); if (!options?.suppressNotification) { this.editorStore.applicationStore.notificationService.notifyError(error); } } } } *fetchCurrentWorkspace(projectId, patchReleaseVersionId, workspaceId, workspaceType, options) { try { this.currentWorkspace = Workspace.serialization.fromJson((yield this.editorStore.sdlcServerClient.getWorkspace(projectId, patchReleaseVersionId, workspaceId, workspaceType))); this.currentWorkspace.source = patchReleaseVersionId; const isInConflictResolutionMode = (yield flowResult(this.checkIfCurrentWorkspaceIsInConflictResolutionMode())); if (isInConflictResolutionMode) { this.editorStore.setMode(EDITOR_MODE.CONFLICT_RESOLUTION); this.currentWorkspace.accessType = WorkspaceAccessType.CONFLICT_RESOLUTION; this.editorStore.setActiveActivity(ACTIVITY_MODE.CONFLICT_RESOLUTION); } } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error); if (!options?.suppressNotification) { this.editorStore.applicationStore.notificationService.notifyError(error); } } } *fetchProjectVersions() { try { this.isFetchingProjectVersions = true; this.projectVersions = (yield this.editorStore.sdlcServerClient.getVersions(this.activeProject.projectId)).map((v) => Version.serialization.fromJson(v)); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error); } finally { this.isFetchingProjectVersions = false; } } *checkIfCurrentWorkspaceIsInConflictResolutionMode() { return (yield this.editorStore.sdlcServerClient.checkIfWorkspaceIsInConflictResolutionMode(this.activeProject.projectId, this.activeWorkspace)); } *fetchRemoteWorkspaceRevision(projectId, workspace) { try { this.editorStore.localChangesState.workspaceSyncState.setIncomingRevisions([]); const latestRevision = Revision.serialization.fromJson(this.editorStore.isInConflictResolutionMode ? (yield this.editorStore.sdlcServerClient.getConflictResolutionRevision(projectId, workspace, RevisionAlias.CURRENT)) : (yield this.editorStore.sdlcServerClient.getRevision(projectId, workspace, RevisionAlias.CURRENT))); this.setWorkspaceLatestRevision(latestRevision); } 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); } } *fetchCurrentRevision(projectId, workspace) { try { const currentRevision = Revision.serialization.fromJson(this.editorStore.isInConflictResolutionMode ? (yield this.editorStore.sdlcServerClient.getConflictResolutionRevision(projectId, workspace, RevisionAlias.CURRENT)) : (yield this.editorStore.sdlcServerClient.getRevision(projectId, workspace, RevisionAlias.CURRENT))); this.setCurrentRevision(currentRevision); this.setWorkspaceLatestRevision(currentRevision); } 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); } } *checkIfWorkspaceIsOutdated() { try { this.isCheckingIfWorkspaceIsOutdated = true; this.isWorkspaceOutdated = this.editorStore.isInConflictResolutionMode ? (yield this.editorStore.sdlcServerClient.isConflictResolutionOutdated(this.activeProject.projectId, this.activeWorkspace)) : (yield this.editorStore.sdlcServerClient.isWorkspaceOutdated(this.activeProject.projectId, this.activeWorkspace)); } 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.isCheckingIfWorkspaceIsOutdated = false; } } *buildWorkspaceLatestRevisionEntityHashesIndex() { try { let entities = []; if (!this.editorStore.isInConflictResolutionMode) { // fetch latest revision // NOTE: this check is already covered in conflict resolution mode so we don't need to do it here const latestRevision = Revision.serialization.fromJson((yield this.editorStore.sdlcServerClient.getRevision(this.activeProject.projectId, this.activeWorkspace, RevisionAlias.CURRENT))); // make sure there is no good recovery from this, at this point all users work risk conflict assertTrue(latestRevision.id === this.activeRevision.id, `Can't run local change detection: current workspace revision is not the latest. Please backup your work and refresh the application`); entities = (yield this.editorStore.sdlcServerClient.getEntitiesByRevision(this.activeProject.projectId, this.activeWorkspace, this.activeRevision.id)); } else { entities = (yield this.editorStore.sdlcServerClient.getEntitiesByRevision(this.activeProject.projectId, this.activeWorkspace, RevisionAlias.CURRENT)); } this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.setEntities(entities); yield flowResult(this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.buildEntityHashesIndex(entities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_LOCAL_HASHES_INDEX__SUCCESS))); this.editorStore.tabManagerState.refreshCurrentEntityDiffViewer(); } 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); } } *buildWorkspaceBaseRevisionEntityHashesIndex() { try { const workspaceBaseEntities = (yield this.editorStore.sdlcServerClient.getEntitiesByRevision(this.activeProject.projectId, this.activeWorkspace, RevisionAlias.BASE)); this.editorStore.changeDetectionState.workspaceBaseRevisionState.setEntities(workspaceBaseEntities); yield flowResult(this.editorStore.changeDetectionState.workspaceBaseRevisionState.buildEntityHashesIndex(workspaceBaseEntities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_WORKSPACE_HASHES_INDEX__SUCCESS))); this.editorStore.tabManagerState.refreshCurrentEntityDiffViewer(); } 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); } } *buildProjectLatestRevisionEntityHashesIndex() { try { const projectLatestEntities = (yield this.editorStore.sdlcServerClient.getEntities(this.activeProject.projectId, undefined)); this.editorStore.changeDetectionState.projectLatestRevisionState.setEntities(projectLatestEntities); yield flowResult(this.editorStore.changeDetectionState.projectLatestRevisionState.buildEntityHashesIndex(projectLatestEntities, LogEvent.create(LEGEND_STUDIO_APP_EVENT.CHANGE_DETECTION_BUILD_PROJECT_LATEST_HASHES_INDEX__SUCCESS))); this.editorStore.tabManagerState.refreshCurrentEntityDiffViewer(); } 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); } } *fetchWorkspaceWorkflows() { try { this.workspaceWorkflows = (yield this.editorStore.sdlcServerClient.getWorkflowsByRevision(this.activeProject.projectId, this.activeWorkspace, RevisionAlias.CURRENT)).map((v) => Workflow.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); } } *fetchAuthorizedActions() { try { const authorizedActions = (yield this.editorStore.sdlcServerClient.getAutorizedActions(this.activeProject.projectId)); this.authorizedActions = authorizedActions; } catch (error) { assertErrorThrown(error); // if there is an error fetching authorized actions we should set undefined this.authorizedActions = undefined; this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error); } } *fetchPublishedProjectVersions() { try { this.fetchPublishedProjectVersionsState.inProgress(); this.projectPublishedVersions = (yield this.editorStore.depotServerClient.getVersions(this.editorStore.projectConfigurationEditorState .currentProjectConfiguration.groupId, this.editorStore.projectConfigurationEditorState .currentProjectConfiguration.artifactId, true)); } catch (error) { assertErrorThrown(error); this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.DEPOT_MANAGER_FAILURE), error); } finally { this.fetchPublishedProjectVersionsState.complete(); } } } //# sourceMappingURL=EditorSDLCState.js.map