UNPKG

@finos/legend-application-pure-ide

Version:
183 lines 8.13 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 {} from '@finos/legend-extension-dsl-diagram/graph'; import { extractElementNameFromPath, } from '@finos/legend-graph'; import { generateEnumerableNameFromToken, guaranteeNonNullable, } from '@finos/legend-shared'; import { action, computed, flow, flowResult, makeObservable, observable, } from 'mobx'; import { deserialize } from 'serializr'; import { DiagramClassInfo, addClassToGraph, buildGraphFromDiagramInfo, } from '../server/models/DiagramInfo.js'; import { FileCoordinate, trimPathLeadingSlash } from '../server/models/File.js'; import { PureIDETabState } from './PureIDETabManagerState.js'; import { LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY } from '../__lib__/LegendPureIDECommand.js'; import { DIAGRAM_INTERACTION_MODE, } from '@finos/legend-extension-dsl-diagram/application'; export class DiagramEditorState extends PureIDETabState { diagramInfo; _renderer; diagram; diagramClasses; graph; diagramPath; filePath; fileLine; fileColumn; constructor(ideStore, diagramInfo, diagramPath, filePath, fileLine, fileColumn) { super(ideStore); makeObservable(this, { _renderer: observable, diagram: observable, diagramInfo: observable, diagramName: computed, diagramCursorClass: computed, addClassView: flow, rebuild: action, setRenderer: action, }); this.diagramPath = diagramPath; this.filePath = filePath; this.fileLine = fileLine; this.fileColumn = fileColumn; this.diagramInfo = diagramInfo; const [diagram, graph, diagramClasses] = buildGraphFromDiagramInfo(diagramInfo); this.diagram = diagram; this.graph = graph; this.diagramClasses = diagramClasses; } get label() { return trimPathLeadingSlash(this.diagramPath); } get description() { return `Diagram: ${trimPathLeadingSlash(this.diagramPath)}`; } get diagramName() { return extractElementNameFromPath(this.diagramPath); } match(tab) { return (tab instanceof DiagramEditorState && this.diagramPath === tab.diagramPath); } get renderer() { return guaranteeNonNullable(this._renderer, `Diagram renderer must be initialized (this is likely caused by calling this method at the wrong place)`); } get isDiagramRendererInitialized() { return Boolean(this._renderer); } // NOTE: we have tried to use React to control the cursor and // could not overcome the jank/lag problem, so we settle with CSS-based approach // See https://css-tricks.com/using-css-cursors/ // See https://developer.mozilla.org/en-US/docs/Web/CSS/cursor get diagramCursorClass() { if (!this.isDiagramRendererInitialized) { return ''; } if (this.renderer.middleClick || this.renderer.rightClick) { return 'diagram-editor__cursor--grabbing'; } switch (this.renderer.interactionMode) { case DIAGRAM_INTERACTION_MODE.PAN: { return this.renderer.leftClick ? 'diagram-editor__cursor--grabbing' : 'diagram-editor__cursor--grab'; } case DIAGRAM_INTERACTION_MODE.ZOOM_IN: { return 'diagram-editor__cursor--zoom-in'; } case DIAGRAM_INTERACTION_MODE.ZOOM_OUT: { return 'diagram-editor__cursor--zoom-out'; } case DIAGRAM_INTERACTION_MODE.LAYOUT: { if (this.renderer.selectionStart) { return 'diagram-editor__cursor--crosshair'; } else if (this.renderer.mouseOverClassCorner || this.renderer.selectedClassCorner) { return 'diagram-editor__cursor--resize'; } else if (this.renderer.mouseOverClassView) { return 'diagram-editor__cursor--pointer'; } return ''; } default: return ''; } } rebuild(value) { this.diagramInfo = value; const [diagram, graph, diagramClasses] = buildGraphFromDiagramInfo(value); this.diagram = diagram; this.graph = graph; this.diagramClasses = diagramClasses; this.fileLine = value.diagram.sourceInformation.line; this.fileColumn = value.diagram.sourceInformation.column; } setupRenderer() { this.renderer.onClassViewDoubleClick = (classView) => { const sourceInformation = this.diagramClasses.get(classView.class.value.path)?.sourceInformation; if (sourceInformation) { const coordinate = new FileCoordinate(sourceInformation.sourceId, sourceInformation.startLine, sourceInformation.startColumn); flowResult(this.ideStore.executeNavigation(coordinate)).catch(this.ideStore.applicationStore.alertUnhandledError); } }; } setRenderer(val) { this._renderer = val; } *addClassView(path, position) { const diagramClassInfo = deserialize(DiagramClassInfo, yield this.ideStore.client.getDiagramClassInfo(path)); const _class = addClassToGraph(diagramClassInfo, this.graph, this.diagramClasses); const classView = this.renderer.addClassView(_class, position); // NOTE: The auto-generated ID by diagram renderer will cause a parser error in Pure // so we need to rewrite it accordingly if (classView) { classView.id = generateEnumerableNameFromToken(this.diagram.classViews.map((cv) => cv.id), 'cview'); } } registerCommands() { const DEFAULT_TRIGGER = () => // make sure the current active editor is this diagram editor this.ideStore.tabManagerState.currentTab === this && // make sure the renderer is initialized this.isDiagramRendererInitialized; this.ideStore.applicationStore.commandService.registerCommand({ key: LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.RECENTER, trigger: DEFAULT_TRIGGER, action: () => this.renderer.recenter(), }); this.ideStore.applicationStore.commandService.registerCommand({ key: LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_ZOOM_TOOL, trigger: DEFAULT_TRIGGER, action: () => this.renderer.switchToZoomMode(), }); this.ideStore.applicationStore.commandService.registerCommand({ key: LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_VIEW_TOOL, trigger: DEFAULT_TRIGGER, action: () => this.renderer.switchToViewMode(), }); this.ideStore.applicationStore.commandService.registerCommand({ key: LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_PAN_TOOL, trigger: DEFAULT_TRIGGER, action: () => this.renderer.switchToPanMode(), }); } deregisterCommands() { [ LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.RECENTER, LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_ZOOM_TOOL, LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_VIEW_TOOL, LEGEND_PURE_IDE_DIAGRAM_EDITOR_COMMAND_KEY.USE_PAN_TOOL, ].forEach((commandKey) => this.ideStore.applicationStore.commandService.deregisterCommand(commandKey)); } } //# sourceMappingURL=DiagramEditorState.js.map