UNPKG

@finos/legend-application-studio

Version:
129 lines 12.8 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 { prettyCONSTName, toSentenceCase } from '@finos/legend-shared'; import { clsx, ContextMenu, FlaskIcon, MapIcon, PlayIcon, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, TimesIcon, PURE_UnknownElementTypeIcon, PURE_ClassIcon, PURE_EnumerationIcon, PURE_AssociationIcon, Panel, useResizeDetector, MenuContentItem, MenuContent, LockIcon, } from '@finos/legend-art'; import { ClassMappingEditor } from './ClassMappingEditor.js'; import { EnumerationMappingEditor } from './EnumerationMappingEditor.js'; import { MappingEditorState, getMappingElementTarget, getMappingElementType, MAPPING_ELEMENT_TYPE, getMappingElementLabel, MAPPING_EDITOR_TAB, } from '../../../../stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js'; import { MappingElementState } from '../../../../stores/editor/editor-state/element-editor-state/mapping/MappingElementState.js'; import { MappingExplorer } from './MappingExplorer.js'; import { DEPRECATED__MappingTestEditor } from './legacy/DEPRECATED__MappingTestEditor.js'; import { DEPRECATED__MappingTestState } from '../../../../stores/editor/editor-state/element-editor-state/mapping/legacy/DEPRECATED__MappingTestState.js'; import { MappingTestsExplorer } from './MappingTestsExplorer.js'; import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js'; import { MappingExecutionState } from '../../../../stores/editor/editor-state/element-editor-state/mapping/MappingExecutionState.js'; import { MappingExecutionBuilder } from './MappingExecutionBuilder.js'; import { flowResult } from 'mobx'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { Class, Enumeration, Association, } from '@finos/legend-graph'; import { useApplicationNavigationContext, useApplicationStore, } from '@finos/legend-application'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js'; import { MappingTestableEditor } from './MappingTestableEditor.js'; import { DocumentationLink } from '@finos/legend-lego/application'; import { LEGEND_STUDIO_DOCUMENTATION_KEY } from '../../../../__lib__/LegendStudioDocumentation.js'; import { MappingTestMigrationTool } from './legacy/MappingTestMigrationTool.js'; export const MappingEditorSplashScreen = () => { const logoWidth = 280; const logoHeight = 270; const [showLogo, setShowLogo] = useState(false); const { ref, height, width } = useResizeDetector(); useEffect(() => { setShowLogo((width ?? 0) > logoWidth && (height ?? 0) > logoHeight); }, [height, width]); return (_jsx("div", { ref: ref, className: "mapping-editor__splash-screen", children: _jsx("div", { className: clsx('mapping-editor__splash-screen__logo', { 'mapping-editor__splash-screen__logo--hidden': !showLogo, }), children: _jsx(MapIcon, {}) }) })); }; const MappingEditorHeaderTabContextMenu = observer(forwardRef(function MappingEditorHeaderTabContextMenu(props, ref) { const { tabState } = props; const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState); const close = applicationStore.guardUnhandledError(() => flowResult(mappingEditorState.closeTab(tabState))); const closeOthers = applicationStore.guardUnhandledError(() => flowResult(mappingEditorState.closeAllOtherTabs(tabState))); const closeAll = () => mappingEditorState.closeAllTabs(); return (_jsxs(MenuContent, { ref: ref, children: [_jsx(MenuContentItem, { onClick: close, children: "Close" }), _jsx(MenuContentItem, { disabled: mappingEditorState.openedTabStates.length < 2, onClick: closeOthers, children: "Close Others" }), _jsx(MenuContentItem, { onClick: closeAll, children: "Close All" })] })); })); const getMappingElementTargetIcon = (mappingElement) => { const target = getMappingElementTarget(mappingElement); if (target instanceof Class) { return _jsx(PURE_ClassIcon, {}); } else if (target instanceof Enumeration) { return _jsx(PURE_EnumerationIcon, {}); } else if (target instanceof Association) { return _jsx(PURE_AssociationIcon, {}); } return _jsx(PURE_UnknownElementTypeIcon, {}); }; const MappingClassMappingEditor = observer(() => { const editorStore = useEditorStore(); const applicationStore = useApplicationStore(); const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState); const isReadOnly = mappingEditorState.isReadOnly; const currentTabState = mappingEditorState.currentTabState; const renderActiveMappingElementTab = () => { if (currentTabState instanceof DEPRECATED__MappingTestState) { return (_jsx(DEPRECATED__MappingTestEditor, { testState: currentTabState, isReadOnly: isReadOnly }, currentTabState.uuid)); } else if (currentTabState instanceof MappingElementState) { const currentMappingElement = currentTabState.mappingElement; switch (getMappingElementType(currentMappingElement)) { case MAPPING_ELEMENT_TYPE.CLASS: return (_jsx(ClassMappingEditor, { setImplementation: currentMappingElement, isReadOnly: isReadOnly })); case MAPPING_ELEMENT_TYPE.ENUMERATION: return (_jsx(EnumerationMappingEditor, { enumerationMapping: currentMappingElement, isReadOnly: isReadOnly })); case MAPPING_ELEMENT_TYPE.ASSOCIATION: // we will not support association mapping default: return _jsx("div", { children: "Unsupported mapping type" }); } } else if (currentTabState instanceof MappingExecutionState) { return (_jsx(MappingExecutionBuilder, { executionState: currentTabState }, currentTabState.uuid)); } return _jsx(MappingEditorSplashScreen, {}); }; const closeTab = (tabState) => () => { flowResult(mappingEditorState.closeTab(tabState)).catch(applicationStore.alertUnhandledError); }; const closeTabOnMiddleClick = (tabState) => (event) => { if (event.nativeEvent.button === 1) { flowResult(mappingEditorState.closeTab(tabState)).catch(applicationStore.alertUnhandledError); } }; const openTab = (tabState) => applicationStore.guardUnhandledError(() => flowResult(mappingEditorState.openTab(tabState))); useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MAPPING_EDITOR); return (_jsx("div", { className: clsx('mapping-editor', 'mapping__theme__dark'), children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 300, minSize: 300, children: _jsx("div", { className: "mapping-editor__side-bar", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { size: 400, minSize: 28, children: _jsx(MappingExplorer, { isReadOnly: isReadOnly }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-light-grey-400)" }) }), _jsx(ResizablePanel, { minSize: 36, children: _jsx(MappingTestsExplorer, { isReadOnly: isReadOnly }) })] }) }) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { children: _jsxs(Panel, { children: [_jsx("div", { className: "panel__header mapping-editor__header", children: _jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.EDITOR__TABS__HEADER, className: "mapping-editor__header__tabs", children: mappingEditorState.openedTabStates.map((tabState) => (_jsx("div", { onMouseUp: closeTabOnMiddleClick(tabState), className: clsx('mapping-editor__header__tab', { 'mapping-editor__header__tab--active': tabState === mappingEditorState.currentTabState, }), children: _jsxs(ContextMenu, { className: "mapping-editor__header__tab__content", content: _jsx(MappingEditorHeaderTabContextMenu, { tabState: tabState }), children: [tabState instanceof DEPRECATED__MappingTestState && (_jsxs(_Fragment, { children: [_jsx(FlaskIcon, { className: "mapping-editor__header__tab__icon--test" }), _jsx("button", { className: "mapping-editor__header__tab__element__name", tabIndex: -1, onClick: openTab(tabState), children: tabState.test.name })] })), tabState instanceof MappingElementState && (_jsxs(_Fragment, { children: [_jsx("div", { className: `mapping-editor__header__tab__element__type icon color--${getMappingElementType(tabState.mappingElement).toLowerCase()}`, children: getMappingElementTargetIcon(tabState.mappingElement) }), _jsx("button", { className: "mapping-editor__header__tab__element__name", tabIndex: -1, onClick: openTab(tabState), title: `${toSentenceCase(getMappingElementType(tabState.mappingElement)).toLowerCase()} mapping '${tabState.mappingElement.id.value}' for '${getMappingElementTarget(tabState.mappingElement) .name}'`, children: getMappingElementLabel(tabState.mappingElement, editorStore).value })] })), tabState instanceof MappingExecutionState && (_jsxs(_Fragment, { children: [_jsx(PlayIcon, { className: "mapping-editor__header__tab__icon--execution" }), _jsx("button", { className: "mapping-editor__header__tab__element__name", tabIndex: -1, onClick: openTab(tabState), children: tabState.name })] })), _jsx("button", { className: "mapping-editor__header__tab__close-btn", onClick: closeTab(tabState), tabIndex: -1, title: "Close", children: _jsx(TimesIcon, {}) })] }) }, tabState.uuid))) }) }), _jsx("div", { className: "panel__content mapping-editor__content", children: renderActiveMappingElementTab() })] }) })] }) })); }); export const MappingEditor = observer(() => { const editorStore = useEditorStore(); const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState); const isReadOnly = mappingEditorState.isReadOnly; const mapping = mappingEditorState.mapping; const selectedTab = mappingEditorState.selectedTab; const changeTab = (tab) => () => mappingEditorState.setSelectedTab(tab); return (_jsx("div", { "data-testid": LEGEND_STUDIO_TEST_ID.MAPPING_EDITOR, className: "service-editor", children: _jsxs("div", { className: "panel", children: [_jsx("div", { className: "panel__header", children: _jsxs("div", { className: "panel__header__title", children: [isReadOnly && (_jsx("div", { className: "uml-element-editor__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "panel__header__title__label", children: "mapping" }), _jsx("div", { className: "panel__header__title__content", children: mapping.name })] }) }), _jsx("div", { className: "panel__header service-editor__header--with-tabs", children: _jsx("div", { className: "uml-element-editor__tabs", children: Object.values(MAPPING_EDITOR_TAB).map((tab) => (_jsxs("div", { onClick: changeTab(tab), className: clsx('service-editor__tab', { 'service-editor__tab--active': tab === selectedTab, }), children: [prettyCONSTName(tab), tab === MAPPING_EDITOR_TAB.TEST_SUITES && (_jsx(DocumentationLink, { documentationKey: LEGEND_STUDIO_DOCUMENTATION_KEY.QUESTION_HOW_TO_WRITE_A_MAPPING_TEST }))] }, tab))) }) }), _jsxs("div", { className: "panel__content service-editor__content", children: [selectedTab === MAPPING_EDITOR_TAB.CLASS_MAPPINGS && (_jsx(MappingClassMappingEditor, {})), selectedTab === MAPPING_EDITOR_TAB.TEST_SUITES && (_jsx(MappingTestableEditor, { mappingTestableState: mappingEditorState.mappingTestableState })), mappingEditorState.migrationState && (_jsx(MappingTestMigrationTool, { mappingEditorState: mappingEditorState, migrationState: mappingEditorState.migrationState }))] })] }) })); }); //# sourceMappingURL=MappingEditor.js.map