Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions superset-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion superset-frontend/packages/superset-core/src/api/editors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@ import type { SupersetTheme } from '../ui';
/**
* Supported editor languages.
*/
export type EditorLanguage = 'sql' | 'json' | 'yaml' | 'markdown' | 'css';
export type EditorLanguage =
| 'sql'
| 'json'
| 'yaml'
| 'markdown'
| 'css'
| 'python'
| 'text'
| 'javascript';

/**
* Describes an editor that can be contributed to the application.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,20 @@ const order_by_cols: SharedControlConfig<'SelectControl'> = {
resetOnHide: false,
};

const echart_options: SharedControlConfig<'JSEditorControl'> = {
type: 'JSEditorControl',
label: t('ECharts Options (JS object literals)'),
description: t(
'A JavaScript object that adheres to the ECharts options specification, ' +
'overriding other control options with higher precedence. ' +
'(i.e. { title: { text: "My Chart" }, tooltip: { trigger: "item" } }). ' +
'Details: https://echarts.apache.org/en/option.html. ',
),
default: '{}',
renderTrigger: true,
validators: [],
};

const sharedControls: Record<string, SharedControlConfig<any>> = {
metrics: dndAdhocMetricsControl,
metric: dndAdhocMetricControl,
Expand Down Expand Up @@ -499,6 +513,7 @@ const sharedControls: Record<string, SharedControlConfig<any>> = {
currency_format,
sort_by_metric,
order_by_cols,
echart_options,

// Add all Matrixify controls
...matrixifyControls,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export type InternalControlType =
| 'FixedOrMetricControl'
| 'ColorBreakpointsControl'
| 'HiddenControl'
| 'JSEditorControl'
| 'SelectAsyncControl'
| 'SelectControl'
| 'SliderControl'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,9 @@ export const ConfigEditor = AsyncAceEditor([
'mode/yaml',
'theme/github',
]);

export const JSEditor = AsyncAceEditor([
'mode/javascript',
'mode/json',
'theme/github',
]);
Comment on lines +506 to +510

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect default mode for JSEditor

The JSEditor is configured with 'mode/json' first, causing the default mode to be 'json', but given the name 'JSEditor', it appears intended for JavaScript editing. Consider reordering the modes to start with 'mode/javascript' for correct default behavior, similar to how other editors prioritize their primary mode.

Code suggestion
Check the AI-generated fix before applying
Suggested change
export const JSEditor = AsyncAceEditor([
'mode/json',
'mode/javascript',
'theme/github',
]);
export const JSEditor = AsyncAceEditor([
'mode/javascript',
'mode/json',
'theme/github',
]);

Code Review Run #3194c9


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export {
AsyncAceEditor,
CssEditor,
JsonEditor,
JSEditor,
SQLEditor,
FullSQLEditor,
MarkdownEditor,
Expand Down
4 changes: 3 additions & 1 deletion superset-frontend/plugins/plugin-chart-echarts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
"dependencies": {
"@types/d3-array": "^3.2.2",
"@types/react-redux": "^7.1.34",
"acorn": "^8.9.0",
"d3-array": "^3.2.4",
"lodash": "^4.17.23"
"lodash": "^4.17.23",
"zod": "^4.3.6"
},
"peerDependencies": {
"@apache-superset/core": "*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ const config: ControlPanelConfig = {
},
},
],
['echart_options'],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
Refs,
} from '../types';
import { parseAxisBound } from '../utils/controls';
import { safeParseEChartOptions } from '../utils/safeEChartOptionsParser';
import {
dedupSeries,
extractDataTotalValues,
Expand Down Expand Up @@ -99,6 +100,7 @@ import {
getYAxisFormatter,
} from '../utils/formatters';
import { getMetricDisplayName } from '../utils/metricDisplayName';
import { mergeCustomEChartOptions } from '../utils/mergeCustomEChartOptions';

const getFormatter = (
customFormatters: Record<string, ValueFormatter>,
Expand All @@ -122,7 +124,7 @@ export default function transformProps(
const {
width,
height,
formData,
formData: { echartOptions: _echartOptions, ...formData },
queriesData,
hooks,
filterState,
Expand Down Expand Up @@ -803,11 +805,25 @@ export default function transformProps(
focusedSeries = seriesName;
};

let customEchartOptions;
try {
// Parse custom EChart options safely using AST analysis
// This replaces the unsafe `new Function()` approach with a secure parser
// that only allows static data structures (no function callbacks)
customEchartOptions = safeParseEChartOptions(_echartOptions);
} catch (_) {
customEchartOptions = undefined;
}
Comment on lines +814 to +816

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tagging this as the same thing Michael mentioned on other comment


const mergedEchartOptions = customEchartOptions
? mergeCustomEChartOptions(echartOptions, customEchartOptions)
: echartOptions;

return {
formData,
width,
height,
echartOptions,
echartOptions: mergedEchartOptions,
setDataMask,
emitCrossFilters,
labelMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ const config: ControlPanelConfig = {
},
},
],
['echart_options'],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken custom ECharts options control

The added 'echart_options' control allows users to input custom ECharts options for Area charts, matching the implementation in other timeseries chart types. However, due to a bug in transformProps.ts where the destructuring accesses 'echartOptions' instead of 'echart_options', the custom options will not be applied. This affects all charts using this control, not just Area.

Code Review Run #048e53


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ const config: ControlPanelConfig = {
...richTooltipSection,
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
...createAxisControl('y'),
['echart_options'],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ const config: ControlPanelConfig = {
},
},
],
['echart_options'],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ const config: ControlPanelConfig = {
},
},
],
['echart_options'],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ import {
getXAxisFormatter,
getYAxisFormatter,
} from '../utils/formatters';
import { safeParseEChartOptions } from '../utils/safeEChartOptionsParser';
import { mergeCustomEChartOptions } from '../utils/mergeCustomEChartOptions';

export default function transformProps(
chartProps: EchartsTimeseriesChartProps,
Expand All @@ -122,7 +124,7 @@ export default function transformProps(
height,
filterState,
legendState,
formData,
formData: { echartOptions: _echartOptions, ...formData },
hooks,
queriesData,
datasource,
Expand Down Expand Up @@ -866,8 +868,23 @@ export default function transformProps(
const onFocusedSeries = (seriesName: string | null) => {
focusedSeries = seriesName;
};

let customEchartOptions;
try {
// Parse custom EChart options safely using AST analysis
// This replaces the unsafe `new Function()` approach with a secure parser
// that only allows static data structures (no function callbacks)
customEchartOptions = safeParseEChartOptions(_echartOptions);
} catch (_) {
Comment thread
michael-s-molina marked this conversation as resolved.
customEchartOptions = undefined;
}

const mergedEchartOptions = customEchartOptions
? mergeCustomEChartOptions(echartOptions, customEchartOptions)
: echartOptions;

return {
echartOptions,
echartOptions: mergedEchartOptions,
emitCrossFilters,
formData,
groupby: groupBy,
Expand Down
3 changes: 3 additions & 0 deletions superset-frontend/plugins/plugin-chart-echarts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ export { default as GanttTransformProps } from './Gantt/transformProps';

export { DEFAULT_FORM_DATA as TimeseriesDefaultFormData } from './Timeseries/constants';

export * from './utils/eChartOptionsSchema';
export * from './utils/safeEChartOptionsParser';

export * from './types';

/**
Expand Down
Loading
Loading