UNPKG

@finos/legend-studio

Version:
217 lines 9.98 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 { observable, action, makeAutoObservable } from 'mobx'; import { LEGEND_STUDIO_APP_EVENT } from '../LegendStudioAppEvent.js'; import { GenerationDirectory, GENERATION_FILE_ROOT_NAME, getGenerationTreeData, openNode, populateDirectoryTreeNodeChildren, buildGenerationDirectory, reprocessOpenNodes, } from '../shared/FileGenerationTreeUtil.js'; import { assertErrorThrown, deepEqual, isEmpty, LogEvent, } from '@finos/legend-shared'; import { ConfigurationProperty, GenerationPropertyItemType, PackageableElement, PackageableElementReference, PackageableElementExplicitReference, ELEMENT_PATH_DELIMITER, getNullableFileGenerationConfig, } from '@finos/legend-graph'; import { configurationProperty_setValue, fileGeneration_addConfigurationProperty, fileGeneration_addScopeElement, fileGeneration_deleteScopeElement, } from '../graphModifier/DSLGeneration_GraphModifierHelper.js'; export class FileGenerationState { editorStore; fileGeneration; isGenerating = false; root; directoryTreeData; selectedNode; filesIndex = new Map(); constructor(editorStore, fileGeneration) { makeAutoObservable(this, { editorStore: false, fileGeneration: false, directoryTreeData: observable.ref, selectedNode: observable.ref, resetFileGeneration: action, setIsGeneration: action, setDirectoryTreeData: action, processGenerationResult: action, reprocessNodeTree: action, setSelectedNode: action, onTreeNodeSelect: action, addScopeElement: action, deleteScopeElement: action, updateFileGenerationParameters: action, }); this.editorStore = editorStore; this.fileGeneration = fileGeneration; this.root = new GenerationDirectory(GENERATION_FILE_ROOT_NAME); } resetFileGeneration() { this.fileGeneration.configurationProperties = []; } setIsGeneration(isGenerating) { this.isGenerating = isGenerating; } setDirectoryTreeData(directoryTreeData) { this.directoryTreeData = directoryTreeData; } getOrCreateDirectory = (directoryName) => GenerationDirectory.getOrCreateDirectory(this.root, directoryName, true); *generate() { this.isGenerating = true; try { // avoid wasting a network call when the scope is empty, we can short-circuit this if (!this.fileGeneration.scopeElements.length) { this.selectedNode = undefined; this.processGenerationResult([]); return; } const mode = this.editorStore.graphState.graphGenerationState.getFileGenerationConfiguration(this.fileGeneration.type).generationMode; const result = (yield this.editorStore.graphManagerState.graphManager.generateFile(this.fileGeneration, mode, this.editorStore.graphManagerState.graph)); this.processGenerationResult(result); } catch (error) { assertErrorThrown(error); this.selectedNode = undefined; this.processGenerationResult([]); this.editorStore.applicationStore.log.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERATION_FAILURE), error); this.editorStore.applicationStore.notifyError(error); } finally { this.isGenerating = false; } } processGenerationResult(output) { this.root = new GenerationDirectory(GENERATION_FILE_ROOT_NAME); this.filesIndex = new Map(); const openedNodeIds = this.directoryTreeData ? Array.from(this.directoryTreeData.nodes.values()) .filter((node) => node.isOpen) .map((node) => node.id) : []; const generationResultIndex = new Map(); const rootFolder = this.fileGeneration.generationOutputPath ?? this.fileGeneration.path.split(ELEMENT_PATH_DELIMITER).join('_'); output.forEach((entry) => { entry.cleanFileName(rootFolder); if (generationResultIndex.has(entry.fileName)) { this.editorStore.applicationStore.log.warn(LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERATION_FAILURE), 'Found 2 generation outputs with same path'); } generationResultIndex.set(entry.fileName, { generationOutput: entry, parentId: this.fileGeneration.path, }); }); // take generation outputs and put them into the root directory buildGenerationDirectory(this.root, generationResultIndex, this.filesIndex); this.directoryTreeData = getGenerationTreeData(this.root); this.reprocessNodeTree(Array.from(generationResultIndex.values()), this.directoryTreeData, openedNodeIds); } reprocessNodeTree(generationResult, treeData, openedNodeIds) { reprocessOpenNodes(treeData, this.filesIndex, this.root, openedNodeIds); // select the current file node if available, else select the first output const selectedFileNodePath = generationResult.length === 1 || (this.selectedNode === undefined && generationResult.length !== 0) ? generationResult[0].generationOutput .fileName : this.selectedNode?.fileNode.path; if (selectedFileNodePath) { const file = this.filesIndex.get(selectedFileNodePath); if (file) { const node = openNode(file, treeData); if (node) { this.onTreeNodeSelect(node, treeData); } } else { this.selectedNode = undefined; } } this.setDirectoryTreeData({ ...treeData }); } setSelectedNode(node) { if (this.selectedNode) { this.selectedNode.isSelected = false; } if (node) { node.isSelected = true; } this.selectedNode = node; } onTreeNodeSelect(node, treeData) { if (node.childrenIds?.length) { node.isOpen = !node.isOpen; if (node.fileNode instanceof GenerationDirectory) { populateDirectoryTreeNodeChildren(node, treeData); } } this.setSelectedNode(node); this.setDirectoryTreeData({ ...treeData }); } getScopeElement(element) { return this.fileGeneration.scopeElements.find((el) => el instanceof PackageableElementReference ? el.value === element : element === el); } addScopeElement(element) { const el = this.getScopeElement(element); if (!el) { fileGeneration_addScopeElement(this.fileGeneration, element instanceof PackageableElement ? PackageableElementExplicitReference.create(element) : element); } } deleteScopeElement(element) { const el = this.getScopeElement(element); if (el) { fileGeneration_deleteScopeElement(this.fileGeneration, el); } } updateFileGenerationParameters(fileGeneration, generationProperty, newValue) { if (generationProperty.type === GenerationPropertyItemType.MAP) { if (!newValue || isEmpty(newValue) || deepEqual(newValue, generationProperty.defaultValue)) { fileGeneration.configurationProperties = fileGeneration.configurationProperties.filter((e) => e.name !== generationProperty.name); } else { const configProperty = getNullableFileGenerationConfig(fileGeneration, generationProperty.name); if (configProperty) { configurationProperty_setValue(configProperty, { ...newValue, }); } else { const newItem = new ConfigurationProperty(generationProperty.name, newValue); fileGeneration_addConfigurationProperty(fileGeneration, newItem); } } } else { const configProperty = getNullableFileGenerationConfig(fileGeneration, generationProperty.name); let useDefaultValue = generationProperty.defaultValue === newValue; if (generationProperty.type === GenerationPropertyItemType.BOOLEAN) { useDefaultValue = (generationProperty.defaultValue === 'true') === newValue; } const newConfigValue = useDefaultValue ? undefined : newValue; if (newConfigValue !== undefined) { if (configProperty) { configurationProperty_setValue(configProperty, newConfigValue); } else { const newItem = new ConfigurationProperty(generationProperty.name, newConfigValue); fileGeneration_addConfigurationProperty(fileGeneration, newItem); } } else { fileGeneration.configurationProperties = fileGeneration.configurationProperties.filter((e) => e.name !== generationProperty.name); } } } } //# sourceMappingURL=FileGenerationState.js.map