mirror of
https://github.com/getredash/redash.git
synced 2026-05-11 00:00:57 -04:00
113 lines
3.4 KiB
JavaScript
113 lines
3.4 KiB
JavaScript
import { isMatch, map, find, sortBy } from 'lodash';
|
|
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import Modal from 'antd/lib/modal';
|
|
import { wrap as wrapDialog, DialogPropType } from '@/components/DialogWrapper';
|
|
import {
|
|
ParameterMappingListInput,
|
|
parameterMappingsToEditableMappings,
|
|
editableMappingsToParameterMappings,
|
|
synchronizeWidgetTitles,
|
|
} from '@/components/ParameterMappingInput';
|
|
import { ParameterMappingType } from '@/services/widget';
|
|
|
|
export function getParamValuesSnapshot(mappings, dashboardParameters) {
|
|
return map(
|
|
sortBy(mappings, m => m.name),
|
|
(m) => {
|
|
let param;
|
|
switch (m.type) {
|
|
case ParameterMappingType.StaticValue:
|
|
return [m.name, m.value];
|
|
case ParameterMappingType.WidgetLevel:
|
|
return [m.name, m.param.value];
|
|
case ParameterMappingType.DashboardLevel:
|
|
param = find(dashboardParameters, p => p.name === m.mapTo);
|
|
return [m.name, param ? param.value : null];
|
|
// no default
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
class EditParameterMappingsDialog extends React.Component {
|
|
static propTypes = {
|
|
dashboard: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
|
widget: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
|
dialog: DialogPropType.isRequired,
|
|
};
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
saveInProgress: false,
|
|
parameterMappings: parameterMappingsToEditableMappings(
|
|
props.widget.options.parameterMappings,
|
|
props.widget.query.getParametersDefs(),
|
|
map(this.props.dashboard.getParametersDefs(), p => p.name),
|
|
),
|
|
};
|
|
}
|
|
|
|
saveWidget() {
|
|
const toastr = this.props.toastr; // eslint-disable-line react/prop-types
|
|
const widget = this.props.widget;
|
|
|
|
this.setState({ saveInProgress: true });
|
|
|
|
const prevMappings = widget.options.parameterMappings;
|
|
const newMappings = editableMappingsToParameterMappings(this.state.parameterMappings);
|
|
widget.options.parameterMappings = newMappings;
|
|
|
|
const dashboardParameters = this.props.dashboard.getParametersDefs();
|
|
const valuesChanged = !isMatch(
|
|
getParamValuesSnapshot(prevMappings, dashboardParameters),
|
|
getParamValuesSnapshot(newMappings, dashboardParameters),
|
|
);
|
|
|
|
const widgetsToSave = [
|
|
widget,
|
|
...synchronizeWidgetTitles(widget.options.parameterMappings, this.props.dashboard.widgets),
|
|
];
|
|
|
|
Promise.all(map(widgetsToSave, w => w.save()))
|
|
.then(() => {
|
|
this.props.dialog.close(valuesChanged);
|
|
})
|
|
.catch(() => {
|
|
toastr.error('Widget cannot be updated');
|
|
})
|
|
.finally(() => {
|
|
this.setState({ saveInProgress: false });
|
|
});
|
|
}
|
|
|
|
updateParamMappings(parameterMappings) {
|
|
this.setState({ parameterMappings });
|
|
}
|
|
|
|
render() {
|
|
const { dialog } = this.props;
|
|
return (
|
|
<Modal
|
|
{...dialog.props}
|
|
title="Parameters"
|
|
onOk={() => this.saveWidget()}
|
|
okButtonProps={{ loading: this.state.saveInProgress }}
|
|
width={700}
|
|
>
|
|
{(this.state.parameterMappings.length > 0) && (
|
|
<ParameterMappingListInput
|
|
mappings={this.state.parameterMappings}
|
|
existingParams={this.props.dashboard.getParametersDefs()}
|
|
onChange={mappings => this.updateParamMappings(mappings)}
|
|
/>
|
|
)}
|
|
</Modal>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default wrapDialog(EditParameterMappingsDialog);
|