Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add tooltips and button to Connect Postgresql DB Modal Form #15179

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bf0131e
Added tooltips. Still need to place in the right spot.
Jun 15, 2021
69682a9
Revert to where I started.
Jun 15, 2021
8f9475b
Merge remote-tracking branch 'upstream/pexdax/db-connection-ui' into …
andrewbastian Jun 15, 2021
dbf8770
Added 3 tooltips, 1 Button(need link config). BigQuery not added yet.
andrewbastian Jun 15, 2021
e590bfc
Merge branch 'pexdax/db-connection-ui' of https://github.com//apache/…
andrewbastian Jun 16, 2021
fa6c2c5
Added tooltip BigOuery modal. `span` above upload btn missing `*`
andrewbastian Jun 16, 2021
23178d4
Merge branch 'pexdax/db-connection-ui' of https://github.com//apache/…
andrewbastian Jun 17, 2021
aea5905
Added tooltip to `Host` field. Alignment needs to be fixed.
andrewbastian Jun 17, 2021
9a2216d
Merge branch 'pexdax/db-connection-ui' of https://github.com//apache/…
andrewbastian Jun 17, 2021
2622bfe
Stuck trying to add conditional render of tooltip to LabeledErrorBoun…
andrewbastian Jun 17, 2021
b73b40b
Clean commit for review
andrewbastian Jun 18, 2021
a4654a3
Dynamic tooltip componet created. Needs alignment of SVG still.
andrewbastian Jun 18, 2021
8d364cc
Merge branch 'pexdax/db-connection-ui' of https://github.com//apache/…
andrewbastian Jun 18, 2021
c1325ab
Fixed typo.
andrewbastian Jun 18, 2021
46ebb23
Added line spacing back in
andrewbastian Jun 18, 2021
c8bbce0
Changed required props to optional/Remove comment
andrewbastian Jun 18, 2021
49bafb3
Fixed alignment of tooltips & moved 2tooltips outside of Btn
andrewbastian Jun 18, 2021
6da403e
Merge branch 'pexdax/db-connection-ui' of https://github.com//apache/…
andrewbastian Jun 18, 2021
34d56a1
Added one more line space back in
andrewbastian Jun 18, 2021
c103c02
Removed Typo
andrewbastian Jun 18, 2021
23b5a1d
Removed another typo
andrewbastian Jun 18, 2021
2cdf91a
Flixed linter error
andrewbastian Jun 18, 2021
4a39740
Created test for tooltip.
andrewbastian Jun 18, 2021
b0de82a
Added expectation for visible tooltipIcon
andrewbastian Jun 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,26 @@ import React, { useState } from 'react';
import LabeledErrorBoundInput, {
LabeledErrorBoundInputProps,
} from './LabeledErrorBoundInput';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like some spacing got removed here on line 23 and also on lines 28, 37, 45, 64, and 70, can you put them back for readability?

export default {
title: 'LabeledErrorBoundInput',
component: LabeledErrorBoundInput,
};

