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:
parent
b56aec763d
commit
022d18d359
|
|
@ -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')}
|
||||
), and they become available in your SQL (example:
|
||||
<code>SELECT * FROM {'{{ my_table }}'} </code>) by using
|
||||
<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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue