@finos/legend-studio
Version:
321 lines • 37.6 kB
JavaScript
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