Skip to content

Commit

Permalink
feat: Added Steps and centralized Headers (#15041)
Browse files Browse the repository at this point in the history
  • Loading branch information
AAfghahi authored Jun 10, 2021
1 parent a95e416 commit cbbb257
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
formScrollableStyles,
validatedFormStyles,
CredentialInfoForm,
StyledFormHeader,
toggleStyle,
infoTooltip,
} from './styles';
Expand All @@ -50,8 +49,12 @@ export const FormFieldOrder = [
'credentials_info',
];

const selectedFile = document.getElementById('selectedFile');

interface FieldPropTypes {
required: boolean;
onParametersChange: (value: any) => string;
onParametersUploadFileChange: (value: any) => string;
changeMethods: { onParametersChange: (value: any) => string } & {
onChange: (value: any) => string;
} & { onParametersUploadFileChange: (value: any) => string };
Expand All @@ -62,23 +65,20 @@ interface FieldPropTypes {
sslForced?: boolean;
}

const credentialsInfo = ({
required,
changeMethods,
getValidation,
validationErrors,
}: FieldPropTypes) => {
const [uploadOption, setUploadOption] = useState<string>('upload');
const [fileToUpload, setFileToUpload] = useState<string>(null);
const CredentialsInfo = ({ changeMethods }: FieldPropTypes) => {
const [uploadOption, setUploadOption] = useState<number>(0);
const [fileToUpload, setFileToUpload] = useState<string | null | undefined>(
null,
);
return (
<CredentialInfoForm>
<label className="label-select">
<span className="label-select">
How do you want to enter service account credentials?
</label>
</span>
<Select
defaultValue={CredentialInfoOptions.jsonUpload}
style={{ width: '100%' }}
onChange={setUploadOption}
onChange={option => setUploadOption(option)}
>
<Select.Option value={CredentialInfoOptions.jsonUpload}>
Upload JSON file
Expand All @@ -87,7 +87,7 @@ const credentialsInfo = ({
Copy and Paste JSON credentials
</Select.Option>
</Select>
{uploadOption === 'paste' ? (
{uploadOption === CredentialInfoOptions.copyPaste ? (
<div className="input-container" onChange={changeMethods.onChange}>
<span className="label-select">Service Account</span>
<textarea className="input-form" name="encrypted_extra" />
Expand All @@ -101,7 +101,7 @@ const credentialsInfo = ({
{!fileToUpload && (
<Button
className="input-upload-btn"
onClick={() => document.getElementById('selectedFile').click()}
onClick={() => document?.getElementById('selectedFile')?.click()}
>
Choose File
</Button>
Expand All @@ -128,17 +128,20 @@ const credentialsInfo = ({
className="input-upload"
type="file"
onChange={async event => {
const file = event?.target?.files[0];
setFileToUpload(file.name);
let file;
if (event.target.files) {
file = event.target.files[0];
}
setFileToUpload(file?.name);
changeMethods.onParametersChange({
target: {
type: null,
name: 'encrypted_extra',
value: await file.text(),
value: await file?.text(),
checked: false,
},
});
document.getElementById('selectedFile').value = null;
(selectedFile as HTMLInputElement).value = null as any;
}}
/>
</div>
Expand Down Expand Up @@ -279,7 +282,7 @@ const queryField = ({
id="query"
name="query"
required={required}
value={db?.query}
value={db?.parameters?.query}
validationMethods={{ onBlur: getValidation }}
errorMessage={validationErrors?.query}
placeholder="e.g. additional parameters"
Expand Down Expand Up @@ -327,11 +330,11 @@ const FORM_FIELD_MAP = {
database_name: displayField,
query: queryField,
encryption: forceSSLField,
credentials_info: credentialsInfo,
credentials_info: CredentialsInfo,
};

const DatabaseConnectionForm = ({
dbModel: { name, parameters },
dbModel: { parameters },
onParametersChange,
onChange,
onParametersUploadFileChange,
Expand All @@ -351,21 +354,13 @@ const DatabaseConnectionForm = ({
onChange: (
event: FormEvent<InputProps> | { target: HTMLInputElement },
) => void;
onParametersUploadFileChange: (
onParametersUploadFileChange?: (
event: FormEvent<InputProps> | { target: HTMLInputElement },
) => void;
validationErrors: JsonObject | null;
getValidation: () => void;
}) => (
<>
{!isEditMode && (
<StyledFormHeader>
<h4>Enter the required {name} credentials</h4>
<p className="helper">
Need help? Learn more about connecting to {name}.
</p>
</StyledFormHeader>
)}
<div
// @ts-ignore
css={(theme: SupersetTheme) => [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* 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 {
EditHeaderTitle,
EditHeaderSubtitle,
CreateHeaderTitle,
CreateHeaderSubtitle,
StyledFormHeader,
} from './styles';
import { DatabaseForm, DatabaseObject } from '../types';

export const DOCUMENTATION_LINK =
'https://superset.apache.org/docs/databases/installing-database-drivers';

const irregularDocumentationLinks = {
postgresql: 'https://superset.apache.org/docs/databases/postgres',
mssql: 'https://superset.apache.org/docs/databases/sql-server',
};

const documentationLink = (engine: string | undefined) => {
if (!engine) return null;
if (!irregularDocumentationLinks[engine]) {
return `https://superset.apache.org/docs/databases/${engine}`;
}
return irregularDocumentationLinks[engine];
};
const ModalHeader = ({
isLoading,
isEditMode,
useSqlAlchemyForm,
hasConnectedDb,
db,
dbName,
dbModel,
}: {
isLoading: boolean;
isEditMode: boolean;
useSqlAlchemyForm: boolean;
hasConnectedDb: boolean;
db: Partial<DatabaseObject> | null;
dbName: string;
dbModel: DatabaseForm;
}) => {
const isEditHeader = (
<>
<EditHeaderTitle>{db?.backend}</EditHeaderTitle>
<EditHeaderSubtitle>{dbName}</EditHeaderSubtitle>
</>
);
const useSqlAlchemyFormHeader = (
<>
<p className="helper"> Step 2 of 2 </p>
<CreateHeaderTitle>Enter Primary Credentials</CreateHeaderTitle>
<CreateHeaderSubtitle>
Need help? Learn how to connect your database{' '}
<a href={DOCUMENTATION_LINK} target="_blank" rel="noopener noreferrer">
here
</a>
.
</CreateHeaderSubtitle>
</>
);
const hasConnectedDbHeader = (
<StyledFormHeader>
<p className="helper"> Step 3 of 3 </p>
<h4>
Your database was successfully connected! Here are some optional
settings for your database
</h4>
<p className="helper">
Need help? Learn more about{' '}
<a
href={documentationLink(db?.engine)}
target="_blank"
rel="noopener noreferrer"
>
connecting to {dbModel.name}
</a>
</p>
</StyledFormHeader>
);
const hasDbHeader = (
<StyledFormHeader>
<p className="helper"> Step 2 of 3 </p>
<h4>Enter the required {dbModel.name} credentials</h4>
<p className="helper">
Need help? Learn more about connecting to {dbModel.name}.
</p>
</StyledFormHeader>
);
const noDbHeader = (
<StyledFormHeader>
<div className="select-db">
<p className="helper"> Step 1 of 3 </p>
<h4>Select a database to connect</h4>
</div>
</StyledFormHeader>
);

if (isLoading) return <></>;
if (isEditMode) {
return isEditHeader;
}
if (useSqlAlchemyForm) {
return useSqlAlchemyFormHeader;
}
if (hasConnectedDb) {
return hasConnectedDbHeader;
}
if (db) {
return hasDbHeader;
}
return noDbHeader;
};

export default ModalHeader;
Loading

0 comments on commit cbbb257

Please sign in to comment.