mirror of
https://github.com/apache/superset.git
synced 2026-04-23 18:14:56 +00:00
Introduce Javascript controls (#4076)
* Introduce Javascript controls This allows power-users to perform intricate transformations on data and objects using javascript code. The operations allowed are "sanboxed" or limited using node's vm `runInNewContext` https://nodejs.org/api/vm.html#vm_vm_runinnewcontext_code_sandbox_options For now I'm only enabling in the line chart visualization, but the plan would be to go towards offering more power to people who can write some JS moving forward. * Not applied
This commit is contained in:
committed by
GitHub
parent
b4909f2d03
commit
69195f8d2d
@@ -7,6 +7,7 @@ import 'brace/mode/sql';
|
||||
import 'brace/mode/json';
|
||||
import 'brace/mode/html';
|
||||
import 'brace/mode/markdown';
|
||||
import 'brace/mode/javascript';
|
||||
|
||||
import 'brace/theme/textmate';
|
||||
|
||||
@@ -16,24 +17,21 @@ import { t } from '../../../locales';
|
||||
|
||||
const propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
value: PropTypes.string,
|
||||
height: PropTypes.number,
|
||||
language: PropTypes.oneOf([null, 'json', 'html', 'sql', 'markdown']),
|
||||
minLines: PropTypes.number,
|
||||
maxLines: PropTypes.number,
|
||||
offerEditInModal: PropTypes.bool,
|
||||
language: PropTypes.oneOf([null, 'json', 'html', 'sql', 'markdown', 'javascript']),
|
||||
aboveEditorSection: PropTypes.node,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
label: null,
|
||||
description: null,
|
||||
onChange: () => {},
|
||||
value: '',
|
||||
height: 250,
|
||||
minLines: 10,
|
||||
minLines: 3,
|
||||
maxLines: 10,
|
||||
offerEditInModal: true,
|
||||
};
|
||||
@@ -73,6 +71,14 @@ export default class TextAreaControl extends React.Component {
|
||||
/>
|
||||
</FormGroup>);
|
||||
}
|
||||
renderModalBody() {
|
||||
return (
|
||||
<div>
|
||||
<div>{this.props.aboveEditorSection}</div>
|
||||
{this.renderEditor(true)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const controlHeader = <ControlHeader {...this.props} />;
|
||||
return (
|
||||
@@ -88,7 +94,7 @@ export default class TextAreaControl extends React.Component {
|
||||
{t('Edit')} <strong>{this.props.language}</strong> {t('in modal')}
|
||||
</Button>
|
||||
}
|
||||
modalBody={this.renderEditor(true)}
|
||||
modalBody={this.renderModalBody(true)}
|
||||
/>}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -46,6 +46,15 @@ const sortAxisChoices = [
|
||||
['value_desc', 'sum(value) descending'],
|
||||
];
|
||||
|
||||
const sandboxUrl = 'https://github.com/apache/incubator-superset/blob/master/superset/assets/javascripts/modules/sandbox.js';
|
||||
const sandboxedEvalInfo = (
|
||||
<span>
|
||||
{t('While this runs in a ')}
|
||||
<a href="https://nodejs.org/api/vm.html#vm_script_runinnewcontext_sandbox_options">sandboxed vm</a>
|
||||
, {t('a set of')}<a href={sandboxUrl}> useful objects are in context </a>
|
||||
{t('to be used where necessary.')}
|
||||
</span>);
|
||||
|
||||
const groupByControl = {
|
||||
type: 'SelectControl',
|
||||
multi: true,
|
||||
@@ -1759,5 +1768,18 @@ export const controls = {
|
||||
default: false,
|
||||
},
|
||||
|
||||
js_data: {
|
||||
type: 'TextAreaControl',
|
||||
label: t('Javascript data mutator'),
|
||||
description: t('Define a function that receives intercepts the data objects and can mutate it'),
|
||||
language: 'javascript',
|
||||
default: '',
|
||||
height: 100,
|
||||
aboveEditorSection: (
|
||||
<p>
|
||||
Define a function that intercepts the <code>data</code> object passed to the visualization
|
||||
and returns a similarly shaped object. {sandboxedEvalInfo}
|
||||
</p>),
|
||||
},
|
||||
};
|
||||
export default controls;
|
||||
|
||||
@@ -607,6 +607,7 @@ export const visTypes = {
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Code'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['markup_type'],
|
||||
['code'],
|
||||
|
||||
Reference in New Issue
Block a user