refactor: TemplateParamsEditor.jsx converted from class to functional component (#12873)

* TemplateParamsEditor.jsx converted from class to functional component

* Fixed import in SqlEditor.jsx

* Corrected renderDoc

* Corrected renderModalBody

* Corrected functional name and import

* Corrected props

* Corrected modalBody and incorporated renderDoc

* Removed t strings

* Removed unnecessary single quotes

* Editor text updating correctly

* Split useState into three different hooks

* Removed onChangefunc, adjusted component to use onChange and code from props through useEffect

* Added parsedJSON reset to catch in useEffect

* Put a throttle on the onChange

* Switched from throttle to debounce
This commit is contained in:
Lyndsi Kay Williams 2021-02-07 23:44:39 -06:00 committed by GitHub
parent b56aec763d
commit 022d18d359
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 83 deletions

View File

@ -16,11 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Badge from 'src/common/components/Badge';
import { t, styled } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { debounce } from 'lodash';
import ModalTrigger from 'src/components/ModalTrigger';
import { ConfigEditor } from 'src/components/AsyncAceEditor';
@ -42,49 +43,29 @@ const StyledConfigEditor = styled(ConfigEditor)`
}
`;
export default class TemplateParamsEditor extends React.Component {
constructor(props) {
super(props);
const codeText = props.code || '{}';
this.state = {
codeText,
parsedJSON: null,
isValid: true,
};
this.onChange = this.onChange.bind(this);
}
function TemplateParamsEditor({ code, language, onChange }) {
const [parsedJSON, setParsedJSON] = useState();
const [isValid, setIsValid] = useState(true);
componentDidMount() {
this.onChange(this.state.codeText);
}
onChange(value) {
const codeText = value;
let isValid;
let parsedJSON = {};
useEffect(() => {
try {
parsedJSON = JSON.parse(value);
isValid = true;
} catch (e) {
isValid = false;
setParsedJSON(JSON.parse(code));
setIsValid(true);
} catch {
setParsedJSON({});
setIsValid(false);
}
this.setState({ parsedJSON, isValid, codeText });
const newValue = isValid ? codeText : '{}';
if (newValue !== this.props.code) {
this.props.onChange(newValue);
}
}
}, [code]);
renderDoc() {
return (
const modalBody = (
<div>
<p>
{t('Assign a set of parameters as')}
Assign a set of parameters as
<code>JSON</code>
{t('below (example:')}
below (example:
<code>{'{"my_table": "foo"}'}</code>
{t('), and they become available in your SQL (example:')}
<code>SELECT * FROM {'{{ my_table }}'} </code>
{t(') by using')}&nbsp;
), and they become available in your SQL (example:
<code>SELECT * FROM {'{{ my_table }}'} </code>) by using&nbsp;
<a
href="https://superset.apache.org/sqllab.html#templating-with-jinja"
target="_blank"
@ -94,54 +75,45 @@ export default class TemplateParamsEditor extends React.Component {
</a>{' '}
syntax.
</p>
);
}
renderModalBody() {
return (
<div>
{this.renderDoc()}
<StyledConfigEditor
keywords={[]}
mode={this.props.language}
minLines={25}
maxLines={50}
onChange={this.onChange}
width="100%"
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={this.state.codeText}
/>
</div>
);
}
render() {
const paramCount = this.state.parsedJSON
? Object.keys(this.state.parsedJSON).length
: 0;
return (
<ModalTrigger
modalTitle={t('Template parameters')}
triggerNode={
<div tooltip={t('Edit template parameters')} buttonSize="small">
{`${t('Parameters')} `}
<Badge count={paramCount} />
{!this.state.isValid && (
<InfoTooltipWithTrigger
icon="exclamation-triangle"
bsStyle="danger"
tooltip={t('Invalid JSON')}
label="invalid-json"
/>
)}
</div>
}
modalBody={this.renderModalBody(true)}
<StyledConfigEditor
keywords={[]}
mode={language}
minLines={25}
maxLines={50}
onChange={debounce(onChange, 200)}
width="100%"
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={code}
/>
);
}
</div>
);
const paramCount = parsedJSON ? Object.keys(parsedJSON).length : 0;
return (
<ModalTrigger
modalTitle={t('Template parameters')}
triggerNode={
<div tooltip={t('Edit template parameters')} buttonSize="small">
{`${t('Parameters')} `}
<Badge count={paramCount} />
{!isValid && (
<InfoTooltipWithTrigger
icon="exclamation-triangle"
bsStyle="danger"
tooltip={t('Invalid JSON')}
label="invalid-json"
/>
)}
</div>
}
modalBody={modalBody}
/>
);
}
TemplateParamsEditor.propTypes = propTypes;
TemplateParamsEditor.defaultProps = defaultProps;
export default TemplateParamsEditor;