You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ta...@apache.org on 2020/11/04 19:04:01 UTC

[incubator-superset] branch master updated: style: database modal updates (#11311)

This is an automated email from the ASF dual-hosted git repository.

tai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 6981017  style: database modal updates (#11311)
6981017 is described below

commit 69810170f7a6703454764e2870d9028413fc37c4
Author: Moriah Kreeger <mo...@gmail.com>
AuthorDate: Wed Nov 4 11:03:39 2020 -0800

    style: database modal updates (#11311)
---
 .../src/common/components/InfoTooltip.tsx          | 80 ++++++++++++++++++++++
 .../src/common/components/common.stories.tsx       | 49 +++++++++++++
 .../src/views/CRUD/data/database/DatabaseModal.tsx | 67 +++++++++++-------
 3 files changed, 172 insertions(+), 24 deletions(-)

diff --git a/superset-frontend/src/common/components/InfoTooltip.tsx b/superset-frontend/src/common/components/InfoTooltip.tsx
new file mode 100644
index 0000000..1bf4bd1
--- /dev/null
+++ b/superset-frontend/src/common/components/InfoTooltip.tsx
@@ -0,0 +1,80 @@
+/**
+ * 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 from 'react';
+import { styled } from '@superset-ui/core';
+import Tooltip from 'src/common/components/Tooltip';
+import Icon from 'src/components/Icon';
+
+interface InfoTooltipProps {
+  className?: string;
+  tooltip: string;
+  placement?:
+    | 'bottom'
+    | 'left'
+    | 'right'
+    | 'top'
+    | 'topLeft'
+    | 'topRight'
+    | 'bottomLeft'
+    | 'bottomRight'
+    | 'leftTop'
+    | 'leftBottom'
+    | 'rightTop'
+    | 'rightBottom'
+    | undefined;
+  trigger?: string | Array<string>;
+  overlayStyle?: any;
+  bgColor?: string;
+}
+
+const StyledTooltip = styled(Tooltip)`
+  cursor: pointer;
+
+  path:first-of-type {
+    fill: #999999;
+  }
+`;
+
+const defaultOverlayStyle = {
+  fontSize: '12px',
+  lineHeight: '16px',
+};
+
+const defaultColor = 'rgba(0,0,0,0.9)';
+
+export default function InfoTooltip({
+  tooltip,
+  placement = 'right',
+  trigger = 'hover',
+  overlayStyle = defaultOverlayStyle,
+  bgColor = defaultColor,
+}: InfoTooltipProps) {
+  return (
+    <StyledTooltip
+      title={tooltip}
+      placement={placement}
+      trigger={trigger}
+      overlayStyle={overlayStyle}
+      color={bgColor}
+    >
+      <Icon name="info-solid-small" />
+    </StyledTooltip>
+  );
+}
diff --git a/superset-frontend/src/common/components/common.stories.tsx b/superset-frontend/src/common/components/common.stories.tsx
index 36dd7c5..19f597e 100644
--- a/superset-frontend/src/common/components/common.stories.tsx
+++ b/superset-frontend/src/common/components/common.stories.tsx
@@ -26,6 +26,7 @@ import AntdPopover from './Popover';
 import AntdTooltip from './Tooltip';
 import { Menu } from '.';
 import { Dropdown } from './Dropdown';
+import InfoTooltip from './InfoTooltip';
 
 export default {
   title: 'Common Components',
@@ -175,3 +176,51 @@ export const Tooltip = () => (
     <Button>A button with tooltip</Button>
   </AntdTooltip>
 );
+
+export const StyledInfoTooltip = (args: any) => {
+  const styles = {
+    padding: '100px 0 0 200px',
+  };
+
+  return (
+    <div style={styles}>
+      <InfoTooltip tooltip="This is the text that will display!" {...args} />
+    </div>
+  );
+};
+
+StyledInfoTooltip.args = {
+  placement: 'right',
+  trigger: 'hover',
+};
+
+StyledInfoTooltip.argTypes = {
+  placement: {
+    name: 'Placement',
+    control: {
+      type: 'select',
+      options: [
+        'bottom',
+        'left',
+        'right',
+        'top',
+        'topLeft',
+        'topRight',
+        'bottomLeft',
+        'bottomRight',
+        'leftTop',
+        'leftBottom',
+        'rightTop',
+        'rightBottom',
+      ],
+    },
+  },
+
+  trigger: {
+    name: 'Trigger',
+    control: {
+      type: 'select',
+      options: ['hover', 'click'],
+    },
+  },
+};
diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx
index 6518d0d..e384bc9 100644
--- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal.tsx
@@ -18,7 +18,7 @@
  */
 import React, { FunctionComponent, useState, useEffect } from 'react';
 import { styled, t, SupersetClient } from '@superset-ui/core';
-import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
+import InfoTooltip from 'src/common/components/InfoTooltip';
 import { useSingleViewResource } from 'src/views/CRUD/hooks';
 import withToasts from 'src/messageToasts/enhancers/withToasts';
 import getClientErrorObject from 'src/utils/getClientErrorObject';
@@ -27,6 +27,7 @@ import Modal from 'src/common/components/Modal';
 import Tabs from 'src/common/components/Tabs';
 import Button from 'src/components/Button';
 import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
+import { JsonEditor } from 'src/components/AsyncAceEditor';
 import { DatabaseObject } from './types';
 
 interface DatabaseModalProps {
@@ -45,6 +46,10 @@ const StyledIcon = styled(Icon)`
 const StyledInputContainer = styled.div`
   margin-bottom: ${({ theme }) => theme.gridUnit * 2}px;
 
+  &.extra-container {
+    padding-top: 8px;
+  }
+
   .helper {
     display: block;
     padding: ${({ theme }) => theme.gridUnit}px 0;
@@ -107,6 +112,12 @@ const StyledInputContainer = styled.div`
   }
 `;
 
+const StyledJsonEditor = styled(JsonEditor)`
+  flex: 1 1 auto;
+  border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+  border-radius: ${({ theme }) => theme.gridUnit}px;
+`;
+
 const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
   addDangerToast,
   addSuccessToast,
@@ -241,6 +252,17 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
     setDB(data);
   };
 
+  const onEditorChange = (json: string, name: string) => {
+    const data = {
+      database_name: db ? db.database_name : '',
+      sqlalchemy_uri: db ? db.sqlalchemy_uri : '',
+      ...db,
+    };
+
+    data[name] = json;
+    setDB(data);
+  };
+
   const validate = () => {
     if (
       db &&
@@ -383,8 +405,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                 onChange={onInputChange}
               />
               <div>{t('Asynchronous Query Execution')}</div>
-              <InfoTooltipWithTrigger
-                label="aqe"
+              <InfoTooltip
                 tooltip={t(
                   'Operate the database in asynchronous mode, meaning that the queries ' +
                     'are executed on remote workers as opposed to on the web server itself. ' +
@@ -406,10 +427,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                   onChange={onInputChange}
                 />
                 <div>{t('Expose in SQL Lab')}</div>
-                <InfoTooltipWithTrigger
-                  label="sql-expose"
-                  tooltip={t('Expose this DB in SQL Lab')}
-                />
+                <InfoTooltip tooltip={t('Expose this DB in SQL Lab')} />
               </div>
             </StyledInputContainer>
             <StyledInputContainer>
@@ -421,8 +439,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                   onChange={onInputChange}
                 />
                 <div>{t('Allow CREATE TABLE AS')}</div>
-                <InfoTooltipWithTrigger
-                  label="allow-cta"
+                <InfoTooltip
                   tooltip={t('Allow CREATE TABLE AS option in SQL Lab')}
                 />
               </div>
@@ -436,8 +453,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                   onChange={onInputChange}
                 />
                 <div>{t('Allow CREATE VIEW AS')}</div>
-                <InfoTooltipWithTrigger
-                  label="allow-cva"
+                <InfoTooltip
                   tooltip={t('Allow CREATE VIEW AS option in SQL Lab')}
                 />
               </div>
@@ -451,8 +467,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                   onChange={onInputChange}
                 />
                 <div>{t('Allow DML')}</div>
-                <InfoTooltipWithTrigger
-                  label="allow-dml"
+                <InfoTooltip
                   tooltip={t(
                     'Allow users to run non-SELECT statements (UPDATE, DELETE, CREATE, ...)',
                   )}
@@ -468,8 +483,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                   onChange={onInputChange}
                 />
                 <div>{t('Allow Multi Schema Metadata Fetch')}</div>
-                <InfoTooltipWithTrigger
-                  label="allow-msmf"
+                <InfoTooltip
                   tooltip={t(
                     'Allow SQL Lab to fetch a list of all tables and all views across all database ' +
                       'schemas. For large data warehouse with thousands of tables, this can be ' +
@@ -502,11 +516,15 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
           <StyledInputContainer>
             <div className="control-label">{t('Secure Extra')}</div>
             <div className="input-container">
-              <textarea
+              <StyledJsonEditor
                 name="encrypted_extra"
                 value={db ? db.encrypted_extra || '' : ''}
                 placeholder={t('Secure Extra')}
-                onChange={onTextChange}
+                onChange={(json: string) =>
+                  onEditorChange(json, 'encrypted_extra')
+                }
+                width="100%"
+                height="160px"
               />
             </div>
             <div className="helper">
@@ -552,8 +570,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                 onChange={onInputChange}
               />
               <div>{t('Impersonate Logged In User (Presto & Hive)')}</div>
-              <InfoTooltipWithTrigger
-                label="impersonate"
+              <InfoTooltip
                 tooltip={t(
                   'If Presto, all the queries in SQL Lab are going to be executed as the ' +
                     'currently logged on user who must have permission to run them. If Hive ' +
@@ -573,21 +590,23 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
                 onChange={onInputChange}
               />
               <div>{t('Allow CSV Upload')}</div>
-              <InfoTooltipWithTrigger
-                label="allow-csv"
+              <InfoTooltip
                 tooltip={t(
                   'If selected, please set the schemas allowed for csv upload in Extra.',
                 )}
               />
             </div>
           </StyledInputContainer>
-          <StyledInputContainer>
+          <StyledInputContainer className="extra-container">
             <div className="control-label">{t('Extra')}</div>
             <div className="input-container">
-              <textarea
+              <StyledJsonEditor
                 name="extra"
                 value={(db && db.extra) ?? defaultExtra}
-                onChange={onTextChange}
+                placeholder={t('Secure Extra')}
+                onChange={(json: string) => onEditorChange(json, 'extra')}
+                width="100%"
+                height="160px"
               />
             </div>
             <div className="helper">