export const InteractiveLabeledErrorBoundInput = ({
name,
value,
placeholder,
type,
id,
tooltipText,
}: LabeledErrorBoundInputProps) => {
const [currentValue, setCurrentValue] = useState(value);

const validateFunctionality: (value: any) => string = value => {
setCurrentValue(value.target.value);
if (value.target.value.includes('success')) {
return 'success';
}
return 'error';
};

return (
<LabeledErrorBoundInput
id={id}
Expand All @@ -58,16 +55,17 @@ export const InteractiveLabeledErrorBoundInput = ({
placeholder={placeholder}
type={type}
required
hasTooltip
tooltipText={tooltipText}
/>
);
};

InteractiveLabeledErrorBoundInput.args = {
name: 'Username',
placeholder: 'Example placeholder text...',
id: 1,
tooltipText: 'This is a tooltip',
};

InteractiveLabeledErrorBoundInput.argTypes = {
type: {
defaultValue: 'textbox',
Expand Down
29 changes: 22 additions & 7 deletions superset-frontend/src/components/Form/LabeledErrorBoundInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import React from 'react';
import { Input } from 'antd';
import { styled, css, SupersetTheme } from '@superset-ui/core';
import InfoTooltip from 'src/components/InfoTooltip';
import FormItem from './FormItem';
import FormLabel from './FormLabel';

andrewbastian marked this conversation as resolved.
Show resolved Hide resolved
export interface LabeledErrorBoundInputProps {
label?: string;
validationMethods:
Expand All @@ -30,23 +30,22 @@ export interface LabeledErrorBoundInputProps {
errorMessage: string | null;
helpText?: string;
required?: boolean;
hasTooltip?: boolean;
tooltipText?: string | null;
id?: string;
classname?: string;
[x: string]: any;
}

const StyledInput = styled(Input)`
margin: ${({ theme }) => `${theme.gridUnit}px 0 ${theme.gridUnit * 2}px`};
`;

const alertIconStyles = (theme: SupersetTheme, hasError: boolean) => css`
.ant-form-item-children-icon {
display: none;
}
${hasError &&
`.ant-form-item-control-input-content {
position: relative;

&:after {
content: ' ';
display: inline-block;
Expand All @@ -72,21 +71,38 @@ const StyledFormGroup = styled('div')`
margin-bottom: 0;
}
`;

const infoTooltip = (theme: SupersetTheme) => css`
svg {
vertical-align: bottom;
margin-bottom: ${theme.gridUnit * 0.25}px;
}
`;
const LabeledErrorBoundInput = ({
label,
validationMethods,
errorMessage,
helpText,
required = false,
hasTooltip = false,
tooltipText,
id,
className,
...props
}: LabeledErrorBoundInputProps) => (
<StyledFormGroup className={className}>
<FormLabel htmlFor={id} required={required}>
<FormLabel
htmlFor={id}
required={required}
css={(theme: SupersetTheme) => infoTooltip(theme)}
>
{label}
</FormLabel>
{hasTooltip && (
<span>
{' '}
<InfoTooltip tooltip={`${tooltipText}`} />
</span>
)}
<FormItem
css={(theme: SupersetTheme) => alertIconStyles(theme, !!errorMessage)}
validateTrigger={Object.keys(validationMethods)}
Expand All @@ -98,5 +114,4 @@ const LabeledErrorBoundInput = ({
</FormItem>
</StyledFormGroup>
);

export default LabeledErrorBoundInput;
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export const FormFieldOrder = [

interface FieldPropTypes {
required: boolean;
hasTooltip: boolean;
tooltipText: (valuse: any) => string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these required props?

onParametersChange: (value: any) => string;
onParametersUploadFileChange: (value: any) => string;
changeMethods: { onParametersChange: (value: any) => string } & {
Expand Down Expand Up @@ -106,8 +108,23 @@ const CredentialsInfo = ({ changeMethods, isEditMode, db }: FieldPropTypes) => {
</span>
</div>
) : (
<div className="input-container">
<span className="label-select">Upload Credentials</span>
<div
className="input-container"
css={(theme: SupersetTheme) => infoTooltip(theme)}
>
{/*This is missing a reqired marker. Need clarification what element to add reqired to.*/}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries here, I can fix it on my UI polish. Go ahead and remove this comment and I'll take care of the required bit 😁

<span
css={{ display: 'flex', alignItems: 'center' }}
className="label-select"
>
Upload Credentials{' '}
<InfoTooltip
tooltip={t(
'Use the JSON file you automatically downloaded when creating your service account in Google BigQuery.',
)}
/>
</span>

{!fileToUpload && (
<Button
className="input-upload-btn"
Expand Down Expand Up @@ -167,13 +184,19 @@ const hostField = ({
changeMethods,
getValidation,
validationErrors,
hasTooltip,
tooltipText,
db,
}: FieldPropTypes) => (
<ValidatedInput
id="host"
name="host"
value={db?.parameters?.host}
required={required}
hasTooltip={true}
tooltipText={t(
'This can be either an IP address (e.g. 127.0.0.1) or a domain name (e.g. mydatabase.com).',
)}
validationMethods={{ onBlur: getValidation }}
errorMessage={validationErrors?.host}
placeholder="e.g. 127.0.0.1"
Expand Down Expand Up @@ -327,7 +350,7 @@ const forceSSLField = ({
/>
<span css={toggleStyle}>SSL</span>
<InfoTooltip
tooltip={t('SSL will be enabled in the database connection')}
tooltip={t('SSL Mode "require" will be used.')}
placement="bottomRight"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* 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
* placement 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
Expand Down Expand Up @@ -34,6 +34,7 @@ import { Alert, Select } from 'src/common/components';
import Modal from 'src/components/Modal';
import Button from 'src/components/Button';
import IconButton from 'src/components/IconButton';
import InfoTooltip from 'src/components/InfoTooltip';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import {
testDatabaseConnection,
Expand Down Expand Up @@ -65,6 +66,7 @@ import {
formStyles,
StyledBasicTab,
SelectDatabaseStyles,
infoTooltip,
StyledFooterButton,
StyledStickyHeader,
} from './styles';
Expand Down Expand Up @@ -670,22 +672,30 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
isEditMode={isEditMode}
/>
{isDynamic(db?.backend || db?.engine) && (
<Button
buttonStyle="link"
onClick={() =>
setDB({
type: ActionType.configMethodChange,
payload: {
database_name: db?.database_name,
configuration_method: CONFIGURATION_METHOD.DYNAMIC_FORM,
engine: db?.engine,
},
})
}
css={theme => alchemyButtonLinkStyles(theme)}
>
Connect this database using the dynamic form instead
</Button>
<div css={(theme: SupersetTheme) => infoTooltip(theme)}>
<Button
buttonStyle="link"
onClick={() =>
setDB({
type: ActionType.configMethodChange,
payload: {
database_name: db?.database_name,
configuration_method:
CONFIGURATION_METHOD.DYNAMIC_FORM,
engine: db?.engine,
},
})
}
css={theme => alchemyButtonLinkStyles(theme)}
>
Connect this database using the dynamic form instead
<InfoTooltip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does putting this in the button component make the tooltip clickable? Was that intentional.

tooltip={t(
'Click this link to switch to an alternate form that exposes only the required fields needed to connect this database.',
)}
/>
</Button>
</div>
)}
</>
) : (
Expand Down Expand Up @@ -896,24 +906,30 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
getValidation={() => getValidation(db)}
validationErrors={validationErrors}
/>

<Button
buttonStyle="link"
onClick={() =>
setDB({
type: ActionType.configMethodChange,
payload: {
engine: db.engine,
configuration_method:
CONFIGURATION_METHOD.SQLALCHEMY_URI,
database_name: db.database_name,
},
})
}
css={buttonLinkStyles}
>
Connect this database with a SQLAlchemy URI string instead
</Button>
<div css={(theme: SupersetTheme) => infoTooltip(theme)}>
<Button
buttonStyle="link"
onClick={() =>
setDB({
type: ActionType.configMethodChange,
payload: {
engine: db.engine,
configuration_method:
CONFIGURATION_METHOD.SQLALCHEMY_URI,
database_name: db.database_name,
},
})
}
css={buttonLinkStyles}
>
Connect this database with a SQLAlchemy URI string instead
<InfoTooltip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, you're surrounding the button + tooltip in a div, which makes me think you don't want the tooltip to be able to link to sql alchemy. But the info tooltip is still inside the button component.

tooltip={t(
'Click this link to switch to an alternate form that allows you to input the SQLAlchemy URL for this database manually.',
)}
/>
</Button>
</div>
{/* Step 2 */}
</>
))}
Expand Down