From 62774d2028ab09ba228369300967293e573d4dc0 Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Thu, 30 Sep 2021 12:14:31 -0400 Subject: [PATCH] refactor(DB Connections): Build Snowflake Dynamic Form (#16875) * moved all non-BasicParameters into own field * refactored DB Connection Form made ValidatedInput --- setup.cfg | 2 +- .../DatabaseModal/DatabaseConnectionForm.tsx | 668 ------------------ .../CommonParameters.tsx | 207 ++++++ .../DatabaseConnectionForm/EncryptedField.tsx | 198 ++++++ .../DatabaseConnectionForm/TableCatalog.tsx | 104 +++ .../ValidatedInputField.tsx | 62 ++ .../DatabaseConnectionForm/index.tsx | 172 +++++ superset/datasets/dao.py | 2 +- superset/db_engine_specs/snowflake.py | 56 +- superset/models/core.py | 2 +- 10 files changed, 779 insertions(+), 694 deletions(-) delete mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/CommonParameters.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/EncryptedField.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/TableCatalog.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/ValidatedInputField.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm/index.tsx diff --git a/setup.cfg b/setup.cfg index 20bf9082a28b7..9a108f76a480e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = superset -known_third_party =alembic,apispec,babel,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml +known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml multi_line_output = 3 order_by_type = false diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx deleted file mode 100644 index a188126f4a50c..0000000000000 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx +++ /dev/null @@ -1,668 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 React, { FormEvent, useState } from 'react'; -import { SupersetTheme, JsonObject, t } from '@superset-ui/core'; -import { InputProps } from 'antd/lib/input'; -import { Switch, Select, Button } from 'src/common/components'; -import InfoTooltip from 'src/components/InfoTooltip'; -import ValidatedInput from 'src/components/Form/LabeledErrorBoundInput'; -import FormLabel from 'src/components/Form/FormLabel'; -import { DeleteFilled, CloseOutlined } from '@ant-design/icons'; -import { - formScrollableStyles, - validatedFormStyles, - CredentialInfoForm, - toggleStyle, - infoTooltip, - StyledFooterButton, - StyledCatalogTable, - labelMarginBotton, -} from './styles'; -import { CatalogObject, DatabaseForm, DatabaseObject } from '../types'; - -// These are the columns that are going to be added to encrypted extra, they differ in name based -// on the engine, however we want to use the same component for each of them. Make sure to add the -// the engine specific name here. -export const encryptedCredentialsMap = { - gsheets: 'service_account_info', - bigquery: 'credentials_info', -}; - -enum CredentialInfoOptions { - jsonUpload, - copyPaste, -} - -const castStringToBoolean = (optionValue: string) => optionValue === 'true'; - -export const FormFieldOrder = [ - 'host', - 'port', - 'database', - 'username', - 'password', - 'database_name', - 'credentials_info', - 'service_account_info', - 'catalog', - 'query', - 'encryption', - 'account', - 'warehouse', - 'role', -]; - -interface FieldPropTypes { - required: boolean; - hasTooltip?: boolean; - tooltipText?: (value: any) => string; - onParametersChange: (value: any) => string; - onParametersUploadFileChange: (value: any) => string; - changeMethods: { onParametersChange: (value: any) => string } & { - onChange: (value: any) => string; - } & { - onQueryChange: (value: any) => string; - } & { onParametersUploadFileChange: (value: any) => string } & { - onAddTableCatalog: () => void; - onRemoveTableCatalog: (idx: number) => void; - }; - validationErrors: JsonObject | null; - getValidation: () => void; - db?: DatabaseObject; - isEditMode?: boolean; - sslForced?: boolean; - defaultDBName?: string; - editNewDb?: boolean; -} - -const CredentialsInfo = ({ - changeMethods, - isEditMode, - db, - editNewDb, -}: FieldPropTypes) => { - const [uploadOption, setUploadOption] = useState( - CredentialInfoOptions.jsonUpload.valueOf(), - ); - const [fileToUpload, setFileToUpload] = useState( - null, - ); - const [isPublic, setIsPublic] = useState(true); - const showCredentialsInfo = - db?.engine === 'gsheets' ? !isEditMode && !isPublic : !isEditMode; - // a database that has an optional encrypted field has an encrypted_extra that is an empty object, this checks for that. - const isEncrypted = isEditMode && db?.encrypted_extra !== '{}'; - const encryptedField = db?.engine && encryptedCredentialsMap[db.engine]; - const encryptedValue = - typeof db?.parameters?.[encryptedField] === 'object' - ? JSON.stringify(db?.parameters?.[encryptedField]) - : db?.parameters?.[encryptedField]; - return ( - - {db?.engine === 'gsheets' && ( -
- labelMarginBotton(theme)} - required - > - {t('Type of Google Sheets allowed')} - - -
- )} - {showCredentialsInfo && ( - <> - - {t('How∂ do you want to enter service account credentials?')} - - - - )} - {uploadOption === CredentialInfoOptions.copyPaste || - isEditMode || - editNewDb ? ( -
- {t('Service Account')} -