UNPKG

@finos/legend-application-studio

Version:
397 lines 48.1 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 { observer } from 'mobx-react-lite'; import { useState } from 'react'; import { RELATIONAL_DATABASE_TAB_TYPE, POST_PROCESSOR_TYPE, } from '../../../../stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.js'; import { ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, CustomSelectorInput, ErrorIcon, FilledWindowMaximizeIcon, PanelHeader, PlusIcon, PanelFormTextField, ContextMenu, MenuContent, MenuContentItem, PanelListSelectorItem, ControlledDropdownMenu, PanelTabs, BlankPanelContent, ResizablePanelSplitterLine, PanelContent, Panel, Badge, PanelListSelectorItemLabel, PanelFormBooleanField, PanelHeaderActions, PanelDivider, PanelFormSection, Dialog, Modal, ModalBody, ModalFooter, ModalFooterButton, ModalHeader, Button, } from '@finos/legend-art'; import { DatabaseType, DelegatedKerberosAuthenticationStrategy, OAuthAuthenticationStrategy, SnowflakePublicAuthenticationStrategy, ApiTokenAuthenticationStrategy, UsernamePasswordAuthenticationStrategy, GCPWorkloadIdentityFederationAuthenticationStrategy, MiddleTierUsernamePasswordAuthenticationStrategy, TrinoDelegatedKerberosAuthenticationStrategy, EmbeddedH2DatasourceSpecification, LocalH2DatasourceSpecification, SnowflakeDatasourceSpecification, DatabricksDatasourceSpecification, StaticDatasourceSpecification, BigQueryDatasourceSpecification, RedshiftDatasourceSpecification, PackageableElementExplicitReference, MapperPostProcessor, SpannerDatasourceSpecification, TrinoDatasourceSpecification, guaranteeRelationalDatabaseConnection, } from '@finos/legend-graph'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor'; import { CodeEditor } from '@finos/legend-lego/code-editor'; import { buildElementOption, } from '@finos/legend-lego/graph-editor'; import { connection_setStore } from '../../../../stores/graph-modifier/DSL_Mapping_GraphModifierHelper.js'; import { apiTokenAuthenticationStrategy_setApiToken, bigQueryDatasourceSpecification_setDefaultDataset, bigQueryDatasourceSpecification_setProjectId, bigQueryDatasourceSpecification_setProxyHost, bigQueryDatasourceSpecification_setProxyPort, databricksDatasourceSpecification_setHostName, databricksDatasourceSpecification_setHttpPath, databricksDatasourceSpecification_setPort, databricksDatasourceSpecification_setProtocol, dBConnection_setQuoteIdentifiers, dBConnection_setType, delegatedKerberosAuthenticationStrategy_setServerPrincipal, embeddedH2DatasourceSpecification_setAutoServerMode, embeddedH2DatasourceSpecification_setDatabaseName, embeddedH2DatasourceSpecification_setDirectory, localH2DatasourceSpecification_setTestDataSetupSqls, oAuthAuthenticationStrategy_setOauthKey, oAuthAuthenticationStrategy_setScopeName, redshiftDatasourceSpecification_setClusterID, redshiftDatasourceSpecification_setDatabaseName, redshiftDatasourceSpecification_setEndpointURL, redshiftDatasourceSpecification_setHost, redshiftDatasourceSpecification_setPort, redshiftDatasourceSpecification_setRegion, snowflakeDatasourceSpec_setAccountName, snowflakeDatasourceSpec_setAccountType, snowflakeDatasourceSpec_setCloudType, snowflakeDatasourceSpec_setDatabaseName, snowflakeDatasourceSpec_setNonProxyHosts, snowflakeDatasourceSpec_setOrganization, snowflakeDatasourceSpec_setProxyHost, snowflakeDatasourceSpec_setProxyPort, snowflakeDatasourceSpec_setQuotedIdentifiersIgnoreCase, snowflakeDatasourceSpec_setEnableQueryTags, snowflakeDatasourceSpec_setRegion, snowflakeDatasourceSpec_setRole, snowflakeDatasourceSpec_setWarehouseName, snowflakePublicAuthenticationStrategy_setPassPhraseVaultReference, snowflakePublicAuthenticationStrategy_setPrivateKeyVaultReference, snowflakePublicAuthenticationStrategy_setPublicUserName, spannerDatasourceSpecification_setDatabaseId, spannerDatasourceSpecification_setProxyHost, spannerDatasourceSpecification_setInstanceId, spannerDatasourceSpecification_setProxyPort, spannerDatasourceSpecification_setProjectId, staticDatasourceSpecification_setDatabaseName, staticDatasourceSpecification_setHost, staticDatasourceSpecification_setPort, trinoDatasourceSpecification_setHost, trinoDatasourceSpecification_setPort, trinoDatasourceSpecification_setCatalog, trinoDatasourceSpecification_setSchema, trinoDatasourceSpecification_setClientTags, trinoDatasourceSpecification_setSsl, trinoDatasourceSpecification_setTrustStorePathVaultReference, trinoDatasourceSpecification_setTrustStorePasswordVaultReference, trinoDelegatedKerberosAuthenticationStrategy_setKerberosRemoteServiceName, trinoDelegatedKerberosAuthenticationStrategy_setKerberosUseCanonicalHostname, usernamePasswordAuthenticationStrategy_setBaseVaultReference, usernamePasswordAuthenticationStrategy_setPasswordVaultReference, usernamePasswordAuthenticationStrategy_setUserNameVaultReference, gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail, gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes, middleTierUsernamePasswordAuthenticationStrategy_setVaultReference, relationalDatabaseConnection_addPostProcessor, relationalDatabaseConnection_deletePostProcessor, snowflakeDatasourceSpec_setTempTableDb, snowflakeDatasourceSpec_setTempTableSchema, dBConnection_setQueryTimeOut, } from '../../../../stores/graph-modifier/STO_Relational_GraphModifierHelper.js'; import { MapperPostProcessorEditor } from './post-processor-editor/MapperPostProcessorEditor.js'; import { UnsupportedEditorPanel } from '../UnsupportedElementEditor.js'; import { prettyCONSTName, uniq } from '@finos/legend-shared'; import { useApplicationStore } from '@finos/legend-application'; export const buildRelationalDatabaseConnectionOption = (connection) => { const connectionValue = guaranteeRelationalDatabaseConnection(connection); return { value: connection, label: (_jsxs("div", { className: "sql-playground__config__connection-selector__option", children: [_jsx("div", { className: "sql-playground__config__connection-selector__option__label", children: connection.name }), _jsx("div", { className: "sql-playground__config__connection-selector__option__type", children: connectionValue.type }), _jsx("div", { className: "sql-playground__config__connection-selector__option__path", children: connection.path })] })), }; }; const LocalH2DatasourceSpecificationEditor = observer((props) => { const applicationStore = useApplicationStore(); const { sourceSpec, isReadOnly } = props; const [showPopUp, setShowPopUp] = useState(false); const openInPopUp = () => setShowPopUp(true); const closePopUp = () => setShowPopUp(false); // TODO?: support CSV and toggler to go to CSV mode const SQLValue = sourceSpec.testDataSetupSqls.join('\n'); return (_jsxs(_Fragment, { children: [showPopUp && (_jsx("div", { children: _jsx(Dialog, { open: showPopUp, onClose: closePopUp, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled, className: "editor-modal", children: [_jsx(ModalHeader, { title: "test data setup SQL" }), _jsx(ModalBody, { className: "modal__body__large", children: _jsx(CodeEditor, { inputValue: SQLValue, updateInput: (value) => localH2DatasourceSpecification_setTestDataSetupSqls(sourceSpec, value ? [value] : []), isReadOnly: isReadOnly, language: CODE_EDITOR_LANGUAGE.SQL }) }), _jsx(ModalFooter, { children: _jsx(ModalFooterButton, { onClick: closePopUp, text: "Close", type: "secondary" }) })] }) }) })), _jsxs("div", { children: [_jsxs("div", { className: "panel__content__form__section__header__label", children: ["Test Data Setup SQL", _jsx(Button, { className: "btn--icon--small btn--icon--margin--left", onClick: openInPopUp, title: "Open...", children: _jsx(FilledWindowMaximizeIcon, {}) })] }), _jsx("div", { className: "panel__content__form__section__text-editor", children: _jsx(CodeEditor, { inputValue: SQLValue, updateInput: (value) => localH2DatasourceSpecification_setTestDataSetupSqls(sourceSpec, value ? [value] : []), isReadOnly: isReadOnly, language: CODE_EDITOR_LANGUAGE.SQL }) })] })] })); }); const StaticDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; const changePort = (event) => { const val = event.target.value; staticDatasourceSpecification_setPort(sourceSpec, parseInt(val, 10)); }; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.host, name: "host (required)", update: (value) => staticDatasourceSpecification_setHost(sourceSpec, value ?? '') }), _jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "port" }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number (required)", disabled: isReadOnly, value: sourceSpec.port, onChange: changePort })] }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, name: "database (required)", update: (value) => staticDatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') })] })); }); const EmbeddedH2DatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, name: "database (required)", update: (value) => embeddedH2DatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.directory, name: "directory (required)", update: (value) => embeddedH2DatasourceSpecification_setDirectory(sourceSpec, value ?? '') }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: sourceSpec.autoServerMode, name: "auto server mode (required)", update: (value) => embeddedH2DatasourceSpecification_setAutoServerMode(sourceSpec, Boolean(value)) })] })); }); const DatabricksDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.hostname, name: "hostname (required)", update: (value) => databricksDatasourceSpecification_setHostName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.port, name: "port (required)", update: (value) => databricksDatasourceSpecification_setPort(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.protocol, name: "protocol (required)", update: (value) => databricksDatasourceSpecification_setProtocol(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.httpPath, name: "httpPath (required)", update: (value) => databricksDatasourceSpecification_setHttpPath(sourceSpec, value ?? '') })] })); }); const TrinoDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; const changePort = (event) => { const val = event.target.value; trinoDatasourceSpecification_setPort(sourceSpec, parseInt(val, 10)); }; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.host, name: "host (required)", update: (value) => trinoDatasourceSpecification_setHost(sourceSpec, value ?? '') }), _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "port (required)" }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number", disabled: isReadOnly, value: sourceSpec.port, onChange: changePort })] }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.catalog, name: "catalog", update: (value) => trinoDatasourceSpecification_setCatalog(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.schema, name: "schema", update: (value) => trinoDatasourceSpecification_setSchema(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.clientTags, name: "clientTags", update: (value) => trinoDatasourceSpecification_setClientTags(sourceSpec, value) }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: sourceSpec.sslSpecification.ssl, name: "SSL", update: (value) => trinoDatasourceSpecification_setSsl(sourceSpec, Boolean(value)) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.sslSpecification.trustStorePathVaultReference, name: "TrustStorePathVaultReference", update: (value) => trinoDatasourceSpecification_setTrustStorePathVaultReference(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.sslSpecification.trustStorePasswordVaultReference, name: "TrustStorePasswordVaultReference", update: (value) => trinoDatasourceSpecification_setTrustStorePasswordVaultReference(sourceSpec, value) })] })); }); const SnowflakeDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.accountName, name: "account (required)", update: (value) => snowflakeDatasourceSpec_setAccountName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.region, name: "region (required)", update: (value) => snowflakeDatasourceSpec_setRegion(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.warehouseName, name: "warehouse (required)", update: (value) => snowflakeDatasourceSpec_setWarehouseName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, name: "database (required)", update: (value) => snowflakeDatasourceSpec_setDatabaseName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.cloudType, name: "cloud type", update: (value) => snowflakeDatasourceSpec_setCloudType(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyHost, name: "proxy host", update: (value) => snowflakeDatasourceSpec_setProxyHost(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyPort, name: "proxy port", update: (value) => snowflakeDatasourceSpec_setProxyPort(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.nonProxyHosts, name: "non proxy hosts", update: (value) => snowflakeDatasourceSpec_setNonProxyHosts(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.organization, name: "organization", update: (value) => snowflakeDatasourceSpec_setOrganization(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.accountType, name: "account type", update: (value) => snowflakeDatasourceSpec_setAccountType(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.role, name: "role", update: (value) => snowflakeDatasourceSpec_setRole(sourceSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.tempTableDb, name: "Temp Table DB", update: (value) => snowflakeDatasourceSpec_setTempTableDb(sourceSpec, value ?? undefined) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.tempTableSchema, name: "Temp Table Schema", update: (value) => snowflakeDatasourceSpec_setTempTableSchema(sourceSpec, value ?? undefined) }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: sourceSpec.quotedIdentifiersIgnoreCase, name: "quoted identifiers ignore case", prompt: "Controls whether Snowflake will treat alphabetic characters in double-quoted identifiers as uppercase", update: (value) => snowflakeDatasourceSpec_setQuotedIdentifiersIgnoreCase(sourceSpec, Boolean(value)) }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: sourceSpec.enableQueryTags, name: "Enable Query Tags", prompt: "Controls whether engine sets a tag on each query for identification", update: (value) => snowflakeDatasourceSpec_setEnableQueryTags(sourceSpec, Boolean(value)) })] })); }); const RedshiftDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; const changePort = (event) => { const val = event.target.value; redshiftDatasourceSpecification_setPort(sourceSpec, parseInt(val, 10)); }; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.host, name: "host (required)", update: (value) => redshiftDatasourceSpecification_setHost(sourceSpec, value ?? '') }), _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "port (required)" }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number", disabled: isReadOnly, value: sourceSpec.port, onChange: changePort })] }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, name: "database (required)", update: (value) => redshiftDatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.region, name: "region (required)", update: (value) => redshiftDatasourceSpecification_setRegion(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.clusterID, name: "cluster (required)", update: (value) => redshiftDatasourceSpecification_setClusterID(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.endpointURL, name: "endpointURL", update: (value) => redshiftDatasourceSpecification_setEndpointURL(sourceSpec, value ?? '') })] })); }); const BigQueryDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.projectId, name: "project id (required)", update: (value) => bigQueryDatasourceSpecification_setProjectId(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.defaultDataset, name: "default dataset", update: (value) => bigQueryDatasourceSpecification_setDefaultDataset(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyHost, name: "proxy host", prompt: "Specifies proxy host for connection to GCP BigQuery", update: (value) => bigQueryDatasourceSpecification_setProxyHost(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyPort, name: "proxy port", prompt: "Specifies proxy port for connection to GCP BigQuery", update: (value) => bigQueryDatasourceSpecification_setProxyPort(sourceSpec, value ?? '') })] })); }); const SpannerDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.projectId, name: "project id (required)", prompt: "Your Google Cloud Platform (GCP) project identifier", update: (value) => spannerDatasourceSpecification_setProjectId(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.instanceId, name: "instance id (required)", prompt: "Spanner instance identifier in Google Cloud Platform (GCP)", update: (value) => spannerDatasourceSpecification_setInstanceId(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.databaseId, name: "database id (required)", prompt: "Spanner database identifier", update: (value) => spannerDatasourceSpecification_setDatabaseId(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyHost, name: "proxyHost", prompt: "Specifies the connection host. Leave blank to use GCP defaults", update: (value) => spannerDatasourceSpecification_setProxyHost(sourceSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: sourceSpec.proxyPort, name: "proxyPort", prompt: "Specifies the connection port. Leave blank to use GCP defaults", update: (value) => spannerDatasourceSpecification_setProxyPort(sourceSpec, value ?? '') })] })); }); // auth strategy const DelegatedKerberosAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsx(_Fragment, { children: _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.serverPrincipal, name: "server principal", update: (value) => delegatedKerberosAuthenticationStrategy_setServerPrincipal(authSpec, value ?? '') }) })); }); const ApiTokenAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsx(_Fragment, { children: _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.apiToken, name: "apiTokenRef (required)", update: (value) => apiTokenAuthenticationStrategy_setApiToken(authSpec, value ?? '') }) })); }); const SnowflakePublicAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.privateKeyVaultReference, name: "private key vault reference (required)", update: (value) => snowflakePublicAuthenticationStrategy_setPrivateKeyVaultReference(authSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.passPhraseVaultReference, name: "pass phrase vault reference (required)", update: (value) => snowflakePublicAuthenticationStrategy_setPassPhraseVaultReference(authSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.publicUserName, name: "public user name (required)", update: (value) => snowflakePublicAuthenticationStrategy_setPublicUserName(authSpec, value ?? '') })] })); }); const OAuthAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.oauthKey, name: "oauth key (required)", update: (value) => oAuthAuthenticationStrategy_setOauthKey(authSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.scopeName, name: "scope name (required)", update: (value) => oAuthAuthenticationStrategy_setScopeName(authSpec, value ?? '') })] })); }); const UsernamePasswordAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.baseVaultReference, name: "base vault reference", update: (value) => usernamePasswordAuthenticationStrategy_setBaseVaultReference(authSpec, value) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.userNameVaultReference, name: "user name vault reference (required)", update: (value) => usernamePasswordAuthenticationStrategy_setUserNameVaultReference(authSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.passwordVaultReference, name: "password vault reference (required)", update: (value) => usernamePasswordAuthenticationStrategy_setPasswordVaultReference(authSpec, value ?? '') })] })); }); // Middle Tier Username Password Authentication Strategy obtains credentials(username and password) from the provided vault reference const MiddleTierUsernamePasswordAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsx(_Fragment, { children: _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.vaultReference, name: "vault reference (required)", prompt: "Specifies the credential vault reference containing connection credentials", update: (value) => middleTierUsernamePasswordAuthenticationStrategy_setVaultReference(authSpec, value ?? '') }) })); }); const TrinoDelegatedKerberosAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.kerberosRemoteServiceName, name: "Kerberos Remote Service Name (required)", prompt: "Specifies the Kerberos Remote Service Name", update: (value) => trinoDelegatedKerberosAuthenticationStrategy_setKerberosRemoteServiceName(authSpec, value ?? '') }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: authSpec.kerberosUseCanonicalHostname, name: "kerberosUseCanonicalHostname", prompt: "Specifies KerberosUseCanonicalHostname", update: (value) => trinoDelegatedKerberosAuthenticationStrategy_setKerberosUseCanonicalHostname(authSpec, Boolean(value)) })] })); }); const GCPWorkloadIdentityFederationAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; const GCPScopes = authSpec.additionalGcpScopes.join('\n'); return (_jsxs(_Fragment, { children: [_jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: authSpec.serviceAccountEmail, name: "Service Account Email (required)", update: (value) => gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail(authSpec, value ?? '') }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: GCPScopes, name: "Additional GCP Scopes", update: (value) => gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes(authSpec, value ? [value] : []) })] })); }); const RelationalConnectionStoreEditor = observer((props) => { const { connectionValueState, isReadOnly } = props; const applicationStore = connectionValueState.editorStore.applicationStore; const connection = connectionValueState.connection; // store const isStoreEmpty = connectionValueState.storeValidationResult; const noStoreLabel = (_jsxs("div", { className: "relational-connection-editor__store-option--empty", title: isStoreEmpty?.messages.join('\n') ?? '', children: [_jsx("div", { className: "relational-connection-editor__store-option--empty__label", children: "(none)" }), _jsx(ErrorIcon, {})] })); const stores = connectionValueState.editorStore.graphManagerState.graph.ownStores; const options = stores.map(buildElementOption); const store = connection.store.value; const selectedStore = { value: store, label: isStoreEmpty ? noStoreLabel : store.path, }; const onStoreChange = (val) => { if (val) { connection_setStore(connection, PackageableElementExplicitReference.create(val.value)); } }; const openDatabaseBuilder = () => connectionValueState.editorStore.explorerTreeState.buildDatabase(connection, isReadOnly); return (_jsx("div", { className: "relational-connection-editor", children: _jsx(PanelContent, { className: "relational-connection-editor__auth__content", children: _jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Store" }), _jsx(CustomSelectorInput, { options: options, onChange: onStoreChange, value: selectedStore, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled, disabled: isReadOnly, hasError: Boolean(isStoreEmpty) }), _jsx(PanelDivider, {}), _jsx("button", { className: "relational-connection-editor-btn btn--dark", onClick: openDatabaseBuilder, children: "Build Database" })] }) }) })); }); const renderEditorPostProcessor = (connectionValueState, postProcessor, isReadOnly, plugins) => { if (postProcessor instanceof MapperPostProcessor) { return (_jsx(MapperPostProcessorEditor, { postProcessorState: connectionValueState.postProcessorState, isReadOnly: isReadOnly, postProcessor: postProcessor })); } else { const extraPostProcessorEditorRenderers = plugins.flatMap((plugin) => plugin.getExtraPostProcessorEditorRenderers?.() ?? []); for (const editorRenderer of extraPostProcessorEditorRenderers) { const editor = editorRenderer(postProcessor, connectionValueState, false); if (editor) { return editor; } } return (_jsx(UnsupportedEditorPanel, { isReadOnly: true, text: "Can't display post-processor in form mode" })); } }; const PostProcessorRelationalConnectionEditor = observer((props) => { const { connectionValueState, isReadOnly } = props; const connection = connectionValueState.connection; const postProcessors = connection.postProcessors; const editorStore = useEditorStore(); const observerContext = editorStore.changeDetectionState.observerContext; const plugins = editorStore.pluginManager.getApplicationPlugins(); const postProcessorState = connectionValueState.postProcessorState; const deletePostProcessor = (postProcessor) => () => { relationalDatabaseConnection_deletePostProcessor(connectionValueState, postProcessor); if (postProcessor === connectionValueState.postProcessorState?.postProcessor) { connectionValueState.postProcessorState.setPostProcessorState(undefined); } }; const postProcessorOptions = Object.values(POST_PROCESSOR_TYPE) .concat(plugins.flatMap((plugin) => plugin.getExtraPostProcessorClassifiers?.() ?? [])) .map((type) => ({ value: type, label: type, })); const addPostProcessor = (postProcessorType) => () => { switch (postProcessorType) { case POST_PROCESSOR_TYPE.MAPPER: { relationalDatabaseConnection_addPostProcessor(connectionValueState, new MapperPostProcessor(), observerContext); break; } default: { const extraPostProcessorCreators = plugins.flatMap((plugin) => plugin.getExtraPostProcessorCreators?.() ?? []); for (const creator of extraPostProcessorCreators) { creator(postProcessorType, connectionValueState, observerContext); } } } connectionValueState.postProcessorState?.setPostProcessorState(connectionValueState.connection.postProcessors[connectionValueState.connection.postProcessors.length - 1]); }; const selectPostProcessor = (postProcessor) => { connectionValueState.selectPostProcessor(postProcessor); }; const getPostProcessorLabel = (postProcessor) => { if (postProcessor instanceof MapperPostProcessor) { return POST_PROCESSOR_TYPE.MAPPER; } else { const extraPostProcessorEditorClassifier = plugins.flatMap((plugin) => plugin.getExtraPostProcessorClassifierGetters?.() ?? []); for (const classify of extraPostProcessorEditorClassifier) { const label = classify(postProcessor); if (label) { return label; } } } return 'unknown type'; }; return (_jsx("div", { className: "relational-connection-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx("div", { className: "relational-connection-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 200, minSize: 100, children: _jsxs(Panel, { children: [_jsx(PanelHeader, { title: "post-processor", children: _jsx(PanelHeaderActions, { children: _jsx(ControlledDropdownMenu, { title: "Create post-processor", className: "panel__header__action", disabled: isReadOnly, content: postProcessorOptions.map((postProcessorType) => (_jsxs(MenuContentItem, { onClick: addPostProcessor(postProcessorType.value), children: ["New ", postProcessorType.label, " Post-Processor"] }, postProcessorType.value))), menuProps: { anchorOrigin: { vertical: 'bottom', horizontal: 'right', }, transformOrigin: { vertical: 'top', horizontal: 'right', }, elevation: 7, }, children: _jsx(PlusIcon, {}) }) }) }), _jsx(PanelContent, { children: postProcessors.map((postProcessor, idx) => (_jsx(ContextMenu, { disabled: isReadOnly, content: _jsx(MenuContent, { children: _jsx(MenuContentItem, { onClick: deletePostProcessor(postProcessor), children: "Delete" }) }), menuProps: { elevation: 7 }, children: _jsxs(PanelListSelectorItem, { onSelect: () => selectPostProcessor(postProcessor), isSelected: postProcessor === postProcessorState?.postProcessor, children: [_jsx(PanelListSelectorItemLabel, { title: `Post-Processor ${idx + 1}` }), _jsx(Badge, { className: "badge--right", title: getPostProcessorLabel(postProcessor) })] }) }, postProcessor._UUID))) })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsxs(ResizablePanel, { children: [postProcessorState?.postProcessor && renderEditorPostProcessor(connectionValueState, postProcessorState.postProcessor, isReadOnly, plugins), !postProcessorState && (_jsx(BlankPanelContent, { children: !postProcessors.length ? 'Add a post-processor' : 'Choose a post-processor to view' }))] })] }) }) })] }) })); }); const renderDatasourceSpecificationEditor = (connection, isReadOnly, plugins) => { const sourceSpec = connection.datasourceSpecification; if (sourceSpec instanceof StaticDatasourceSpecification) { return (_jsx(StaticDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof EmbeddedH2DatasourceSpecification) { return (_jsx(EmbeddedH2DatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof DatabricksDatasourceSpecification) { return (_jsx(DatabricksDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof SnowflakeDatasourceSpecification) { return (_jsx(SnowflakeDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof BigQueryDatasourceSpecification) { return (_jsx(BigQueryDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof RedshiftDatasourceSpecification) { return (_jsx(RedshiftDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof LocalH2DatasourceSpecification) { return (_jsx(LocalH2DatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof SpannerDatasourceSpecification) { return (_jsx(SpannerDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else if (sourceSpec instanceof TrinoDatasourceSpecification) { return (_jsx(TrinoDatasourceSpecificationEditor, { sourceSpec: sourceSpec, isReadOnly: isReadOnly })); } else { const extraDatasourceSpecificationEditorRenderers = plugins.flatMap((plugin) => plugin.getExtraDatasourceSpecificationEditorRenderers?.() ?? []); for (const editorRenderer of extraDatasourceSpecificationEditorRenderers) { const editor = editorRenderer(sourceSpec, isReadOnly); if (editor) { return editor; } } // TODO: create unsupported screen return null; } }; const renderAuthenticationStrategyEditor = (connection, isReadOnly, plugins) => { const authSpec = connection.authenticationStrategy; if (authSpec instanceof DelegatedKerberosAuthenticationStrategy) { return (_jsx(DelegatedKerberosAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof SnowflakePublicAuthenticationStrategy) { return (_jsx(SnowflakePublicAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof ApiTokenAuthenticationStrategy) { return (_jsx(ApiTokenAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof OAuthAuthenticationStrategy) { return (_jsx(OAuthAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof UsernamePasswordAuthenticationStrategy) { return (_jsx(UsernamePasswordAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof MiddleTierUsernamePasswordAuthenticationStrategy) { return (_jsx(MiddleTierUsernamePasswordAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof GCPWorkloadIdentityFederationAuthenticationStrategy) { return (_jsx(GCPWorkloadIdentityFederationAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else if (authSpec instanceof TrinoDelegatedKerberosAuthenticationStrategy) { return (_jsx(TrinoDelegatedKerberosAuthenticationStrategyEditor, { authSpec: authSpec, isReadOnly: isReadOnly })); } else { const extraAuthenticationStrategyEditorRenderers = plugins.flatMap((plugin) => plugin.getExtraAuthenticationStrategyEditorRenderers?.() ?? []); for (const editorRenderer of extraAuthenticationStrategyEditorRenderers) { const editor = editorRenderer(authSpec, isReadOnly); if (editor) { return editor; } } // TODO: create unsupported screen return null; } }; export const RelationalConnectionGeneralEditor = observer((props) => { const { connectionValueState, isReadOnly, hideHeader } = props; const connection = connectionValueState.connection; const editorStore = useEditorStore(); const applicationStore = editorStore.applicationStore; const plugins = editorStore.pluginManager.getApplicationPlugins(); const databseTypeConfigs = connectionValueState.editorStore.graphState .relationalDatabseTypeConfigurations; const availableDbTypes = databseTypeConfigs?.length ? // Currently H2 Flow is not returned in relational configs. We will remove this once it is properly returned as a supported flow in engine uniq([DatabaseType.H2, ...databseTypeConfigs.map((e) => e.type)]) : Object.values(DatabaseType); const dbTypes = availableDbTypes.map((dbType) => ({ value: dbType, label: dbType, })); const selectedDbType = { value: connection.type, label: connection.type, }; const changeTimeOut = (event) => { const val = event.target.value; dBConnection_setQueryTimeOut(connection, val === '' ? undefined : parseInt(val, 10)); }; const onTypeChange = (val) => { dBConnection_setType(connection, val?.value ?? DatabaseType.H2); if (connectionValueState.selectedValidDatasources[0]) { connectionValueState.changeDatasourceSpec(connectionValueState.selectedValidDatasources[0]); } if (connectionValueState.selectedValidAuthenticationStrategies[0]) { connectionValueState.changeAuthenticationStrategy(connectionValueState.selectedValidAuthenticationStrategies[0]); } }; // source spec type const sourceSpecOptions = connectionValueState.selectedValidDatasources.map((type) => ({ value: type, label: prettyCONSTName(type), })); const selectedSourceSpec = (spec) => ({ label: prettyCONSTName(connectionValueState.selectedDatasourceSpecificationType(spec) ?? 'Unknown'), value: connectionValueState.selectedDatasourceSpecificationType(spec), }); const onSourceSpecChange = (val) => { if (val?.value) { connectionValueState.changeDatasourceSpec(val.value); } }; // auth type const authOptions = connectionValueState.selectedValidAuthenticationStrategies.map((type) => ({ value: type, label: prettyCONSTName(type), })); const selectedAuth = (auth) => ({ label: prettyCONSTName(connectionValueState.selectedAuthenticationStrategyType(auth) ?? 'Unknown'), value: connectionValueState.selectedAuthenticationStrategyType(auth), }); const onAuthStrategyChange = (val) => { if (val?.value) { connectionValueState.changeAuthenticationStrategy(val.value); } }; // HACKY: if (connection.localMode) { return (_jsx("div", { className: "relational-connection-editor", children: _jsxs(Panel, { children: [_jsx(PanelHeader, { title: "general" }), _jsx(PanelContent, { className: "relational-connection-editor__general", children: _jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Database Type" }), _jsx(CustomSelectorInput, { options: dbTypes, onChange: onTypeChange, value: selectedDbType, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled })] }) })] }) })); } return (_jsx("div", { className: "relational-connection-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { size: 200, minSize: 15, children: _jsxs(Panel, { children: [!hideHeader && _jsx(PanelHeader, { title: "general" }), _jsxs(PanelContent, { className: "relational-connection-editor__general", children: [_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Database Type" }), _jsx(CustomSelectorInput, { options: dbTypes, onChange: onTypeChange, value: selectedDbType, darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled })] }), _jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: connection.quoteIdentifiers, name: "Quote identifiers", prompt: "Specifies whether to use double-quotes for SQL identifiers", update: (value) => dBConnection_setQuoteIdentifiers(connection, Boolean(value)) }), _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Query timeout (in seconds)" }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number", disabled: isReadOnly, value: connection.queryTimeOutInSeconds, onChange: changeTimeOut })] })] })] }) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { children: _jsx("div", { className: "relational-connection-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 450, minSize: 50, children: _jsxs("div", { className: "relational-connection-editor__auth", children: [_jsx(PanelHeader, { title: "datasource specification" }), _jsxs(PanelContent, { className: "relational-connection-editor__auth__content", children: [_jsxs(PanelFormSection, { children: [_jsx("div", { style: { width: '100%' }, children: _jsx("div", { style: { display: 'inline-block', width: '10px' }, className: "panel__content__form__section__header__label", children: "Datasource" }) }), _jsx(CustomSelectorInput, { options: sourceSpecOptions, onChange: onSourceSpecChange, value: selectedSourceSpec(connection.datasourceSpecification), darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled })] }), _jsx(PanelDivider, {}), _jsx("div", { className: "relational-connection-editor__auth__properties", children: renderDatasourceSpecificationEditor(connection, isReadOnly, plugins) })] })] }) }), _jsx(ResizablePanelSplitter, {}), _jsx(ResizablePanel, { children: _jsxs("div", { className: "relational-connection-editor__source", children: [_jsx(PanelHeader, { title: "authentication strategy" }), _jsxs(PanelContent, { className: "relational-connection-editor__source__content", children: [_jsxs(PanelFormSection, { children: [_jsx("div", { style: { width: '100%' }, children: _jsx("div", { style: { display: 'inline-block', width: '10px' }, className: "panel__content__form__section__header__label", children: "Authentication" }) }), _jsx(CustomSelectorInput, { options: authOptions, onChange: onAuthStrategyChange, value: selectedAuth(connection.authenticationStrategy), darkMode: !applicationStore.layoutService .TEMPORARY__isLightColorThemeEnabled })] }), _jsx(PanelDivider, {}), _jsx("div", { className: "relational-connection-editor__source__properties", children: renderAuthenticationStrategyEditor(connection, isReadOnly, plugins) })] })] }) })] }) }) })] }) })); }); export const RelationalDatabaseConnectionEditor = observer((props) => { const { connectionValueState, isReadOnly } = props; const selectedTab = connectionValueState.selectedTab; const changeTab = (tab) => () => { connectionValueState.setSelectedTab(tab); }; return (_jsxs(Panel, { children: [_jsx(PanelTabs, { tabs: Object.values(RELATIONAL_DATABASE_TAB_TYPE), changeTab: changeTab, selectedTab: selectedTab, tabClassName: "relational-connection-editor__tab" }), _jsxs(PanelContent, { children: [selectedTab === RELATIONAL_DATABASE_TAB_TYPE.GENERAL && (_jsx(RelationalConnectionGeneralEditor, { connectionValueState: connectionValueState, isReadOnly: isReadOnly })), selectedTab === RELATIONAL_DATABASE_TAB_TYPE.STORE && (_jsx(RelationalConnectionStoreEditor, { connectionValueState: connectionValueState, isReadOnly: isReadOnly })), selectedTab === RELATIONAL_DATABASE_TAB_TYPE.POST_PROCESSORS && (_jsx(PostProcessorRelationalConnectionEditor, { connectionValueState: connectionValueState, isReadOnly: isReadOnly }))] })] })); }); //# sourceMappingURL=RelationalDatabaseConnectionEditor.js.map