UNPKG

@finos/legend-application-studio

Version:
437 lines 36.6 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 { useState, useEffect, useCallback, forwardRef } from 'react'; import { observer } from 'mobx-react-lite'; import { LakehouseRuntimeEditorState, PackageableRuntimeEditorState, RuntimeEditorRuntimeTabState, IdentifiedConnectionsEditorTabState, IdentifiedConnectionsPerClassEditorTabState, IdentifiedConnectionsPerStoreEditorTabState, LakehouseRuntimeType, } from '../../../stores/editor/editor-state/element-editor-state/RuntimeEditorState.js'; import { clsx, Dialog, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, TreeView, ContextMenu, CustomSelectorInput, createFilter, BlankPanelContent, MenuContent, MenuContentItem, BlankPanelPlaceholder, PURE_RuntimeIcon, PURE_ConnectionIcon, PURE_ModelStoreIcon, PURE_ClassIcon, PURE_MappingIcon, ChevronDownIcon, ChevronRightIcon, PlusIcon, TimesIcon, LongArrowRightIcon, CogIcon, CaretRightIcon, PanelDropZone, Panel, PanelContent, PanelHeader, ModalHeader, ModalTitle, ModalHeaderActions, ModalBody, Modal, PanelHeaderActions, PanelHeaderActionItem, LockIcon, PanelFormTextField, PanelFormSection, } from '@finos/legend-art'; import { getElementIcon } from '../../ElementIconUtils.js'; import { ConnectionEditor } from './connection-editor/ConnectionEditor.js'; import { CORE_DND_TYPE, ElementDragSource, } from '../../../stores/editor/utils/DnDUtils.js'; import { useDrop } from 'react-dnd'; import { assertErrorThrown, prettyCONSTName } from '@finos/legend-shared'; import { useEditorStore } from '../EditorStoreProvider.js'; import { Connection, ConnectionPointer, Runtime, IdentifiedConnection, RuntimePointer, ModelStore, Mapping, Class, Store, PackageableConnection, JsonModelConnection, XmlModelConnection, FlatDataConnection, RelationalDatabaseConnection, PackageableElementExplicitReference, ModelChainConnection, generateIdentifiedConnectionId, } from '@finos/legend-graph'; import { useApplicationNavigationContext, useApplicationStore, } from '@finos/legend-application'; import { buildElementOption, } from '@finos/legend-lego/graph-editor'; import { runtime_addIdentifiedConnection, runtime_deleteIdentifiedConnection, } from '../../../stores/graph-modifier/DSL_Mapping_GraphModifierHelper.js'; import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../__lib__/LegendStudioApplicationNavigationContext.js'; import { CUSTOM_LABEL } from '../../../stores/editor/NewElementState.js'; import { lakehouseRuntime_setWarehouse } from '../../../stores/graph-modifier/DSL_LakehouseRuntime_GraphModifierHelper.js'; import { useAuth } from 'react-oidc-context'; import { flowResult } from 'mobx'; const getConnectionTooltipText = (connection, editorStore) => { const connectionValue = connection instanceof ConnectionPointer ? connection.packageableConnection.value.connectionValue : connection; if (connectionValue instanceof JsonModelConnection) { return `JSON model connection \u2022 Class ${connectionValue.class.value.path}`; } else if (connectionValue instanceof XmlModelConnection) { return `XML model connection \u2022 Class ${connectionValue.class.value.path}`; } else if (connectionValue instanceof FlatDataConnection) { return `Flat-data connection \u2022 Flat-data store ${connectionValue.store.value.path}`; } else if (connectionValue instanceof RelationalDatabaseConnection) { return connectionValue.store ? `Relational database connection \u2020 database store ${connectionValue.store.value.path}` : `Relational database connection`; } else if (connectionValue instanceof ModelChainConnection) { return `Model chain connection \u2022`; } const extraConnectionToolTipTexts = editorStore.pluginManager .getApplicationPlugins() .flatMap((plugin) => plugin.getExtraRuntimeConnectionTooltipTextBuilders?.() ?? []); for (const builder of extraConnectionToolTipTexts) { const tooltipText = builder(connectionValue); if (tooltipText) { return tooltipText; } } return `Unknown connection`; }; const IdentifiedConnectionsPerStoreExplorerContextMenu = observer(forwardRef(function IdentifiedConnectionsPerStoreExplorerContextMenu(props, ref) { const { identifiedConnection, deleteIdentifiedConnection, createNewIdentifiedConnection, } = props; const remove = () => deleteIdentifiedConnection?.(); return (_jsxs(MenuContent, { ref: ref, children: [identifiedConnection && (_jsx(MenuContentItem, { onClick: remove, children: "Remove" })), !identifiedConnection && (_jsx(MenuContentItem, { onClick: createNewIdentifiedConnection, children: "Create a new connection for store" }))] })); })); export const IdentifiedConnectionsPerStoreExplorerItem = observer((props) => { const { identifiedConnection, currentRuntimeEditorTabState, isActive, isReadOnly, } = props; const editorStore = useEditorStore(); const openConnection = () => currentRuntimeEditorTabState.openIdentifiedConnection(identifiedConnection); const deleteConnection = () => currentRuntimeEditorTabState.deleteIdentifiedConnection(identifiedConnection); const openNewConnectionModal = () => currentRuntimeEditorTabState.addIdentifiedConnection(); // context menu const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] = useState(false); const onContextMenuOpen = () => setIsSelectedFromContextMenu(true); const onContextMenuClose = () => setIsSelectedFromContextMenu(false); return (_jsx(ContextMenu, { className: clsx('runtime-explorer__item', { 'context-menu__trigger--on-menu-open': !isActive && isSelectedFromContextMenu, }, { 'runtime-explorer__item--active': isActive }), disabled: isReadOnly, content: _jsx(IdentifiedConnectionsPerStoreExplorerContextMenu, { identifiedConnection: identifiedConnection, deleteIdentifiedConnection: deleteConnection, createNewIdentifiedConnection: openNewConnectionModal }), menuProps: { elevation: 7 }, onOpen: onContextMenuOpen, onClose: onContextMenuClose, children: _jsxs("button", { className: "runtime-explorer__item__label runtime-explorer__item__label--simple", onClick: openConnection, tabIndex: -1, title: getConnectionTooltipText(identifiedConnection.connection, editorStore), children: [_jsx("div", { className: "runtime-explorer__item__label__icon", children: _jsx(PURE_ConnectionIcon, {}) }), _jsx("div", { className: "runtime-explorer__item__label__text", children: identifiedConnection.id })] }) })); }); const getRuntimeExplorerTreeNodeIcon = (editorStore, node) => { if (node.data instanceof Runtime) { return _jsx(PURE_RuntimeIcon, {}); } else if (node.data instanceof ModelStore) { return _jsx(PURE_ModelStoreIcon, {}); } else if (node.data instanceof Connection) { return _jsx(PURE_ConnectionIcon, {}); } return getElementIcon(node.data, editorStore); }; const getRuntimeExplorerTreeNodeTooltipText = (node) => { if (node.data instanceof Runtime) { return ''; // number of mapping and stores } else if (node.data instanceof ModelStore) { return ''; } else if (node.data instanceof Store) { /* do nothing */ } else if (node.data instanceof Class) { // return `JSON model connection \u2022 Class ${connectionValue.class.path}`; } return undefined; }; const RuntimeExplorerTreeNodeContainer = observer((props) => { const { node, level, stepPaddingInRem, onNodeSelect, innerProps } = props; const { runtimeEditorState, onNodeExpand } = innerProps; const engineEditorState = runtimeEditorState.runtimeValueEditorState; const editorStore = useEditorStore(); const isExpandable = Boolean(node.childrenIds?.length); const nodeExpandIcon = isExpandable ? (node.isOpen ? (_jsx(ChevronDownIcon, {})) : (_jsx(ChevronRightIcon, {}))) : (_jsx("div", {})); const selectNode = () => onNodeSelect?.(node); const onExpandIconClick = () => onNodeExpand(node); // Selection const isActive = engineEditorState.isTreeNodeSelected(node); return (_jsx("div", { className: clsx('tree-view__node__container runtime-explorer__tree__node__container', { 'runtime-explorer__item--active': isActive }), onClick: selectNode, style: { paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1) + 0.5}rem`, display: 'flex', }, children: _jsxs("button", { className: "runtime-explorer__item__label", tabIndex: -1, title: getRuntimeExplorerTreeNodeTooltipText(node), children: [_jsx("div", { className: "tree-view__node__expand-icon", onClick: onExpandIconClick, children: nodeExpandIcon }), _jsx("div", { className: "runtime-explorer__item__label__icon", children: getRuntimeExplorerTreeNodeIcon(editorStore, node) }), node.data instanceof Runtime && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "runtime-explorer__item__label__text", children: [node.label, " ~"] }), _jsx("div", { className: "runtime-explorer__item__label__runtime__mapping__icon", children: _jsx(PURE_MappingIcon, {}) }), _jsx("div", { className: "runtime-explorer__item__label__runtime__mapping__text", children: engineEditorState.runtimeValue.mappings.length ? engineEditorState.runtimeValue .mappings[0].value.name : '(no mapping)' })] })), node.data instanceof Store && (_jsx("div", { className: "runtime-explorer__item__label__text", children: node.label })), node.data instanceof Class && (_jsx("div", { className: "runtime-explorer__item__label__text", children: node.label }))] }) })); }); const RuntimeExplorer = observer((props) => { const { runtimeEditorState, isReadOnly } = props; const engineEditorState = runtimeEditorState.runtimeValueEditorState; const runtime = runtimeEditorState.runtime; const runtimeValue = engineEditorState.runtimeValue; const runtimeName = runtime instanceof RuntimePointer ? runtime.packageableRuntime.value.name : CUSTOM_LABEL; // explorer tree data const treeData = engineEditorState.explorerTreeData; const onNodeSelect = (node) => engineEditorState.onExplorerTreeNodeSelect(node); const onNodeExpand = (node) => engineEditorState.onExplorerTreeNodeExpand(node); const getTreeChildNodes = (node) => engineEditorState.getExplorerTreeChildNodes(node); // DnD const handleDropRuntimeSubElement = useCallback((item) => { const element = item.data.packageableElement; if (!isReadOnly) { if (element instanceof PackageableConnection) { engineEditorState.addIdentifiedConnection(new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), new ConnectionPointer(PackageableElementExplicitReference.create(element)))); } else if (element instanceof Mapping) { engineEditorState.addMapping(element); } } }, [engineEditorState, isReadOnly, runtimeValue]); const [{ isRuntimeSubElementDragOver }, dropConnector] = useDrop(() => ({ accept: [ CORE_DND_TYPE.PROJECT_EXPLORER_CONNECTION, CORE_DND_TYPE.PROJECT_EXPLORER_MAPPING, ], drop: (item) => handleDropRuntimeSubElement(item), collect: (monitor) => ({ isRuntimeSubElementDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropRuntimeSubElement]); useEffect(() => { engineEditorState.decorateRuntimeConnections(); engineEditorState.reprocessCurrentTabState(); engineEditorState.reprocessRuntimeExplorerTree(); return () => engineEditorState.cleanUpDecoration(); }, [engineEditorState, runtimeEditorState]); return (_jsxs(Panel, { className: "runtime-explorer", children: [_jsx(PanelHeader, { title: "runtime", children: _jsx("div", { className: "panel__header__title__content", children: runtimeName }) }), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isRuntimeSubElementDragOver, children: _jsx("div", { className: "panel__content__list", children: _jsx(TreeView, { components: { TreeNodeContainer: RuntimeExplorerTreeNodeContainer, }, treeData: treeData, onNodeSelect: onNodeSelect, getChildNodes: getTreeChildNodes, innerProps: { isReadOnly, runtimeEditorState, onNodeExpand, } }) }) }) })] })); }); const IdentifiedConnectionEditor = observer((props) => { const { runtimeEditorState, currentRuntimeEditorTabState, connectionEditorState, identifiedConnection, isReadOnly, } = props; const applicationStore = useApplicationStore(); const engineEditorState = runtimeEditorState.runtimeValueEditorState; const runtimeValue = engineEditorState.runtimeValue; // TODO: add runtime connection ID // connection pointer const isEmbeddedConnection = !(identifiedConnection.connection instanceof ConnectionPointer); const embeddedConnectionLabel = (_jsxs("div", { className: "runtime-connection-editor__connection-option--custom", children: [_jsx(CogIcon, {}), _jsx("div", { className: "runtime-connection-editor__connection-option--custom__label", children: CUSTOM_LABEL })] })); // only show custom connnection option when a connnection pointer is currently selected let connectionOptions = isEmbeddedConnection ? [] : [{ label: embeddedConnectionLabel }]; connectionOptions = connectionOptions.concat(currentRuntimeEditorTabState.packageableConnections.map((packageableConnection) => ({ label: packageableConnection.path, value: packageableConnection, }))); const selectedConnectionOption = identifiedConnection.connection instanceof ConnectionPointer ? { value: identifiedConnection.connection.packageableConnection.value, label: isEmbeddedConnection ? embeddedConnectionLabel : identifiedConnection.connection.packageableConnection.value .path, } : null; const editorStore = useEditorStore(); const onConnectionSelectionChange = (val) => { if (val.value === undefined) { let customConnection; try { customConnection = currentRuntimeEditorTabState.createDefaultConnection(); } catch (error) { assertErrorThrown(error); applicationStore.notificationService.notifyWarning(error.message); return; } const newIdentifiedConnection = new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), customConnection); runtime_addIdentifiedConnection(runtimeValue, newIdentifiedConnection, editorStore.changeDetectionState.observerContext); runtime_deleteIdentifiedConnection(runtimeValue, identifiedConnection); currentRuntimeEditorTabState.openIdentifiedConnection(newIdentifiedConnection); } else if (val.value instanceof PackageableConnection && (!(identifiedConnection.connection instanceof ConnectionPointer) || val.value !== identifiedConnection.connection.packageableConnection.value)) { const connectionPointer = new ConnectionPointer(PackageableElementExplicitReference.create(val.value)); const newIdentifiedConnection = new IdentifiedConnection(generateIdentifiedConnectionId(runtimeValue), connectionPointer); runtime_addIdentifiedConnection(runtimeValue, newIdentifiedConnection, editorStore.changeDetectionState.observerContext); runtime_deleteIdentifiedConnection(runtimeValue, identifiedConnection); currentRuntimeEditorTabState.openIdentifiedConnection(newIdentifiedConnection); } }; const visitConnection = () => { if (identifiedConnection.connection instanceof ConnectionPointer) { editorStore.graphEditorMode.openElement(identifiedConnection.connection.packageableConnection.value); } }; return (_jsxs("div", { className: "runtime-connection-editor", children: [_jsxs("div", { className: "panel runtime-connection-editor__pointer", children: [_jsx(PanelHeader, { title: "runtime connection" }), _jsx(PanelContent, { children: _jsxs("div", { className: "runtime-connection-editor__connection-option", children: [_jsx("div", { className: "runtime-connection-editor__connection-option__label", children: _jsx(PURE_ConnectionIcon, {}) }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", disabled: isReadOnly, options: connectionOptions, onChange: onConnectionSelectionChange, value: selectedConnectionOption, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled }), !isEmbeddedConnection && (_jsx("button", { className: "btn--dark btn--sm runtime-connection-editor__connection-option__visit-btn", onClick: visitConnection, tabIndex: -1, title: "See connection", children: _jsx(LongArrowRightIcon, {}) }))] }) })] }), _jsx("div", { className: "runtime-connection-editor__embedded", children: _jsx(ConnectionEditor, { connectionEditorState: connectionEditorState, disableChangingStore: true, isReadOnly: isReadOnly }) })] })); }); const IdentifiedConnectionsPerStoreEditor = observer((props) => { const { isReadOnly, currentRuntimeEditorTabState, runtimeEditorState } = props; const isEmbeddedRuntime = runtimeEditorState.isEmbeddedRuntime; const connectionEditorState = currentRuntimeEditorTabState.getConnectionEditorState(); const identifiedConnection = currentRuntimeEditorTabState.identifiedConnectionEditorState ?.idenfitiedConnection; // explorer const addNewConnection = () => currentRuntimeEditorTabState.addIdentifiedConnection(); // DnD const handleDropConnection = useCallback((item) => { const element = item.data.packageableElement; if (!isReadOnly && element instanceof PackageableConnection && currentRuntimeEditorTabState.packageableConnections.includes(element)) { currentRuntimeEditorTabState.addIdentifiedConnection(element); } }, [currentRuntimeEditorTabState, isReadOnly]); const [{ isConnectionDragOver, dragItem }, dropConnector] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_CONNECTION], drop: (item) => handleDropConnection(item), collect: (monitor) => ({ isConnectionDragOver: monitor.isOver({ shallow: true }), dragItem: monitor.getItem(), }), }), [handleDropConnection]); const canDropConnection = !isReadOnly && dragItem instanceof ElementDragSource && dragItem.data.packageableElement instanceof PackageableConnection && currentRuntimeEditorTabState.packageableConnections.includes(dragItem.data.packageableElement); return (_jsx("div", { className: "runtime-store-connections-editor", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 300, minSize: 300, children: _jsxs(Panel, { className: "runtime-explorer", children: [_jsxs(PanelHeader, { children: [currentRuntimeEditorTabState instanceof IdentifiedConnectionsPerStoreEditorTabState && (_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "store" }), _jsx("div", { className: "panel__header__title__content", children: currentRuntimeEditorTabState.store.name })] })), currentRuntimeEditorTabState instanceof IdentifiedConnectionsPerClassEditorTabState && (_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "store" }), _jsx("div", { className: "panel__header__title__content", children: "ModelStore" }), _jsx("div", { className: "runtime-store-connections-editor__model-store__arrow-icon", children: _jsx(CaretRightIcon, {}) }), _jsx("div", { className: "runtime-store-connections-editor__model-store__class-icon", children: _jsx(PURE_ClassIcon, {}) }), _jsx("div", { className: "runtime-store-connections-editor__model-store__class-name", children: currentRuntimeEditorTabState.class.name })] })), _jsx(PanelHeaderActions, { children: _jsx(PanelHeaderActionItem, { disabled: isReadOnly, onClick: addNewConnection, title: "Add Connection...", children: _jsx(PlusIcon, {}) }) })] }), _jsx(ContextMenu, { className: "panel__content", disabled: isReadOnly, content: _jsx(IdentifiedConnectionsPerStoreExplorerContextMenu, { createNewIdentifiedConnection: addNewConnection }), menuProps: { elevation: 7 }, children: _jsxs(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isConnectionDragOver, children: [Boolean(currentRuntimeEditorTabState.identifiedConnections.length) && (_jsx("div", { className: "panel__content__list", children: currentRuntimeEditorTabState.identifiedConnections.map((rtConnection) => (_jsx(IdentifiedConnectionsPerStoreExplorerItem, { identifiedConnection: rtConnection, currentRuntimeEditorTabState: currentRuntimeEditorTabState, isActive: rtConnection === identifiedConnection, isReadOnly: isReadOnly }, rtConnection._UUID))) })), !currentRuntimeEditorTabState.identifiedConnections .length && (_jsx(BlankPanelPlaceholder, { text: "Add a connection", onClick: addNewConnection, clickActionType: "add", tooltipText: "Drop a connection to add it to the list, or click to add an embedded connection", isDropZoneActive: isEmbeddedRuntime ? undefined : canDropConnection, disabled: isReadOnly, previewText: "No connection" }))] }) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsxs(ResizablePanel, { children: [connectionEditorState && identifiedConnection && (_jsx(IdentifiedConnectionEditor, { runtimeEditorState: runtimeEditorState, currentRuntimeEditorTabState: currentRuntimeEditorTabState, connectionEditorState: connectionEditorState, identifiedConnection: identifiedConnection, isReadOnly: isReadOnly })), (!connectionEditorState || !identifiedConnection) && (_jsxs(Panel, { children: [_jsx(PanelHeader, { title: "runtime connection" }), _jsx(PanelContent, { children: _jsx(BlankPanelContent, { children: "No connection selected" }) })] }))] })] }) })); }); const RuntimeMappingEditor = observer((props) => { const { runtimeEditorState, mappingRef, isReadOnly } = props; const engineEditorState = runtimeEditorState.runtimeValueEditorState; const editorStore = useEditorStore(); const applicationStore = editorStore.applicationStore; const runtimeValue = engineEditorState.runtimeValue; const mappingOptions = editorStore.graphManagerState.graph.ownMappings .filter((m) => !runtimeValue.mappings.map((_m) => _m.value).includes(m)) .map(buildElementOption); const filterOption = createFilter({ ignoreCase: true, ignoreAccents: false, stringify: (option) => option.data.value.path, }); const selectedMappingOption = { value: mappingRef.value, label: mappingRef.value.name, }; const changeMapping = (val) => engineEditorState.changeMapping(mappingRef, val.value); const deleteMapping = () => engineEditorState.deleteMapping(mappingRef); const visitMapping = () => editorStore.graphEditorMode.openElement(mappingRef.value); return (_jsxs("div", { className: "panel__content__form__section__list__item--customized runtime-mapping-editor", children: [_jsx(CustomSelectorInput, { className: "runtime-mapping-editor__mapping", disabled: isReadOnly, options: mappingOptions, onChange: changeMapping, value: selectedMappingOption, placeholder: "Choose a class", filterOption: filterOption, darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled }), _jsx("button", { className: "btn--dark btn__icon--dark", onClick: visitMapping, tabIndex: -1, title: "Visit Mapping", children: _jsx(LongArrowRightIcon, {}) }), !isReadOnly && (_jsx("button", { className: "btn--dark btn__icon--dark btn--caution", disabled: runtimeValue.mappings.length < 2, onClick: deleteMapping, tabIndex: -1, title: "Remove", children: _jsx(TimesIcon, {}) }))] })); }); const RuntimeGeneralEditor = observer((props) => { const { runtimeEditorState, isReadOnly } = props; const engineEditorState = runtimeEditorState.runtimeValueEditorState; const editorStore = useEditorStore(); const runtime = runtimeEditorState.runtime; const runtimeValue = engineEditorState.runtimeValue; const isRuntimeEmbedded = !(runtime instanceof RuntimePointer); // mappings const mappings = editorStore.graphManagerState.graph.ownMappings.filter((mapping) => !runtimeValue.mappings.map((m) => m.value).includes(mapping)); const allowAddingMapping = !isReadOnly && Boolean(mappings.length); const addMapping = () => { if (allowAddingMapping) { engineEditorState.addMapping(mappings[0]); } }; const handleDropMapping = useCallback((item) => { const element = item.data.packageableElement; if (!isReadOnly && // Have to be a mapping element instanceof Mapping && // Must not be an already specified mapping !runtimeValue.mappings.map((m) => m.value).includes(element)) { engineEditorState.addMapping(element); } }, [engineEditorState, isReadOnly, runtimeValue.mappings]); const [{ isMappingDragOver }, dropConnector] = useDrop(() => ({ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_MAPPING], drop: (item) => handleDropMapping(item), collect: (monitor) => ({ isMappingDragOver: monitor.isOver({ shallow: true }), }), }), [handleDropMapping]); return (_jsxs("div", { className: "panel runtime-explorer", children: [_jsx(PanelHeader, {}), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isMappingDragOver && !isReadOnly, children: _jsx("div", { className: "panel__content__form", children: _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Mappings" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Specifies the list of mappings covered by this runtime" }), _jsxs("div", { className: "panel__content__form__section__list", children: [runtimeValue.mappings.map((mappingRef) => (_jsx(RuntimeMappingEditor, { runtimeEditorState: runtimeEditorState, mappingRef: mappingRef, isReadOnly: isReadOnly || isRuntimeEmbedded }, mappingRef.value._UUID))), !isRuntimeEmbedded && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: !allowAddingMapping, tabIndex: -1, onClick: addMapping, title: "Add Mapping", children: "Add Value" }) }))] })] }) }) }) })] })); }); const RuntimeEditorPanel = observer((props) => { const { runtimeEditorState, isReadOnly } = props; const engineEditorState = runtimeEditorState.runtimeValueEditorState; const currentRuntimeEditorTabState = engineEditorState.currentTabState; if (currentRuntimeEditorTabState instanceof IdentifiedConnectionsEditorTabState) { return (_jsx(IdentifiedConnectionsPerStoreEditor, { runtimeEditorState: runtimeEditorState, currentRuntimeEditorTabState: currentRuntimeEditorTabState, isReadOnly: isReadOnly }, runtimeEditorState.uuid)); } else if (currentRuntimeEditorTabState instanceof RuntimeEditorRuntimeTabState) { return (_jsx(RuntimeGeneralEditor, { runtimeEditorState: runtimeEditorState, runtimeEditorTabState: currentRuntimeEditorTabState, isReadOnly: isReadOnly }, runtimeEditorState.uuid)); } return _jsx("div", {}); // no need for splash screen since will always show at least a tab }); export const RuntimeEditor = observer((props) => { const { runtimeEditorState, isReadOnly } = props; return (_jsx("div", { className: "runtime-editor", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 300, minSize: 300, children: _jsx(RuntimeExplorer, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx(RuntimeEditorPanel, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) })] }) })); }); export const LakehouseRuntimeEditor = observer((props) => { const { runtimeEditorState, lakehouseRuntimeEditorState, isReadOnly } = props; const editorStore = runtimeEditorState.editorStore; const auth = useAuth(); const applicationStore = editorStore.applicationStore; const lakehouseRuntime = lakehouseRuntimeEditorState.runtimeValue; // type const typeOptions = Object.values(LakehouseRuntimeType).map((type) => ({ label: prettyCONSTName(type), value: type, })); const selectedType = { label: prettyCONSTName(lakehouseRuntimeEditorState.lakehouseRuntimeType), value: lakehouseRuntimeEditorState.lakehouseRuntimeType, }; const onTypeChange = (val) => { if (val.value !== lakehouseRuntimeEditorState.lakehouseRuntimeType) { lakehouseRuntimeEditorState.setLakehouseRuntimeType(val.value); } }; const environmentOptions = lakehouseRuntimeEditorState.envOptions; const onEnvironmentSelectionChange = (val) => { if (!val) { lakehouseRuntime.environment = undefined; return; } if (val.value !== lakehouseRuntime.environment) { lakehouseRuntime.environment = val.value; } }; const handleWarehouseChange = (val) => { lakehouseRuntime_setWarehouse(lakehouseRuntime, val); }; const selectedEnvironmentOption = lakehouseRuntime.environment ? { label: lakehouseRuntime.environment, value: lakehouseRuntime.environment, } : null; const connection = lakehouseRuntime.connectionPointer?.packageableConnection.value; const connectionOptions = editorStore.graphManagerState.usableConnections.map(buildElementOption); const selectedConnectionOption = connection ? { label: connection.path, value: connection } : null; const onConnectionSelectionChange = (val) => { if (val.value !== connection) { lakehouseRuntime.connectionPointer = new ConnectionPointer(PackageableElementExplicitReference.create(val.value)); } }; useEffect(() => { flowResult(lakehouseRuntimeEditorState.fetchLakehouseSummaries(auth.user?.access_token)).catch(applicationStore.alertUnhandledError); }, [ applicationStore.alertUnhandledError, auth.user?.access_token, lakehouseRuntimeEditorState, ]); return (_jsx(_Fragment, { children: _jsx("div", { className: "data-product-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: "lakehouse runtime" })] }) }), _jsxs("div", { className: "panel", style: { padding: '1rem', flex: 0 }, children: [_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Lakehouse Runtime Source" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: typeOptions, onChange: onTypeChange, value: selectedType, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled }) })] }), lakehouseRuntimeEditorState.lakehouseRuntimeType === LakehouseRuntimeType.ENVIRONMENT ? (_jsxs(_Fragment, { children: [_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Environment" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: environmentOptions, onChange: onEnvironmentSelectionChange, value: selectedEnvironmentOption, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled }) })] }), _jsx(PanelFormTextField, { name: "Warehouse", value: lakehouseRuntime.warehouse, prompt: "Provide the warehouse", update: handleWarehouseChange, placeholder: "Enter warehouse" })] })) : (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Connection" }), _jsx("div", { className: "explorer__new-element-modal__driver", children: _jsx(CustomSelectorInput, { className: "explorer__new-element-modal__driver__dropdown", options: connectionOptions, onChange: onConnectionSelectionChange, value: selectedConnectionOption, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled }) })] }))] })] }) }) })); }); export const PackageableRuntimeEditor = observer(() => { const editorStore = useEditorStore(); const editorState = editorStore.tabManagerState.getCurrentEditorState(PackageableRuntimeEditorState); const isReadOnly = editorState.isReadOnly; const runtimeEditorState = editorState.runtimeEditorState; const engineState = runtimeEditorState.runtimeValueEditorState; useApplicationNavigationContext(LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.RUNTIME_EDITOR); return engineState instanceof LakehouseRuntimeEditorState ? (_jsx(LakehouseRuntimeEditor, { lakehouseRuntimeEditorState: engineState, isReadOnly: isReadOnly, runtimeEditorState: editorState.runtimeEditorState })) : (_jsx(RuntimeEditor, { runtimeEditorState: editorState.runtimeEditorState, isReadOnly: isReadOnly })); }); export const EmbeddedRuntimeEditor = observer((props) => { const { runtimeEditorState, onClose, isReadOnly } = props; const applicationStore = useApplicationStore(); const closeEditor = () => onClose(); if (!runtimeEditorState) { return null; } return (_jsx(Dialog, { open: Boolean(runtimeEditorState), onClose: closeEditor, classes: { root: 'editor-modal__root-container', container: 'editor-modal__container', paper: 'editor-modal__content', }, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "editor-modal embedded-runtime-editor", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { icon: _jsx(CogIcon, {}), title: "custom runtime" }), _jsx(ModalHeaderActions, { children: _jsx("button", { className: "modal__header__action", tabIndex: -1, onClick: closeEditor, children: _jsx(TimesIcon, {}) }) })] }), _jsx(ModalBody, { className: "modal__body--footless", children: _jsx(RuntimeEditor, { runtimeEditorState: runtimeEditorState, isReadOnly: isReadOnly }) })] }) })); }); //# sourceMappingURL=RuntimeEditor.js.map