UNPKG

@finos/legend-studio

Version:
212 lines 20.9 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { forwardRef, useEffect, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { clsx, DropdownMenu, ContextMenu, MenuContent, MenuContentItem, TimesIcon, PlusIcon, ArrowsAltHIcon, } from '@finos/legend-art'; import { MappingEditor } from './mapping-editor/MappingEditor.js'; import { UMLEditor } from './uml-editor/UMLEditor.js'; import { MappingEditorState } from '../../../stores/editor-state/element-editor-state/mapping/MappingEditorState.js'; import { UMLEditorState } from '../../../stores/editor-state/element-editor-state/UMLEditorState.js'; import { ElementEditorState } from '../../../stores/editor-state/element-editor-state/ElementEditorState.js'; import { LEGEND_STUDIO_TEST_ID } from '../../LegendStudioTestID.js'; import { ELEMENT_NATIVE_VIEW_MODE } from '../../../stores/EditorConfig.js'; import { useResizeDetector } from 'react-resize-detector'; import { DIFF_VIEW_MODE, EntityDiffViewState, } from '../../../stores/editor-state/entity-diff-editor-state/EntityDiffViewState.js'; import { EntityDiffView } from '../../editor/edit-panel/diff-editor/EntityDiffView.js'; import { ModelLoader } from '../../editor/edit-panel/ModelLoader.js'; import { ModelLoaderState } from '../../../stores/editor-state/ModelLoaderState.js'; import { FunctionEditorState } from '../../../stores/editor-state/element-editor-state/FunctionEditorState.js'; import { ServiceEditorState } from '../../../stores/editor-state/element-editor-state/service/ServiceEditorState.js'; import { ProjectConfigurationEditorState } from '../../../stores/editor-state/ProjectConfigurationEditorState.js'; import { ProjectConfigurationEditor } from '../../editor/edit-panel/project-configuration-editor/ProjectConfigurationEditor.js'; import { ElementGenerationEditor } from './element-generation-editor/ElementGenerationEditor.js'; import { FunctionEditor } from './FunctionEditor.js'; import { ElementNativeView } from './element-generation-editor/ElementNativeView.js'; import { ServiceEditor } from './service-editor/ServiceEditor.js'; import { PackageableRuntimeEditor } from './RuntimeEditor.js'; import { PackageableRuntimeEditorState } from '../../../stores/editor-state/element-editor-state/RuntimeEditorState.js'; import { PackageableConnectionEditorState } from '../../../stores/editor-state/element-editor-state/connection/ConnectionEditorState.js'; import { PackageableConnectionEditor } from './connection-editor/ConnectionEditor.js'; import { FileGenerationEditorState } from '../../../stores/editor-state/element-editor-state/FileGenerationEditorState.js'; import { FileGenerationEditor } from './element-generation-editor/FileGenerationEditor.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { EntityChangeConflictEditorState } from '../../../stores/editor-state/entity-diff-editor-state/EntityChangeConflictEditorState.js'; import { EntityChangeConflictEditor } from './diff-editor/EntityChangeConflictEditor.js'; import { UnsupportedElementEditorState } from '../../../stores/editor-state/UnsupportedElementEditorState.js'; import { UnsupportedElementEditor } from './UnsupportedElementEditor.js'; import { getPrettyLabelForRevision } from '../../../stores/editor-state/entity-diff-editor-state/EntityDiffEditorState.js'; import { GenerationSpecificationEditorState } from '../../../stores/editor-state/GenerationSpecificationEditorState.js'; import { GenerationSpecificationEditor } from './GenerationSpecificationEditor.js'; import { FileGenerationViewerState } from '../../../stores/editor-state/FileGenerationViewerState.js'; import { FileGenerationViewer } from '../../editor/edit-panel/FileGenerationViewer.js'; import { useEditorStore } from '../EditorStoreProvider.js'; import { PackageableDataEditorState } from '../../../stores/editor-state/element-editor-state/data/DataEditorState.js'; import { DataElementEditor } from './data-editor/DataElementEditor.js'; export const ViewerEditPanelSplashScreen = () => { const commandListWidth = 300; const commandListHeight = 50; const [showCommandList, setShowCommandList] = useState(false); const { ref, width, height } = useResizeDetector(); useEffect(() => { setShowCommandList((width ?? 0) > commandListWidth && (height ?? 0) > commandListHeight); }, [width, height]); return (_jsx("div", { ref: ref, className: "edit-panel__splash-screen", children: _jsx("div", { className: clsx('edit-panel__splash-screen__content', { 'edit-panel__splash-screen__content--hidden': !showCommandList, }), children: _jsxs("div", { className: "edit-panel__splash-screen__content__item", children: [_jsx("div", { className: "edit-panel__splash-screen__content__item__label", children: "Open or Search for an Element" }), _jsxs("div", { className: "edit-panel__splash-screen__content__item__hot-keys", children: [_jsx("div", { className: "hotkey__key", children: "Ctrl" }), _jsx("div", { className: "hotkey__plus", children: _jsx(PlusIcon, {}) }), _jsx("div", { className: "hotkey__key", children: "P" })] })] }) }) })); }; export const EditPanelSplashScreen = () => { const commandListWidth = 300; const commandListHeight = 180; const [showCommandList, setShowCommandList] = useState(false); const { ref, width, height } = useResizeDetector(); useEffect(() => { setShowCommandList((width ?? 0) > commandListWidth && (height ?? 0) > commandListHeight); }, [width, height]); return (_jsx("div", { ref: ref, className: "edit-panel__splash-screen", children: _jsxs("div", { className: clsx('edit-panel__splash-screen__content', { 'edit-panel__splash-screen__content--hidden': !showCommandList, }), children: [_jsxs("div", { className: "edit-panel__splash-screen__content__item", children: [_jsx("div", { className: "edit-panel__splash-screen__content__item__label", children: "Open or Search for an Element" }), _jsxs("div", { className: "edit-panel__splash-screen__content__item__hot-keys", children: [_jsx("div", { className: "hotkey__key", children: "Ctrl" }), _jsx("div", { className: "hotkey__plus", children: _jsx(PlusIcon, {}) }), _jsx("div", { className: "hotkey__key", children: "P" })] })] }), _jsxs("div", { className: "edit-panel__splash-screen__content__item", children: [_jsx("div", { className: "edit-panel__splash-screen__content__item__label", children: "Push Local Changes" }), _jsxs("div", { className: "edit-panel__splash-screen__content__item__hot-keys", children: [_jsx("div", { className: "hotkey__key", children: "Ctrl" }), _jsx("div", { className: "hotkey__plus", children: _jsx(PlusIcon, {}) }), _jsx("div", { className: "hotkey__key", children: "S" })] })] }), _jsxs("div", { className: "edit-panel__splash-screen__content__item", children: [_jsx("div", { className: "edit-panel__splash-screen__content__item__label", children: "Toggle Hackermode" }), _jsx("div", { className: "edit-panel__splash-screen__content__item__hot-keys", children: _jsx("div", { className: "hotkey__key", children: "F8" }) })] }), _jsxs("div", { className: "edit-panel__splash-screen__content__item", children: [_jsx("div", { className: "edit-panel__splash-screen__content__item__label", children: "Compile" }), _jsx("div", { className: "edit-panel__splash-screen__content__item__hot-keys", children: _jsx("div", { className: "hotkey__key", children: "F9" }) })] })] }) })); }; const EditPanelHeaderTabContextMenu = observer(forwardRef(function EditPanelHeaderTabContextMenu(props, ref) { const { editorState } = props; const editorStore = useEditorStore(); const close = () => editorStore.closeState(editorState); const closeOthers = () => editorStore.closeAllOtherStates(editorState); const closeAll = () => editorStore.closeAllStates(); return (_jsxs("div", { ref: ref, className: "edit-panel__header__tab__context-menu", children: [_jsx("button", { className: "edit-panel__header__tab__context-menu__item", onClick: close, children: "Close" }), _jsx("button", { className: "edit-panel__header__tab__context-menu__item", disabled: editorStore.openedEditorStates.length < 2, onClick: closeOthers, children: "Close Others" }), _jsx("button", { className: "edit-panel__header__tab__context-menu__item", onClick: closeAll, children: "Close All" })] })); })); export const EditPanel = observer(() => { const editorStore = useEditorStore(); const currentEditorState = editorStore.currentEditorState; const openedEditorStates = editorStore.openedEditorStates; const nativeViewModes = currentEditorState instanceof ElementEditorState ? Object.values(ELEMENT_NATIVE_VIEW_MODE) : []; const generationViewModes = currentEditorState instanceof ElementEditorState ? editorStore.graphState.graphGenerationState.fileGenerationConfigurations .slice() .sort((a, b) => a.label.localeCompare(b.label)) : []; const renderActiveElementTab = () => { if (currentEditorState instanceof ElementEditorState) { if (currentEditorState.generationViewMode) { const elementGenerationState = editorStore.elementGenerationStates.find((state) => state.fileGenerationType === currentEditorState.generationViewMode); return (_jsx(ElementGenerationEditor, { elementGenerationState: guaranteeNonNullable(elementGenerationState), currentElementState: currentEditorState }, elementGenerationState?.uuid)); } switch (currentEditorState.editMode) { case ELEMENT_NATIVE_VIEW_MODE.FORM: { if (currentEditorState instanceof UMLEditorState) { return _jsx(UMLEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof FunctionEditorState) { return _jsx(FunctionEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof MappingEditorState) { return _jsx(MappingEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof ServiceEditorState) { return _jsx(ServiceEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof PackageableRuntimeEditorState) { return _jsx(PackageableRuntimeEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof PackageableConnectionEditorState) { return (_jsx(PackageableConnectionEditor, {}, currentEditorState.uuid)); } else if (currentEditorState instanceof FileGenerationEditorState) { return _jsx(FileGenerationEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof PackageableDataEditorState) { return _jsx(DataElementEditor, {}, currentEditorState.uuid); } else if (currentEditorState instanceof GenerationSpecificationEditorState) { return (_jsx(GenerationSpecificationEditor, {}, currentEditorState.uuid)); } else if (currentEditorState instanceof UnsupportedElementEditorState) { return _jsx(UnsupportedElementEditor, {}, currentEditorState.uuid); } const extraElementEditorCreators = editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getExtraElementEditorRenderers?.() ?? []); for (const elementEditorCreators of extraElementEditorCreators) { const elementEditor = elementEditorCreators(currentEditorState); if (elementEditor) { return elementEditor; } } break; } case ELEMENT_NATIVE_VIEW_MODE.JSON: case ELEMENT_NATIVE_VIEW_MODE.GRAMMAR: return (_jsx(ElementNativeView, { currentElementState: currentEditorState }, currentEditorState.uuid)); default: return null; } } else if (currentEditorState instanceof EntityDiffViewState) { return (_jsx(EntityDiffView, { entityDiffViewState: currentEditorState }, currentEditorState.uuid)); } else if (currentEditorState instanceof EntityChangeConflictEditorState) { return (_jsx(EntityChangeConflictEditor, { conflictEditorState: currentEditorState }, currentEditorState.uuid)); } else if (currentEditorState instanceof FileGenerationViewerState) { return _jsx(FileGenerationViewer, {}, currentEditorState.uuid); } else if (currentEditorState instanceof ModelLoaderState) { return _jsx(ModelLoader, {}); } else if (currentEditorState instanceof ProjectConfigurationEditorState) { return _jsx(ProjectConfigurationEditor, {}); } return null; }; const renderHeaderLabel = (editorState) => { if (editorState instanceof EntityDiffViewState) { return (_jsxs("div", { className: "edit-panel__header__tab__label__diff", children: [_jsx("div", { className: "edit-panel__header__tab__label__diff__element-name", children: editorState.headerName }), _jsxs("div", { className: "edit-panel__header__tab__label__diff__text", children: ["(", getPrettyLabelForRevision(editorState.fromRevision)] }), _jsx("div", { className: "edit-panel__header__tab__label__diff__icon", children: _jsx(ArrowsAltHIcon, {}) }), _jsxs("div", { className: "edit-panel__header__tab__label__diff__text", children: [getPrettyLabelForRevision(editorState.toRevision), ")"] })] })); } else if (editorState instanceof EntityChangeConflictEditorState) { return (_jsxs("div", { className: "edit-panel__header__tab__label__diff", children: [_jsx("div", { className: "edit-panel__header__tab__label__diff__element-name", children: editorState.headerName }), _jsx("div", { className: "edit-panel__header__tab__label__diff__text", children: editorState.isReadOnly ? '(Merge Preview)' : '(Merged)' })] })); } return editorState.headerName; }; // actions const closeTab = (editorState) => (event) => editorStore.closeState(editorState); const closeTabOnMiddleClick = (editorState) => (event) => { if (event.nativeEvent.button === 1) { editorStore.closeState(editorState); } }; const openTab = (editorState) => () => editorStore.openState(editorState); if (!currentEditorState) { return editorStore.isInViewerMode ? (_jsx(ViewerEditPanelSplashScreen, {})) : (_jsx(EditPanelSplashScreen, {})); } return (_jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.EDIT_PANEL, className: "panel edit-panel", children: [_jsxs(ContextMenu, { disabled: true, className: "panel__header edit-panel__header", children: [_jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS, className: "edit-panel__header__tabs", children: openedEditorStates.map((editorState) => (_jsx("div", { className: clsx('edit-panel__header__tab', { 'edit-panel__header__tab--active': editorState === currentEditorState, }), onMouseUp: closeTabOnMiddleClick(editorState), children: _jsxs(ContextMenu, { content: _jsx(EditPanelHeaderTabContextMenu, { editorState: editorState }), className: "edit-panel__header__tab__content", children: [_jsx("button", { className: "edit-panel__header__tab__label", tabIndex: -1, onClick: openTab(editorState), title: editorState instanceof ElementEditorState ? editorState.element.path : editorState instanceof EntityDiffViewState ? editorState.headerTooltip : editorState.headerName, children: renderHeaderLabel(editorState) }), _jsx("button", { className: "edit-panel__header__tab__close-btn", onClick: closeTab(editorState), tabIndex: -1, title: 'Close', children: _jsx(TimesIcon, {}) })] }) }, editorState.uuid))) }), _jsxs("div", { className: "edit-panel__header__actions", children: [currentEditorState instanceof ElementEditorState && (_jsx(DropdownMenu, { className: "edit-panel__view-mode", content: _jsxs(MenuContent, { "data-testid": LEGEND_STUDIO_TEST_ID.EDIT_PANEL__ELEMENT_VIEW__OPTIONS, className: "edit-panel__view-mode__options edit-panel__view-mode__options--with-group", children: [_jsxs("div", { className: "edit-panel__view-mode__option__group edit-panel__view-mode__option__group--native", children: [_jsx("div", { className: "edit-panel__view-mode__option__group__name", children: "native" }), _jsx("div", { className: "edit-panel__view-mode__option__group__options", children: nativeViewModes.map((mode) => (_jsx(MenuContentItem, { className: "edit-panel__view-mode__option", onClick: () => currentEditorState.setEditMode(mode), children: mode }, mode))) })] }), Boolean(generationViewModes.length) && (_jsxs(_Fragment, { children: [_jsx("div", { className: "edit-panel__view-mode__option__group__separator" }), _jsxs("div", { className: "edit-panel__view-mode__option__group edit-panel__view-mode__option__group--generation", children: [_jsx("div", { className: "edit-panel__view-mode__option__group__name", children: "generation" }), _jsx("div", { className: "edit-panel__view-mode__option__group__options", children: generationViewModes.map((mode) => (_jsx(MenuContentItem, { className: "edit-panel__view-mode__option", disabled: !editorStore.graphState.graphGenerationState.supportedFileGenerationConfigurationsForCurrentElement.includes(mode), onClick: () => currentEditorState.setGenerationViewMode(mode.key), children: mode.label }, mode.key))) })] })] }))] }), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'right' }, }, children: _jsx("button", { className: "edit-panel__view-mode__type", title: "View as...", children: _jsx("div", { className: "edit-panel__view-mode__type__label", children: currentEditorState.generationViewMode ? editorStore.graphState.graphGenerationState.getFileGenerationConfiguration(currentEditorState.generationViewMode).label : currentEditorState.editMode }) }) })), currentEditorState instanceof EntityDiffViewState && (_jsx(DropdownMenu, { className: "edit-panel__view-mode", content: _jsxs(MenuContent, { "data-testid": LEGEND_STUDIO_TEST_ID.EDIT_PANEL__ELEMENT_VIEW__OPTIONS, className: "edit-panel__view-mode__options", children: [_jsx(MenuContentItem, { className: "edit-panel__view-mode__option", onClick: () => currentEditorState.setDiffMode(DIFF_VIEW_MODE.GRAMMAR), children: DIFF_VIEW_MODE.GRAMMAR }), _jsx(MenuContentItem, { className: "edit-panel__view-mode__option", onClick: () => currentEditorState.setDiffMode(DIFF_VIEW_MODE.JSON), children: DIFF_VIEW_MODE.JSON })] }), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, transformOrigin: { vertical: 'top', horizontal: 'right' }, }, children: _jsx("button", { className: "edit-panel__view-mode__type", title: "View as...", children: _jsx("div", { className: "edit-panel__view-mode__type__label", children: currentEditorState.diffMode }) }) }))] })] }), _jsx("div", { className: "panel__content edit-panel__content", "data-testid": LEGEND_STUDIO_TEST_ID.EDIT_PANEL_CONTENT, children: renderActiveElementTab() }, currentEditorState.uuid)] })); }); //# sourceMappingURL=EditPanel.js.map