feat: Add parseJson Handlebars Helper to Support Processing Nested JSON Data (#31998)

Co-authored-by: AdrianKoszalka <adrian.koszalka@techminers.com>
This commit is contained in:
Adrian Koszałka 2025-02-06 21:48:28 +01:00 committed by GitHub
parent 649a0dec6c
commit 205cff3a94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 74 additions and 2 deletions

View File

@ -73,3 +73,26 @@ more details.
└── types
└── external.d.ts
```
### Available Handlebars Helpers in Superset
Below, you will find a list of all currently registered helpers in the Handlebars plugin for Superset. These helpers are registered and managed in the file [`HandlebarsViewer.tsx`](./path/to/HandlebarsViewer.tsx).
#### List of Registered Helpers:
1. **`dateFormat`**: Formats a date using a specified format.
- **Usage**: `{{dateFormat my_date format="MMMM YYYY"}}`
- **Default format**: `YYYY-MM-DD`.
2. **`stringify`**: Converts an object into a JSON string or returns a string representation of non-object values.
- **Usage**: `{{stringify myObj}}`.
3. **`formatNumber`**: Formats a number using locale-specific formatting.
- **Usage**: `{{formatNumber number locale="en-US"}}`.
- **Default locale**: `en-US`.
4. **`parseJson`**: Parses a JSON string into a JavaScript object.
- **Usage**: `{{parseJson jsonString}}`.

View File

@ -99,5 +99,18 @@ Handlebars.registerHelper(
},
);
// usage: {{parseJson jsonString}}
Handlebars.registerHelper('parseJson', (jsonString: string) => {
try {
return JSON.parse(jsonString);
} catch (error) {
if (error instanceof Error) {
error.message = `Invalid JSON string: ${error.message}`;
throw error;
}
throw new Error(`Invalid JSON string: ${String(error)}`);
}
});
Helpers.registerHelpers(Handlebars);
HandlebarsGroupBy.register(Handlebars);

View File

@ -20,8 +20,9 @@ import {
ControlSetItem,
CustomControlConfig,
sharedControls,
InfoTooltipWithTrigger,
} from '@superset-ui/chart-controls';
import { t, validateNonEmpty } from '@superset-ui/core';
import { t, validateNonEmpty, useTheme, SafeMarkdown } from '@superset-ui/core';
import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
import { ControlHeader } from '../../components/ControlHeader/controlHeader';
import { debounceFunc } from '../../consts';
@ -33,13 +34,48 @@ interface HandlebarsCustomControlProps {
const HandlebarsTemplateControl = (
props: CustomControlConfig<HandlebarsCustomControlProps>,
) => {
const theme = useTheme();
const val = String(
props?.value ? props?.value : props?.default ? props?.default : '',
);
const helperDescriptionsHeader = t(
'Available Handlebars Helpers in Superset:',
);
const helperDescriptions = [
{ key: 'dateFormat', descKey: 'Formats a date using a specified format.' },
{ key: 'stringify', descKey: 'Converts an object to a JSON string.' },
{
key: 'formatNumber',
descKey: 'Formats a number using locale-specific formatting.',
},
{
key: 'parseJson',
descKey: 'Parses a JSON string into a JavaScript object.',
},
];
const helpersTooltipContent = `
${helperDescriptionsHeader}
${helperDescriptions
.map(({ key, descKey }) => `- **${key}**: ${t(descKey)}`)
.join('\n')}
`;
return (
<div>
<ControlHeader>{props.label}</ControlHeader>
<ControlHeader>
<div>
{props.label}
<InfoTooltipWithTrigger
iconsStyle={{ marginLeft: theme.gridUnit }}
tooltip={<SafeMarkdown source={helpersTooltipContent} />}
/>
</div>
</ControlHeader>
<CodeEditor
theme="dark"
value={val}