UNPKG

@finos/legend-studio

Version:
321 lines 37.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 { observer } from 'mobx-react-lite'; import { CORE_AUTHENTICATION_STRATEGY_TYPE, CORE_DATASOURCE_SPEC_TYPE, RELATIONAL_DATABASE_TAB_TYPE, } from '../../../../stores/editor-state/element-editor-state/connection/ConnectionEditorState.js'; import { useState } from 'react'; import { ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, clsx, CustomSelectorInput, CheckSquareIcon, SquareIcon, TimesIcon, ErrorIcon, PencilIcon, } from '@finos/legend-art'; import { capitalize, prettyCONSTName } from '@finos/legend-shared'; import { DatabaseType, DelegatedKerberosAuthenticationStrategy, OAuthAuthenticationStrategy, SnowflakePublicAuthenticationStrategy, ApiTokenAuthenticationStrategy, UsernamePasswordAuthenticationStrategy, GCPWorkloadIdentityFederationAuthenticationStrategy, EmbeddedH2DatasourceSpecification, LocalH2DatasourceSpecification, SnowflakeDatasourceSpecification, DatabricksDatasourceSpecification, StaticDatasourceSpecification, BigQueryDatasourceSpecification, RedshiftDatasourceSpecification, PackageableElementExplicitReference, } from '@finos/legend-graph'; import { runInAction } from 'mobx'; import { DatabaseBuilder } from './DatabaseBuilder.js'; import { useEditorStore } from '../../EditorStoreProvider.js'; import { EDITOR_LANGUAGE, buildElementOption, } from '@finos/legend-application'; import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor.js'; import { connection_setStore } from '../../../../stores/graphModifier/DSLMapping_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_setRegion, snowflakeDatasourceSpec_setRole, snowflakeDatasourceSpec_setWarehouseName, snowflakePublicAuthenticationStrategy_setPassPhraseVaultReference, snowflakePublicAuthenticationStrategy_setPrivateKeyVaultReference, snowflakePublicAuthenticationStrategy_setPublicUserName, staticDatasourceSpecification_setDatabaseName, staticDatasourceSpecification_setHost, staticDatasourceSpecification_setPort, usernamePasswordAuthenticationStrategy_setBaseVaultReference, usernamePasswordAuthenticationStrategy_setPasswordVaultReference, usernamePasswordAuthenticationStrategy_setUserNameVaultReference, gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail, gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes, } from '../../../../stores/graphModifier/StoreRelational_GraphModifierHelper.js'; /** * NOTE: this is a WIP we did to quickly assemble a modular UI for relational database connection editor * This is subjected to change and review, especially in terms in UX. */ // TODO: consider to move this to shared export const ConnectionEditor_BooleanEditor = observer((props) => { const { value, propertyName, description, isReadOnly, update } = props; const toggle = () => { if (!isReadOnly) { update(!value); } }; return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: capitalize(propertyName) }), _jsxs("div", { className: clsx('panel__content__form__section__toggler', { 'panel__content__form__section__toggler--disabled': isReadOnly, }), onClick: toggle, children: [_jsx("button", { className: clsx('panel__content__form__section__toggler__btn', { 'panel__content__form__section__toggler__btn--toggled': value, }), disabled: isReadOnly, tabIndex: -1, children: value ? _jsx(CheckSquareIcon, {}) : _jsx(SquareIcon, {}) }), _jsx("div", { className: "panel__content__form__section__toggler__prompt", children: description })] })] })); }); // TODO: consider to move this to shared export const ConnectionEditor_StringEditor = observer((props) => { const { value, propertyName, description, isReadOnly, update } = props; const displayValue = value ?? ''; const changeValue = (event) => { const stringValue = event.target.value; const updatedValue = stringValue ? stringValue : undefined; update(updatedValue); }; return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: capitalize(propertyName) }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: description }), _jsx("input", { className: "panel__content__form__section__input", spellCheck: false, disabled: isReadOnly, value: displayValue, onChange: changeValue })] })); }); // TODO: consider to move this to shared export const ConnectionEditor_TextEditor = observer((props) => { const { value, propertyName, description, isReadOnly, language, update } = props; return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: capitalize(propertyName) }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: description }), _jsx("div", { className: "panel__content__form__section__text-editor", children: _jsx(StudioTextInputEditor, { inputValue: value ?? '', updateInput: update, isReadOnly: isReadOnly, language: language }) })] })); }); // TODO: consider to move this to shared export const ConnectionEditor_ArrayEditor = observer((props) => { const { propertyName, description, values, isReadOnly, update } = props; const arrayValues = values; // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited) const [showEditInput, setShowEditInput] = useState(false); const [itemValue, setItemValue] = useState(''); const showAddItemInput = () => setShowEditInput(true); const showEditItemInput = (value, idx) => () => { setItemValue(value); setShowEditInput(idx); }; const hideAddOrEditItemInput = () => { setShowEditInput(false); setItemValue(''); }; const changeItemInputValue = (event) => setItemValue(event.target.value); const addValue = () => { if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) { update(arrayValues.concat([itemValue])); } hideAddOrEditItemInput(); }; const updateValue = (idx) => () => { if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) { runInAction(() => { arrayValues[idx] = itemValue; }); update(arrayValues); } hideAddOrEditItemInput(); }; const deleteValue = (idx) => () => { if (!isReadOnly) { runInAction(() => arrayValues.splice(idx, 1)); update(arrayValues); // Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry if (typeof showEditInput === 'number' && showEditInput > idx) { setShowEditInput(showEditInput - 1); } } }; return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: capitalize(propertyName) }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: description }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", children: [arrayValues.map((value, idx) => ( // NOTE: since the value must be unique, we will use it as the key _jsx("div", { className: showEditInput === idx ? 'panel__content__form__section__list__new-item' : 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: updateValue(idx), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "panel__content__form__section__list__item__value", children: value }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: deleteValue(idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, value))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_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: isReadOnly, onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] })] })); }); const LocalH2DatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; const SQLValue = sourceSpec.testDataSetupSqls.join('\n'); // TODO: support CSV and toggler to go to CSV mode return (_jsx(_Fragment, { children: _jsx(ConnectionEditor_TextEditor, { isReadOnly: isReadOnly, value: SQLValue, propertyName: 'test data setup SQL', language: EDITOR_LANGUAGE.SQL, update: (value) => localH2DatasourceSpecification_setTestDataSetupSqls(sourceSpec, value ? [value] : []) }) })); }); // data source 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(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.host, propertyName: 'host', update: (value) => staticDatasourceSpecification_setHost(sourceSpec, value ?? '') }), _jsxs("div", { className: "panel__content__form__section", 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", disabled: isReadOnly, value: sourceSpec.port, onChange: changePort })] }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, propertyName: 'database', update: (value) => staticDatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') })] })); }); const EmbeddedH2DatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, propertyName: 'database', update: (value) => embeddedH2DatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.directory, propertyName: 'directory', update: (value) => embeddedH2DatasourceSpecification_setDirectory(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_BooleanEditor, { isReadOnly: isReadOnly, value: sourceSpec.autoServerMode, propertyName: 'auto server mode', update: (value) => embeddedH2DatasourceSpecification_setAutoServerMode(sourceSpec, Boolean(value)) })] })); }); const DatabricksDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.hostname, propertyName: "hostname", update: (value) => databricksDatasourceSpecification_setHostName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.port, propertyName: "port", update: (value) => databricksDatasourceSpecification_setPort(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.protocol, propertyName: "protocol", update: (value) => databricksDatasourceSpecification_setProtocol(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.httpPath, propertyName: "httpPath", update: (value) => databricksDatasourceSpecification_setHttpPath(sourceSpec, value ?? '') })] })); }); const SnowflakeDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.accountName, propertyName: "account", update: (value) => snowflakeDatasourceSpec_setAccountName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.region, propertyName: "region", update: (value) => snowflakeDatasourceSpec_setRegion(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.warehouseName, propertyName: "warehouse", update: (value) => snowflakeDatasourceSpec_setWarehouseName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, propertyName: "database", update: (value) => snowflakeDatasourceSpec_setDatabaseName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.cloudType, propertyName: "cloud type", update: (value) => snowflakeDatasourceSpec_setCloudType(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.proxyHost, propertyName: "proxy host", update: (value) => snowflakeDatasourceSpec_setProxyHost(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.proxyPort, propertyName: "proxy port", update: (value) => snowflakeDatasourceSpec_setProxyPort(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.nonProxyHosts, propertyName: "non proxy hosts", update: (value) => snowflakeDatasourceSpec_setNonProxyHosts(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.organization, propertyName: "organization", update: (value) => snowflakeDatasourceSpec_setOrganization(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.accountType, propertyName: "account type", update: (value) => snowflakeDatasourceSpec_setAccountType(sourceSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.role, propertyName: "role", update: (value) => snowflakeDatasourceSpec_setRole(sourceSpec, value) }), _jsx(ConnectionEditor_BooleanEditor, { isReadOnly: isReadOnly, value: sourceSpec.quotedIdentifiersIgnoreCase, propertyName: "quoted identifiers ignore case", description: "Controls whether Snowflake will treat alphabetic characters in double-quoted identifiers as uppercase", update: (value) => snowflakeDatasourceSpec_setQuotedIdentifiersIgnoreCase(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(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.host, propertyName: "host", 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" }), _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(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.databaseName, propertyName: "database", update: (value) => redshiftDatasourceSpecification_setDatabaseName(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.region, propertyName: "region", update: (value) => redshiftDatasourceSpecification_setRegion(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.clusterID, propertyName: "cluster", update: (value) => redshiftDatasourceSpecification_setClusterID(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.endpointURL, propertyName: "endpointURL", update: (value) => redshiftDatasourceSpecification_setEndpointURL(sourceSpec, value ?? '') })] })); }); const BigQueryDatasourceSpecificationEditor = observer((props) => { const { sourceSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.projectId, propertyName: 'project id', update: (value) => bigQueryDatasourceSpecification_setProjectId(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.defaultDataset, propertyName: 'default dataset', update: (value) => bigQueryDatasourceSpecification_setDefaultDataset(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.proxyHost, propertyName: "proxy host", description: "Specifies proxy host for connection to GCP BigQuery", update: (value) => bigQueryDatasourceSpecification_setProxyHost(sourceSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: sourceSpec.proxyPort, propertyName: "proxy port", description: "Specifies proxy port for connection to GCP BigQuery", update: (value) => bigQueryDatasourceSpecification_setProxyPort(sourceSpec, value ?? '') })] })); }); // auth strategy const DelegatedKerberosAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsx(_Fragment, { children: _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.serverPrincipal, propertyName: 'server principal', update: (value) => delegatedKerberosAuthenticationStrategy_setServerPrincipal(authSpec, value ?? '') }) })); }); const ApiTokenAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsx(_Fragment, { children: _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.apiToken, propertyName: 'apiTokenRef', update: (value) => apiTokenAuthenticationStrategy_setApiToken(authSpec, value ?? '') }) })); }); const SnowflakePublicAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.privateKeyVaultReference, propertyName: 'private key vault reference', update: (value) => snowflakePublicAuthenticationStrategy_setPrivateKeyVaultReference(authSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.passPhraseVaultReference, propertyName: 'pass phrase vault reference', update: (value) => snowflakePublicAuthenticationStrategy_setPassPhraseVaultReference(authSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.publicUserName, propertyName: 'public user name', update: (value) => snowflakePublicAuthenticationStrategy_setPublicUserName(authSpec, value ?? '') })] })); }); const OAuthAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.oauthKey, propertyName: 'oauth key', update: (value) => oAuthAuthenticationStrategy_setOauthKey(authSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.scopeName, propertyName: 'scope name', update: (value) => oAuthAuthenticationStrategy_setScopeName(authSpec, value ?? '') })] })); }); const UsernamePasswordAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.baseVaultReference, propertyName: 'base vault reference', update: (value) => usernamePasswordAuthenticationStrategy_setBaseVaultReference(authSpec, value) }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.userNameVaultReference, propertyName: 'user name vault reference', update: (value) => usernamePasswordAuthenticationStrategy_setUserNameVaultReference(authSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.passwordVaultReference, propertyName: 'password vault reference', update: (value) => usernamePasswordAuthenticationStrategy_setPasswordVaultReference(authSpec, value ?? '') })] })); }); const GCPWorkloadIdentityFederationAuthenticationStrategyEditor = observer((props) => { const { authSpec, isReadOnly } = props; const GCPScopes = authSpec.additionalGcpScopes.join('\n'); return (_jsxs(_Fragment, { children: [_jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: authSpec.serviceAccountEmail, propertyName: 'Service Account Email', update: (value) => gcpWorkloadIdentityFederationAuthenticationStrategy_setServiceAccountEmail(authSpec, value ?? '') }), _jsx(ConnectionEditor_StringEditor, { isReadOnly: isReadOnly, value: GCPScopes, propertyName: 'Additional GCP Scopes', update: (value) => gcpWorkloadIdentityFederationAuthenticationStrategy_setAdditionalGcpScopes(authSpec, value ? [value] : []) })] })); }); const RelationalConnectionStoreEditor = observer((props) => { const { connectionValueState, isReadOnly } = props; const connection = connectionValueState.connection; const databaseBuilderState = connectionValueState.databaseBuilderState; // 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 = () => databaseBuilderState.setShowModal(true); return (_jsxs("div", { className: "relational-connection-editor", children: [_jsxs("div", { className: "panel__content relational-connection-editor__auth__content", children: [_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Store" }), _jsx(CustomSelectorInput, { options: options, onChange: onStoreChange, value: selectedStore, darkMode: true, disabled: isReadOnly, hasError: isStoreEmpty })] }), _jsx("div", { children: _jsx("button", { className: "btn--dark", onClick: openDatabaseBuilder, children: "Build Database" }) })] }), _jsx(DatabaseBuilder, { databaseBuilderState: databaseBuilderState, isReadOnly: isReadOnly })] })); }); 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 { 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 GCPWorkloadIdentityFederationAuthenticationStrategy) { return (_jsx(GCPWorkloadIdentityFederationAuthenticationStrategyEditor, { 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; } }; const RelationalConnectionGeneralEditor = observer((props) => { const { connectionValueState, isReadOnly } = props; const connection = connectionValueState.connection; const editorStore = useEditorStore(); const plugins = editorStore.pluginManager.getApplicationPlugins(); // database type const typeOptions = Object.values(DatabaseType).map((e) => ({ value: e, label: e, })); const selectedType = { value: connection.type, label: connection.type, }; const onTypeChange = (val) => { dBConnection_setType(connection, val?.value ?? DatabaseType.H2); }; // source spec type const sourceSpecOptions = Object.values(CORE_DATASOURCE_SPEC_TYPE) .concat(plugins.flatMap((plugin) => plugin.getExtraDatasourceSpecificationTypes?.() ?? [])) .map((e) => ({ value: e, label: prettyCONSTName(e), })); const selectedSourceSpec = { value: connectionValueState.selectedDatasourceSpec, label: prettyCONSTName(connectionValueState.selectedDatasourceSpec), }; const onSourceSpecChange = (val) => { connectionValueState.changeDatasourceSpec(val?.value ?? CORE_DATASOURCE_SPEC_TYPE.STATIC); }; // auth type const authOptions = Object.values(CORE_AUTHENTICATION_STRATEGY_TYPE) .concat(plugins.flatMap((plugin) => plugin.getExtraAuthenticationStrategyTypes?.() ?? [])) .map((e) => ({ value: e, label: prettyCONSTName(e), })); const selectedAuth = { value: connectionValueState.selectedAuth, label: prettyCONSTName(connectionValueState.selectedAuth), }; const onAuthStrategyChange = (val) => { connectionValueState.changeAuthenticationStrategy(val?.value ?? CORE_AUTHENTICATION_STRATEGY_TYPE.OAUTH); }; return (_jsx("div", { className: "relational-connection-editor", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { size: 200, minSize: 15, children: _jsxs("div", { className: "panel", children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: "general" }) }) }), _jsxs("div", { className: "panel__content relational-connection-editor__general", children: [_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Database type" }), _jsx(CustomSelectorInput, { options: typeOptions, onChange: onTypeChange, value: selectedType, darkMode: true })] }), _jsx(ConnectionEditor_BooleanEditor, { isReadOnly: isReadOnly, value: connection.quoteIdentifiers, propertyName: "Quote identifiers", description: "Specifies whether to use double-quotes for SQL identifiers", update: (value) => dBConnection_setQuoteIdentifiers(connection, Boolean(value)) })] })] }) }), _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("div", { className: "panel__header", children: _jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: "datasource spec" }) }) }), _jsxs("div", { className: "panel__content relational-connection-editor__auth__content", children: [_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Datasource" }), _jsx(CustomSelectorInput, { options: sourceSpecOptions, onChange: onSourceSpecChange, value: selectedSourceSpec, darkMode: true })] }), _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("div", { className: "panel__header", children: _jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: "authentication spec" }) }) }), _jsxs("div", { className: "panel__content relational-connection-editor__source__content", children: [_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Authentication" }), _jsx(CustomSelectorInput, { options: authOptions, onChange: onAuthStrategyChange, value: selectedAuth, darkMode: true })] }), _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(_Fragment, { children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "uml-element-editor__tabs", children: Object.values(RELATIONAL_DATABASE_TAB_TYPE).map((tab) => (_jsx("div", { onClick: changeTab(tab), className: clsx('relational-connection-editor__tab', { 'relational-connection-editor__tab--active': tab === selectedTab, }), children: prettyCONSTName(tab) }, tab))) }) }), _jsxs("div", { className: "panel__content", 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 }))] })] })); }); //# sourceMappingURL=RelationalDatabaseConnectionEditor.js.map