From 022d18d3595be92b712900204c719e444f20bdbd Mon Sep 17 00:00:00 2001 From: Lyndsi Kay Williams <55605634+lyndsiWilliams@users.noreply.github.com> Date: Sun, 7 Feb 2021 23:44:39 -0600 Subject: [PATCH] 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 --- .../components/TemplateParamsEditor.jsx | 138 +++++++----------- 1 file changed, 55 insertions(+), 83 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx index 863e994c1..20e80a171 100644 --- a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx +++ b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx @@ -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 = ( +

- {t('Assign a set of parameters as')} + Assign a set of parameters as JSON - {t('below (example:')} + below (example: {'{"my_table": "foo"}'} - {t('), and they become available in your SQL (example:')} - SELECT * FROM {'{{ my_table }}'} - {t(') by using')}  + ), and they become available in your SQL (example: + SELECT * FROM {'{{ my_table }}'} ) by using  {' '} syntax.

- ); - } - - renderModalBody() { - return ( -
- {this.renderDoc()} - -
- ); - } - - render() { - const paramCount = this.state.parsedJSON - ? Object.keys(this.state.parsedJSON).length - : 0; - return ( - - {`${t('Parameters')} `} - - {!this.state.isValid && ( - - )} -
- } - modalBody={this.renderModalBody(true)} + - ); - } + + ); + + const paramCount = parsedJSON ? Object.keys(parsedJSON).length : 0; + + return ( + + {`${t('Parameters')} `} + + {!isValid && ( + + )} + + } + modalBody={modalBody} + /> + ); } TemplateParamsEditor.propTypes = propTypes; TemplateParamsEditor.defaultProps = defaultProps; + +export default TemplateParamsEditor;