@finos/legend-application-studio
Version:
Legend Studio application core
254 lines • 13.9 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 { EditorState } from '../EditorState.js';
import { action, computed, flow, observable, makeObservable, flowResult, } from 'mobx';
import { LogEvent, assertErrorThrown, guaranteeNonNullable, hashArray, ActionState, prettyCONSTName, } from '@finos/legend-shared';
import { ProjectStructureVersion, UpdateProjectConfigurationCommand, UpdatePlatformConfigurationsCommand, ProjectType, } from '@finos/legend-server-sdlc';
import { LEGEND_STUDIO_APP_EVENT } from '../../../../__lib__/LegendStudioEvent.js';
import { SNAPSHOT_ALIAS, StoreProjectData } from '@finos/legend-server-depot';
import { ProjectDependencyEditorState } from './ProjectDependencyEditorState.js';
export var CONFIGURATION_EDITOR_TAB;
(function (CONFIGURATION_EDITOR_TAB) {
CONFIGURATION_EDITOR_TAB["PROJECT_STRUCTURE"] = "PROJECT_STRUCTURE";
CONFIGURATION_EDITOR_TAB["PROJECT_DEPENDENCIES"] = "PROJECT_DEPENDENCIES";
CONFIGURATION_EDITOR_TAB["PLATFORM_CONFIGURATIONS"] = "PLATFORM_CONFIGURATIONS";
CONFIGURATION_EDITOR_TAB["ADVANCED"] = "ADVANCED";
})(CONFIGURATION_EDITOR_TAB || (CONFIGURATION_EDITOR_TAB = {}));
export const projectTypeTabFilter = (mode, tab) => {
if (mode === ProjectType.EMBEDDED &&
tab === CONFIGURATION_EDITOR_TAB.PLATFORM_CONFIGURATIONS) {
return false;
}
return true;
};
export class ProjectConfigurationEditorState extends EditorState {
sdlcState;
updatingConfigurationState = ActionState.create();
fetchingProjectVersionsState = ActionState.create();
projectDependencyEditorState;
originalProjectConfiguration; // TODO: we might want to remove this when we do change detection for project configuration
projectConfiguration;
selectedTab;
isReadOnly = false;
projects = new Map();
versions = new Map();
latestProjectStructureVersion;
manualOverwrite = false;
associatedProjectsAndVersionsFetched = false;
constructor(editorStore, sdlcState) {
super(editorStore);
makeObservable(this, {
originalProjectConfiguration: observable,
updatingConfigurationState: observable,
projectConfiguration: observable,
selectedTab: observable,
isReadOnly: observable,
manualOverwrite: observable,
projects: observable,
versions: observable,
associatedProjectsAndVersionsFetched: observable,
fetchingProjectVersionsState: observable,
latestProjectStructureVersion: observable,
projectDependencyEditorState: observable,
originalConfig: computed,
isGroupIdChanged: computed,
isArtifactIdChanged: computed,
setOriginalProjectConfiguration: action,
setProjectConfiguration: action,
setSelectedTab: action,
setManualOverwrite: action,
fectchAssociatedProjectsAndVersions: flow,
updateProjectConfiguration: flow,
updateToLatestStructure: flow,
updateConfigs: flow,
fetchLatestProjectStructureVersion: flow,
changeProjectType: flow,
});
this.projectDependencyEditorState = new ProjectDependencyEditorState(this, this.editorStore);
this.selectedTab = CONFIGURATION_EDITOR_TAB.PROJECT_STRUCTURE;
this.isReadOnly = editorStore.isInViewerMode;
this.sdlcState = sdlcState;
}
setOriginalProjectConfiguration(projectConfiguration) {
this.originalProjectConfiguration = projectConfiguration;
}
setProjectConfiguration(projectConfiguration) {
this.projectConfiguration = projectConfiguration;
}
setSelectedTab(tab) {
this.selectedTab = tab;
}
setManualOverwrite(value) {
this.manualOverwrite = value;
}
get label() {
return 'config';
}
match(tab) {
return tab instanceof ProjectConfigurationEditorState;
}
get currentProjectConfiguration() {
return guaranteeNonNullable(this.projectConfiguration, 'Project configuration must exist');
}
get originalConfig() {
return guaranteeNonNullable(this.originalProjectConfiguration, 'Original project configuration is not set');
}
get isGroupIdChanged() {
return (this.currentProjectConfiguration.groupId !==
this.originalProjectConfiguration?.groupId);
}
get isArtifactIdChanged() {
return (this.currentProjectConfiguration.artifactId !==
this.originalProjectConfiguration?.artifactId);
}
get containsSnapshotDependencies() {
return Boolean(this.originalProjectConfiguration?.projectDependencies.some((dependency) => dependency.versionId.endsWith(SNAPSHOT_ALIAS)));
}
get isInEmbeddedMode() {
return (this.originalProjectConfiguration?.projectType === ProjectType.EMBEDDED);
}
*fectchAssociatedProjectsAndVersions() {
this.fetchingProjectVersionsState.inProgress();
try {
(yield this.editorStore.depotServerClient.getProjects())
.map((v) => StoreProjectData.serialization.fromJson(v))
.forEach((project) => this.projects.set(project.coordinates, project));
// fetch the versions for the dependency projects
for (const dep of this.projectConfiguration?.projectDependencies ?? []) {
const project = this.projects.get(dep.projectId);
if (project) {
const _versions = (yield this.editorStore.depotServerClient.getVersions(guaranteeNonNullable(dep.groupId), guaranteeNonNullable(dep.artifactId), true));
this.versions.set(project.coordinates, _versions);
}
}
this.associatedProjectsAndVersionsFetched = true;
}
catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.editorStore.applicationStore.notificationService.notifyError(`Can't get project dependencies data. Error:\n${error.message}`);
}
finally {
this.fetchingProjectVersionsState.complete();
}
}
*updateProjectConfiguration(updateConfigurationCommand) {
try {
this.updatingConfigurationState.inProgress();
yield this.editorStore.sdlcServerClient.updateConfiguration(this.editorStore.sdlcState.activeProject.projectId, this.editorStore.sdlcState.activeWorkspace, UpdateProjectConfigurationCommand.serialization.toJson(updateConfigurationCommand));
this.editorStore.reset();
// reset editor
yield flowResult(this.editorStore.sdlcState.fetchCurrentWorkspace(this.editorStore.sdlcState.activeProject.projectId, this.editorStore.sdlcState.activePatch?.patchReleaseVersionId.id, this.editorStore.sdlcState.activeWorkspace.workspaceId, this.editorStore.sdlcState.activeWorkspace.workspaceType));
yield flowResult(this.sdlcState.fetchCurrentRevision(this.editorStore.sdlcState.activeProject.projectId, this.editorStore.sdlcState.activeWorkspace));
yield flowResult(this.editorStore.initMode());
this.editorStore.tabManagerState.openTab(this.editorStore.projectConfigurationEditorState);
}
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.updatingConfigurationState.complete();
}
}
*updateToLatestStructure() {
if (this.latestProjectStructureVersion) {
try {
let latestStructure = this.latestProjectStructureVersion;
if (this.isInEmbeddedMode) {
const projectStructureVersion = new ProjectStructureVersion();
projectStructureVersion.version =
this.latestProjectStructureVersion.version;
// extension version does not exists in embedded mode
projectStructureVersion.extensionVersion = undefined;
latestStructure = projectStructureVersion;
}
const updateCommand = new UpdateProjectConfigurationCommand(this.currentProjectConfiguration.groupId, this.currentProjectConfiguration.artifactId, latestStructure, `update project configuration from ${this.editorStore.applicationStore.config.appName}: update to latest project structure`);
yield flowResult(this.updateProjectConfiguration(updateCommand));
}
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);
}
}
}
*changeProjectType() {
try {
const newProjectType = this.isInEmbeddedMode
? ProjectType.MANAGED
: ProjectType.EMBEDDED;
const updateCommand = new UpdateProjectConfigurationCommand(this.currentProjectConfiguration.groupId, this.currentProjectConfiguration.artifactId, undefined, `update project configuration from ${this.editorStore.applicationStore.config.appName}: changed project type to ${prettyCONSTName(newProjectType)}`);
updateCommand.projectType = newProjectType;
yield flowResult(this.updateProjectConfiguration(updateCommand));
}
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);
}
}
// TODO: we will probably need to remove this in the future when we have a better strategy for change detection and persistence of project config
// See https://github.com/finos/legend-studio/issues/952
*updateConfigs() {
this.updatingConfigurationState.inProgress();
this.editorStore.applicationStore.alertService.setBlockingAlert({
message: `Updating project configuration...`,
prompt: `Please do not reload the application`,
showLoading: true,
});
try {
const updateProjectConfigurationCommand = new UpdateProjectConfigurationCommand(this.currentProjectConfiguration.groupId, this.currentProjectConfiguration.artifactId, this.currentProjectConfiguration.projectStructureVersion, `update project configuration from ${this.editorStore.applicationStore.config.appName}`);
if (hashArray(this.originalConfig.platformConfigurations ?? []) !==
hashArray(this.currentProjectConfiguration.platformConfigurations ?? [])) {
updateProjectConfigurationCommand.platformConfigurations =
new UpdatePlatformConfigurationsCommand(this.currentProjectConfiguration.platformConfigurations);
}
if (this.originalConfig.runDependencyTests !==
this.currentProjectConfiguration.runDependencyTests) {
updateProjectConfigurationCommand.runDependencyTests =
this.currentProjectConfiguration.runDependencyTests;
}
updateProjectConfigurationCommand.projectDependenciesToAdd =
this.currentProjectConfiguration.projectDependencies.filter((dep) => !this.originalConfig.projectDependencies.find((originalProjDep) => originalProjDep.hashCode === dep.hashCode));
updateProjectConfigurationCommand.projectDependenciesToRemove =
this.originalConfig.projectDependencies.filter((originalProjDep) => !this.currentProjectConfiguration.projectDependencies.find((dep) => dep.hashCode === originalProjDep.hashCode));
yield flowResult(this.updateProjectConfiguration(updateProjectConfigurationCommand));
}
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.updatingConfigurationState.complete();
this.editorStore.applicationStore.alertService.setBlockingAlert(undefined);
}
}
*fetchLatestProjectStructureVersion() {
try {
this.latestProjectStructureVersion =
ProjectStructureVersion.serialization.fromJson((yield this.editorStore.sdlcServerClient.getLatestProjectStructureVersion()));
}
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);
}
}
}
//# sourceMappingURL=ProjectConfigurationEditorState.js.map