Repository: apache/superset
File: superset-frontend/src/SqlLab/components/TemplateParamsEditor/index.tsx (TypeScript)

Code before:

  useEffect(() => {
    try {
      setParsedJSON(JSON.parse(code));
      setIsValid(true);
    } catch {
      setParsedJSON({} as any);
      setIsValid(false);
    }
  }, [code]);

  const modalBody = (
    <div>
      <p>
        {t('Assign a set of parameters as')}
        <code>JSON</code>
        {t('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;
        <a
          href="https://superset.apache.org/sqllab.html#templating-with-jinja"
          target="_blank"
          rel="noopener noreferrer"
        >
          {t('Jinja templating')}
        </a>{' '}
        {t('syntax.')}
      </p>
      <StyledConfigEditor
        mode={language}
        minLines={25}
        maxLines={50}
        onChange={debounce(onChange, Constants.FAST_DEBOUNCE)}
        width="100%"
        editorProps={{ $blockScrolling: true }}
        enableLiveAutocompletion
        value={code}
      />
    </div>
  );

  const paramCount = parsedJSON ? Object.keys(parsedJSON).length : 0;

  return (
    <ModalTrigger
      modalTitle={t('Template parameters')}
      triggerNode={
        <Tooltip
          id="parameters-tooltip"
          placement="top"

Review comment (suggestion):
We should use a library like `react-i18next` so we can write this as:

```typescript
<Trans i18nKey="assignParams">
  Assign a set of parameters as <Code>JSON</Code> below (example:
  <Code>{"{\"my_table\": \"foo\"}"}</Code>), and they become available
  in your SQL (example: <Code>SELECT * FROM {{ my_table }}</Code>)
  by using
</Trans>
```

Because as-is the translation strings are too dependent on English, and translators don't have the full context.

Code after:
  language,
  onChange = () => {},
}: TemplateParamsEditorProps) => {
  const [parsedJSON, setParsedJSON] = useState({});
  const [isValid, setIsValid] = useState(true);

  const { templateParams } = useQueryEditor(queryEditorId, ['templateParams']);
  const code = templateParams ?? '{}';

  useEffect(() => {
    try {
      setParsedJSON(JSON.parse(code));
      setIsValid(true);
    } catch {
      setParsedJSON({} as any);
      setIsValid(false);
    }
  }, [code]);

  const modalBody = (
    <div>
      <StyledParagraph>
        {t('Assign a set of parameters as')} <Code>JSON</Code>{' '}
        {t('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;
        <a
          href="https://superset.apache.org/sqllab.html#templating-with-jinja"
          target="_blank"
          rel="noopener noreferrer"
        >
          {t('Jinja templating')}
        </a>{' '}
        {t('syntax.')}
      </StyledParagraph>
      <StyledConfigEditor
        mode={language}
        minLines={25}
        maxLines={50}
        onChange={debounce(onChange, Constants.FAST_DEBOUNCE)}
        width="100%"
        editorProps={{ $blockScrolling: true }}
        enableLiveAutocompletion
        value={code}
      />
    </div>
  );

  const paramCount = parsedJSON ? Object.keys(parsedJSON).length : 0;

  return (