blob: cc91daee4cb195f278fc1db0087ad71764268100 [file] [log] [blame]
/* global notify */
import React from 'react';
import PropTypes from 'prop-types';
import { Button, FormControl, FormGroup, Radio } from 'react-bootstrap';
import { getAjaxErrorMsg } from '../../modules/utils';
import ModalTrigger from '../../components/ModalTrigger';
import { t } from '../../locales';
import Checkbox from '../../components/Checkbox';
const $ = window.$ = require('jquery');
const propTypes = {
css: PropTypes.string,
dashboard: PropTypes.object.isRequired,
triggerNode: PropTypes.node.isRequired,
readFilters: PropTypes.func,
serialize: PropTypes.func,
onSave: PropTypes.func,
};
class SaveModal extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
dashboard: props.dashboard,
css: props.css,
saveType: 'overwrite',
newDashName: props.dashboard.dashboard_title + ' [copy]',
duplicateSlices: false,
};
this.modal = null;
this.handleSaveTypeChange = this.handleSaveTypeChange.bind(this);
this.handleNameChange = this.handleNameChange.bind(this);
this.saveDashboard = this.saveDashboard.bind(this);
}
toggleDuplicateSlices() {
this.setState({ duplicateSlices: !this.state.duplicateSlices });
}
handleSaveTypeChange(event) {
this.setState({
saveType: event.target.value,
});
}
handleNameChange(event) {
this.setState({
newDashName: event.target.value,
saveType: 'newDashboard',
});
}
saveDashboardRequest(data, url, saveType) {
const saveModal = this.modal;
const onSaveDashboard = this.props.onSave;
Object.assign(data, { css: this.props.css });
$.ajax({
type: 'POST',
url,
data: {
data: JSON.stringify(data),
},
success(resp) {
saveModal.close();
onSaveDashboard();
if (saveType === 'newDashboard') {
window.location = `/superset/dashboard/${resp.id}/`;
} else {
notify.success(t('This dashboard was saved successfully.'));
}
},
error(error) {
saveModal.close();
const errorMsg = getAjaxErrorMsg(error);
notify.error(t('Sorry, there was an error saving this dashboard: ') + '</ br>' + errorMsg);
},
});
}
saveDashboard(saveType, newDashboardTitle) {
const dashboard = this.props.dashboard;
const positions = this.props.serialize();
const data = {
positions,
css: this.state.css,
expanded_slices: dashboard.metadata.expanded_slices || {},
dashboard_title: dashboard.dashboard_title,
default_filters: this.props.readFilters(),
duplicate_slices: this.state.duplicateSlices,
};
let url = null;
if (saveType === 'overwrite') {
url = `/superset/save_dash/${dashboard.id}/`;
this.saveDashboardRequest(data, url, saveType);
} else if (saveType === 'newDashboard') {
if (!newDashboardTitle) {
this.modal.close();
showModal({
title: t('Error'),
body: t('You must pick a name for the new dashboard'),
});
} else {
data.dashboard_title = newDashboardTitle;
url = `/superset/copy_dash/${dashboard.id}/`;
this.saveDashboardRequest(data, url, saveType);
}
}
}
render() {
return (
<ModalTrigger
ref={(modal) => { this.modal = modal; }}
triggerNode={this.props.triggerNode}
modalTitle={t('Save Dashboard')}
modalBody={
<FormGroup>
<Radio
value="overwrite"
onChange={this.handleSaveTypeChange}
checked={this.state.saveType === 'overwrite'}
>
{t('Overwrite Dashboard [%s]', this.props.dashboard.dashboard_title)}
</Radio>
<hr />
<Radio
value="newDashboard"
onChange={this.handleSaveTypeChange}
checked={this.state.saveType === 'newDashboard'}
>
{t('Save as:')}
</Radio>
<FormControl
type="text"
placeholder={t('[dashboard name]')}
value={this.state.newDashName}
onFocus={this.handleNameChange}
onChange={this.handleNameChange}
/>
<div className="m-l-25 m-t-5">
<Checkbox
checked={this.state.duplicateSlices}
onChange={this.toggleDuplicateSlices.bind(this)}
/>
<span className="m-l-5">also copy (duplicate) slices</span>
</div>
</FormGroup>
}
modalFooter={
<div>
<Button
bsStyle="primary"
onClick={() => { this.saveDashboard(this.state.saveType, this.state.newDashName); }}
>
{t('Save')}
</Button>
</div>
}
/>
);
}
}
SaveModal.propTypes = propTypes;
export default SaveModal;