From 2d991ec3592fc21f5783ba0abef52ee2491f1acf Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Mon, 3 May 2021 14:00:41 -0700 Subject: [PATCH] refactor: split db modal file (#14436) * split db modal file * fix tests --- .../spec/helpers/reducerIndex.ts | 2 +- .../CRUD/data/database/DatabaseModal.tsx | 662 ------------------ .../database/DatabaseModal/ExtraOptions.tsx | 378 ++++++++++ .../database/DatabaseModal/SqlAlchemyForm.tsx | 99 +++ .../index.test.jsx} | 23 +- .../data/database/DatabaseModal/index.tsx | 360 ++++++++++ .../database/{ => DatabaseModal}/styles.ts | 2 +- 7 files changed, 850 insertions(+), 676 deletions(-) delete mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/ExtraOptions.tsx create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/SqlAlchemyForm.tsx rename superset-frontend/src/views/CRUD/data/database/{DatabaseModal.test.jsx => DatabaseModal/index.test.jsx} (96%) create mode 100644 superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx rename superset-frontend/src/views/CRUD/data/database/{ => DatabaseModal}/styles.ts (98%) diff --git a/superset-frontend/spec/helpers/reducerIndex.ts b/superset-frontend/spec/helpers/reducerIndex.ts index f1cbfd47ff..e84b7f6f51 100644 --- a/superset-frontend/spec/helpers/reducerIndex.ts +++ b/superset-frontend/spec/helpers/reducerIndex.ts @@ -53,5 +53,5 @@ export default { explore, sqlLab, localStorageUsageInKilobytes, - common, + common: () => common, }; diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx deleted file mode 100644 index 4e3f6e19b5..0000000000 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx +++ /dev/null @@ -1,662 +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, { FunctionComponent, useState, useEffect } from 'react'; -import cx from 'classnames'; -import InfoTooltip from 'src/components/InfoTooltip'; -import { t, supersetTheme } from '@superset-ui/core'; -import { - useSingleViewResource, - testDatabaseConnection, -} from 'src/views/CRUD/hooks'; -import withToasts from 'src/messageToasts/enhancers/withToasts'; -import Tabs from 'src/components/Tabs'; -import Button from 'src/components/Button'; -import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox'; -import Collapse from 'src/components/Collapse'; -import { DatabaseObject } from './types'; -import { useCommonConf } from './state'; -import { - StyledModal, - StyledInputContainer, - StyledJsonEditor, - StyledExpandableForm, - StyledRequiredTab, -} from './styles'; - -interface DatabaseModalProps { - addDangerToast: (msg: string) => void; - addSuccessToast: (msg: string) => void; - onDatabaseAdd?: (database?: DatabaseObject) => void; // TODO: should we add a separate function for edit? - onHide: () => void; - show: boolean; - database?: DatabaseObject | null; // If included, will go into edit mode -} - -const DEFAULT_TAB_KEY = '1'; - -const DatabaseModal: FunctionComponent = ({ - addDangerToast, - addSuccessToast, - onDatabaseAdd, - onHide, - show, - database = null, -}) => { - const [disableSave, setDisableSave] = useState(true); - const [db, setDB] = useState(null); - const [isHidden, setIsHidden] = useState(true); - const [tabKey, setTabKey] = useState(DEFAULT_TAB_KEY); - const conf = useCommonConf(); - - const isEditMode = database !== null; - const defaultExtra = - '{\n "metadata_params": {},\n "engine_params": {},' + - '\n "metadata_cache_timeout": {},\n "schemas_allowed_for_csv_upload": [] \n}'; - - // Database fetch logic - const { - state: { loading: dbLoading, resource: dbFetched }, - fetchResource, - createResource, - updateResource, - } = useSingleViewResource( - 'database', - t('database'), - addDangerToast, - ); - - // Test Connection logic - const testConnection = () => { - if (!db || !db.sqlalchemy_uri || !db.sqlalchemy_uri.length) { - addDangerToast(t('Please enter a SQLAlchemy URI to test')); - return; - } - - const connection = { - sqlalchemy_uri: db?.sqlalchemy_uri || '', - database_name: db?.database_name?.trim() || undefined, - impersonate_user: db?.impersonate_user || undefined, - extra: db?.extra || undefined, - encrypted_extra: db?.encrypted_extra || undefined, - server_cert: db?.server_cert || undefined, - }; - - testDatabaseConnection(connection, addDangerToast, addSuccessToast); - }; - - // Functions - const hide = () => { - setIsHidden(true); - onHide(); - }; - - const onSave = () => { - if (isEditMode) { - // Edit - const update: DatabaseObject = { - database_name: db?.database_name.trim() || '', - sqlalchemy_uri: db?.sqlalchemy_uri || '', - ...db, - }; - - // Need to clean update object - if (update.id) { - delete update.id; - } - - if (db?.id) { - updateResource(db.id, update).then(result => { - if (result) { - if (onDatabaseAdd) { - onDatabaseAdd(); - } - hide(); - } - }); - } - } else if (db) { - // Create - db.database_name = db.database_name.trim(); - createResource(db).then(dbId => { - if (dbId) { - if (onDatabaseAdd) { - onDatabaseAdd(); - } - hide(); - } - }); - } - }; - - const onInputChange = (event: React.ChangeEvent) => { - const { target } = event; - const { checked, name, value, type } = target; - const data = { - database_name: db?.database_name || '', - sqlalchemy_uri: db?.sqlalchemy_uri || '', - ...db, - }; - - if (type === 'checkbox') { - data[name] = checked; - } else { - data[name] = value; - } - - setDB(data); - }; - - const onTextChange = (event: React.ChangeEvent) => { - const { target } = event; - const { name, value } = target; - const data = { - database_name: db?.database_name || '', - sqlalchemy_uri: db?.sqlalchemy_uri || '', - ...db, - }; - - data[name] = value; - setDB(data); - }; - - const onEditorChange = (json: string, name: string) => { - const data = { - database_name: db?.database_name || '', - sqlalchemy_uri: db?.sqlalchemy_uri || '', - ...db, - }; - - data[name] = json; - setDB(data); - }; - - const validate = () => { - if (db?.database_name?.trim() && db?.sqlalchemy_uri) { - setDisableSave(false); - } else { - setDisableSave(true); - } - }; - - // Initialize - if ( - isEditMode && - (!db || !db.id || database?.id !== db.id || (isHidden && show)) - ) { - if (database?.id && !dbLoading) { - const id = database.id || 0; - setTabKey(DEFAULT_TAB_KEY); - - fetchResource(id) - .then(() => { - setDB(dbFetched); - }) - .catch(e => - addDangerToast( - t( - 'Sorry there was an error fetching database information: %s', - e.message, - ), - ), - ); - } - } else if (!isEditMode && (!db || db.id || (isHidden && show))) { - setTabKey(DEFAULT_TAB_KEY); - setDB({ - database_name: '', - sqlalchemy_uri: '', - }); - } - - // Validation - useEffect(() => { - validate(); - }, [db?.database_name || null, db?.sqlalchemy_uri || null]); - - // Show/hide - if (isHidden && show) { - setIsHidden(false); - } - - const tabChange = (key: string) => { - setTabKey(key); - }; - - const expandableModalIsOpen = !!db?.expose_in_sqllab; - const createAsOpen = !!(db?.allow_ctas || db?.allow_cvas); - - return ( - {isEditMode ? t('Edit database') : t('Add database')}} - > - - {t('Basic')}} key="1"> - -
- {t('Display Name')} - * -
-
- -
-
- {t('Pick a name to help you identify this database.')} -
-
- -
- {t('SQLAlchemy URI')} - * -
-
- -
-
- {t('Refer to the ')} - - {conf?.SQLALCHEMY_DISPLAY_TEXT ?? ''} - - {t(' for more information on how to structure your URI.')} -
-
- -
- {t('Advanced')}} key="2"> - - -

