UNPKG

@finos/legend-application-studio

Version:
155 lines 10.7 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * 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 { Fragment, useEffect } from 'react'; import { observer } from 'mobx-react-lite'; import { getCollapsiblePanelGroupProps, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, useResizeDetector, } from '@finos/legend-art'; import { PanelGroup } from './panel-group/PanelGroup.js'; import { SideBar } from './side-bar/SideBar.js'; import { EditorGroup, EditorGroupSplashScreen, } from './editor-group/EditorGroup.js'; import { GrammarTextEditor } from './editor-group/GrammarTextEditor.js'; import { StatusBar } from './StatusBar.js'; import { ActivityBar } from './ActivityBar.js'; import { ShowcaseSideBar } from './ShowcaseSideBar.js'; import { ProjectSearchCommand } from '../editor/command-center/ProjectSearchCommand.js'; import { guaranteeNonNullable, isNonNullable } from '@finos/legend-shared'; import { flowResult } from 'mobx'; import { useEditorStore, withEditorStore } from './EditorStoreProvider.js'; import { useApplicationStore, useApplicationNavigationContext, ActionAlertType, ActionAlertActionType, useCommands, } from '@finos/legend-application'; import { useParams } from '@finos/legend-application/browser'; import { WorkspaceType } from '@finos/legend-server-sdlc'; import { WorkspaceSyncConflictResolver } from './side-bar/WorkspaceSyncConflictResolver.js'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../__lib__/LegendStudioApplicationNavigationContext.js'; import { EmbeddedQueryBuilder } from './EmbeddedQueryBuilder.js'; import { GRAPH_EDITOR_MODE } from '../../stores/editor/EditorConfig.js'; import { QuickInput } from './QuickInput.js'; import { ShowcaseManager } from '../ShowcaseManager.js'; import { QueryDataCubeViewer } from '@finos/legend-query-builder'; export const Editor = withEditorStore(observer(() => { const params = useParams(); const projectId = guaranteeNonNullable(params.projectId); const patchReleaseVersionId = params.patchReleaseVersionId; const workspaceType = params.groupWorkspaceId ? WorkspaceType.GROUP : WorkspaceType.USER; const workspaceId = guaranteeNonNullable(params.groupWorkspaceId ?? params.workspaceId, `Workspace/group workspace ID is not provided`); const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const editable = editorStore.graphManagerState.graphBuildState.hasCompleted && editorStore.isInitialized; const isResolvingConflicts = editorStore.isInConflictResolutionMode && !editorStore.conflictResolutionState.hasResolvedAllConflicts; // Extensions const extraEditorExtensionComponents = editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getExtraEditorExtensionComponentRendererConfigurations?.() ?? []) .filter(isNonNullable) .map((config) => (_jsx(Fragment, { children: config.renderer(editorStore) }, config.key))); // layout const { ref, width, height } = useResizeDetector(); // These create snapping effect on panel resizing const resizeSideBar = (handleProps) => editorStore.sideBarDisplayState.setSize(handleProps.domElement.getBoundingClientRect() .width); const resizePanel = (handleProps) => editorStore.panelGroupDisplayState.setSize(handleProps.domElement.getBoundingClientRect() .height); const collapsibleSideBarGroupProps = getCollapsiblePanelGroupProps(editorStore.sideBarDisplayState.size === 0, { onStopResize: resizeSideBar, size: editorStore.sideBarDisplayState.size, }); const collapsiblePanelGroupProps = getCollapsiblePanelGroupProps(editorStore.panelGroupDisplayState.size === 0, { onStopResize: resizePanel, size: editorStore.panelGroupDisplayState.size, }); const maximizedCollapsiblePanelGroupProps = getCollapsiblePanelGroupProps(editorStore.panelGroupDisplayState.isMaximized); // handle resizing showcase sidebar const showcaseResizeSideBar = (handleProps) => editorStore.showcasePanelDisplayState.setSize(handleProps.domElement.getBoundingClientRect() .width); const showcaseCollapsibleSideBarGroupProps = getCollapsiblePanelGroupProps(editorStore.showcasePanelDisplayState.size === 0, { onStopResize: showcaseResizeSideBar, size: editorStore.showcasePanelDisplayState.size, }); useEffect(() => { if (ref.current) { editorStore.panelGroupDisplayState.setMaxSize(ref.current.offsetHeight); } }, [editorStore, ref, height, width]); // initialize useEffect(() => { editorStore.internalizeEntityPath(params); }, [editorStore, params]); useEffect(() => { flowResult(editorStore.initialize(projectId, patchReleaseVersionId, workspaceId, workspaceType)).catch(applicationStore.alertUnhandledError); }, [ editorStore, patchReleaseVersionId, applicationStore, projectId, workspaceId, workspaceType, ]); useEffect(() => { applicationStore.navigationService.navigator.blockNavigation([ () => editorStore.isInConflictResolutionMode || editorStore.localChangesState.hasUnpushedChanges, ], (onProceed) => { applicationStore.alertService.setActionAlertInfo({ // TODO?: should we make this message generic like the `BeforeUnloadEvent` message? message: editorStore.isInConflictResolutionMode ? 'You have not accepted the conflict resolution, the current resolution will be discarded. Leave anyway?' : 'You have unpushed changes. Leave anyway?', type: ActionAlertType.CAUTION, actions: [ { label: 'Leave this page', type: ActionAlertActionType.PROCEED_WITH_CAUTION, handler: () => onProceed(), }, { label: 'Stay on this page', type: ActionAlertActionType.PROCEED, default: true, }, ], }); }, () => applicationStore.notificationService.notifyWarning(`Navigation from the editor is blocked`)); return () => { applicationStore.navigationService.navigator.unblockNavigation(); }; }, [editorStore, applicationStore]); useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.EDITOR); useCommands(editorStore); // Cleanup the editor useEffect(() => () => editorStore.cleanUp(), [editorStore]); return (_jsx("div", { className: "app__page", children: _jsxs("div", { className: "editor", children: [_jsxs("div", { className: "editor__body", children: [_jsx(ActivityBar, {}), _jsx("div", { ref: ref, className: "editor__content-container", children: _jsx("div", { className: "editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { ...collapsibleSideBarGroupProps.collapsiblePanel, direction: 1, children: _jsx(SideBar, {}) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { ...(!editorStore.sideBarDisplayState.isOpen && !editorStore.showcasePanelDisplayState.isOpen ? { flex: 1 } : {}), minSize: 300, children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsxs(ResizablePanel, { ...maximizedCollapsiblePanelGroupProps.collapsiblePanel, ...(editorStore.panelGroupDisplayState.size === 0 ? collapsiblePanelGroupProps.remainingPanel : {}), children: [(isResolvingConflicts || editable) && editorStore.graphEditorMode.mode === GRAPH_EDITOR_MODE.FORM && _jsx(EditorGroup, {}), editable && editorStore.graphEditorMode.mode === GRAPH_EDITOR_MODE.GRAMMAR_TEXT && (_jsx(GrammarTextEditor, {})), !editable && _jsx(EditorGroupSplashScreen, {})] }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: editorStore.panelGroupDisplayState.isMaximized ? 'transparent' : 'var(--color-dark-grey-250)' }) }), _jsx(ResizablePanel, { ...collapsiblePanelGroupProps.collapsiblePanel, ...(editorStore.panelGroupDisplayState.isMaximized ? maximizedCollapsiblePanelGroupProps.remainingPanel : {}), direction: -1, children: _jsx(PanelGroup, {}) })] }) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { ...showcaseCollapsibleSideBarGroupProps.collapsiblePanel, direction: -1, children: _jsx("div", { className: "panel__content explorer__content__container", children: _jsx(ShowcaseManager, {}) }) })] }) }) }), _jsx(ShowcaseSideBar, {})] }), _jsx(QuickInput, {}), _jsx(StatusBar, { actionsDisabled: !editable }), editable && _jsx(ProjectSearchCommand, {}), editorStore.localChangesState.workspaceSyncState .workspaceSyncConflictResolutionState.showModal && (_jsx(WorkspaceSyncConflictResolver, {})), _jsx(EmbeddedQueryBuilder, {}), editorStore.embeddedDataCubeViewerState && (_jsx(QueryDataCubeViewer, { state: editorStore.embeddedDataCubeViewerState, close: () => editorStore.setEmbeddedDataCubeViewerState(undefined), options: { fullScreen: true, } })), extraEditorExtensionComponents] }) })); })); //# sourceMappingURL=Editor.js.map