SQL Lab

-

- Configure how this database will function in SQL Lab. -

- - } - key="1" - > - -
- - -
- - -
- - -
-
- -
- - -
- -
- {t('CTAS & CVAS SCHEMA')} -
-
- -
-
- {t( - 'When allowing CREATE TABLE AS option in SQL Lab, this option ' + - 'forces the table to be created in this schema.', - )} -
-
-
- -
- - -
-
- -
- - -
-
-
-
-
- -

Performance

-

- Adjust settings that will impact the performance of this - database. -

- - } - key="2" - > - -
{t('Chart cache timeout')}
-
- -
-
- {t( - 'Duration (in seconds) of the caching timeout for charts of this database.' + - ' A timeout of 0 indicates that the cache never expires.' + - ' Note this defaults to the global timeout if undefined.', - )} -
-
- -
- - -
-
-
- -

Security

-

- Add connection information for other systems. -

- - } - key="3" - > - -
{t('Secure extra')}
-
- - onEditorChange(json, 'encrypted_extra') - } - width="100%" - height="160px" - /> -
-
-
- {t( - 'JSON string containing additional connection configuration.', - )} -
-
- {t( - 'This is used to provide connection information for systems like Hive, ' + - 'Presto, and BigQuery, which do not conform to the username:password syntax ' + - 'normally used by SQLAlchemy.', - )} -
-
-
- -
{t('Root certificate')}
-
-