Files
superset2/superset/assets/javascripts/explorev2/components/SaveModal.js
Maxime Beauchemin 0cc8eff1c3 [WiP] Deprecate Explore v1 (#2064)
* Simplifying the viz interface (#2005)

* Working on dashes

* Making this a collaborative branch

* Fixing some bugs

* Fixing bugs

* More improvements

* Add datasource back in bootstrap data

* Decent state

* Linting

* Moving forward

* Some more linting

* Fix the timer

* Triggering events through state

* Lingint

* Put filters in an array instead of flt strings (#2090)

* Put filters in an array instead of flt strings

* Remove query_filter(), put opChoices into Filter

* Update version_info.json

* Fix migrations

* More renderTrigger=true

* Fixing bugs

* Working on standalone

* getting standalone to work

* Fixed forcedHeight for standalone =view

* Linting

* Get save slice working in v2 (#2106)

* Filter bugfix

* Fixing empty series limit bug

* Fixed dashboard view

* Fixing short urls

* Only allow owners to overwrite slice (#2142)

* Raise exception when date range is wrong

* Only allow owner to overwrite a slice

* Fix tests for deprecate v1 (#2140)

* Fixed tests for control panels container and filters

* Fixed python tests for explorev2

* Fix linting errors

* Add in stop button during slice querying/rendering (#2121)

* Add in stop button during slice querying/rendering

* Abort ajax request on stop

* Adding missing legacy module

* Removing select2.sortable.js because of license

* Allow query to display while slice is loading (#2100)

* Allow query to display while slice is loading

* Put latestQueryFormData in store

* Reorganized query function, got rid of tu[le return values

* Merging migrations

* Wrapping up shortner migration

* Fixing tests

* Add folder creation to syncBackend

* Fixing edit URL in explore view

* Fix look of Stop button

* Adding syntax highlighting to query modal

* Fix cast_form_data and flase checkbox on dash

* Bugfix

* Going deeper

* Fix filtering

* Deleing invalid filters when changing datasource

* Minor adjustments

* Fixing calendar heatmap examples

* Moving edit datasource button to header's right side

* Fixing mapbox example

* Show stack trace when clicking alert

* Adding npm sync-backend command to build instruction

* Bumping up JS dependencies

* rm dep on select2

* Fix py3 urlparse

* rm superset-select2.js

* Improving migration scripts

* Bugfixes on staging

* Fixing Markup viz
2017-02-16 17:28:35 -08:00

241 lines
6.7 KiB
JavaScript

/* eslint camelcase: 0 */
import React, { PropTypes } from 'react';
import $ from 'jquery';
import { Modal, Alert, Button, Radio } from 'react-bootstrap';
import Select from 'react-select';
import { connect } from 'react-redux';
const propTypes = {
can_overwrite: PropTypes.bool,
onHide: PropTypes.func.isRequired,
actions: PropTypes.object.isRequired,
form_data: PropTypes.object,
user_id: PropTypes.string.isRequired,
dashboards: PropTypes.array.isRequired,
alert: PropTypes.string,
slice: PropTypes.object,
datasource: PropTypes.object,
};
class SaveModal extends React.Component {
constructor(props) {
super(props);
this.state = {
saveToDashboardId: null,
newDashboardName: '',
newSliceName: '',
dashboards: [],
alert: null,
action: 'saveas',
addToDash: 'noSave',
};
}
componentDidMount() {
this.props.actions.fetchDashboards(this.props.user_id);
}
onChange(name, event) {
switch (name) {
case 'newSliceName':
this.setState({ newSliceName: event.target.value });
break;
case 'saveToDashboardId':
this.setState({ saveToDashboardId: event.value });
this.changeDash('existing');
break;
case 'newDashboardName':
this.setState({ newDashboardName: event.target.value });
break;
default:
break;
}
}
changeAction(action) {
this.setState({ action });
}
changeDash(dash) {
this.setState({ addToDash: dash });
}
saveOrOverwrite(gotodash) {
this.setState({ alert: null });
this.props.actions.removeSaveModalAlert();
const sliceParams = {};
let sliceName = null;
sliceParams.action = this.state.action;
if (this.props.slice.slice_id) {
sliceParams.slice_id = this.props.slice.slice_id;
}
if (sliceParams.action === 'saveas') {
sliceName = this.state.newSliceName;
if (sliceName === '') {
this.setState({ alert: 'Please enter a slice name' });
return;
}
sliceParams.slice_name = sliceName;
} else {
sliceParams.slice_name = this.props.slice.slice_name;
}
const addToDash = this.state.addToDash;
sliceParams.add_to_dash = addToDash;
let dashboard = null;
switch (addToDash) {
case ('existing'):
dashboard = this.state.saveToDashboardId;
if (!dashboard) {
this.setState({ alert: 'Please select a dashboard' });
return;
}
sliceParams.save_to_dashboard_id = dashboard;
break;
case ('new'):
dashboard = this.state.newDashboardName;
if (dashboard === '') {
this.setState({ alert: 'Please enter a dashboard name' });
return;
}
sliceParams.new_dashboard_name = dashboard;
break;
default:
dashboard = null;
}
sliceParams.goto_dash = gotodash;
const baseUrl = `/superset/explore/${this.props.datasource.type}/${this.props.datasource.id}/`;
sliceParams.datasource_name = this.props.datasource.name;
const saveUrl = `${baseUrl}?form_data=` +
`${encodeURIComponent(JSON.stringify(this.props.form_data))}` +
`&${$.param(sliceParams, true)}`;
this.props.actions.saveSlice(saveUrl);
this.props.onHide();
}
removeAlert() {
if (this.props.alert) {
this.props.actions.removeSaveModalAlert();
}
this.setState({ alert: null });
}
render() {
return (
<Modal
show
onHide={this.props.onHide}
bsStyle="large"
>
<Modal.Header closeButton>
<Modal.Title>
Save A Slice
</Modal.Title>
</Modal.Header>
<Modal.Body>
{(this.state.alert || this.props.alert) &&
<Alert>
{this.state.alert ? this.state.alert : this.props.alert}
<i
className="fa fa-close pull-right"
onClick={this.removeAlert.bind(this)}
style={{ cursor: 'pointer' }}
/>
</Alert>
}
<Radio
disabled={!this.props.can_overwrite}
checked={this.state.action === 'overwrite'}
onChange={this.changeAction.bind(this, 'overwrite')}
>
{`Overwrite slice ${this.props.slice.slice_name}`}
</Radio>
<Radio
inline
checked={this.state.action === 'saveas'}
onChange={this.changeAction.bind(this, 'saveas')}
> Save as &nbsp;
</Radio>
<input
name="new_slice_name"
placeholder="[slice name]"
onChange={this.onChange.bind(this, 'newSliceName')}
onFocus={this.changeAction.bind(this, 'saveas')}
/>
<br />
<hr />
<Radio
checked={this.state.addToDash === 'noSave'}
onChange={this.changeDash.bind(this, 'noSave')}
>
Do not add to a dashboard
</Radio>
<Radio
inline
checked={this.state.addToDash === 'existing'}
onChange={this.changeDash.bind(this, 'existing')}
>
Add slice to existing dashboard
</Radio>
<Select
options={this.props.dashboards}
onChange={this.onChange.bind(this, 'saveToDashboardId')}
autoSize={false}
value={this.state.saveToDashboardId}
/>
<Radio
inline
checked={this.state.addToDash === 'new'}
onChange={this.changeDash.bind(this, 'new')}
>
Add to new dashboard &nbsp;
</Radio>
<input
onChange={this.onChange.bind(this, 'newDashboardName')}
onFocus={this.changeDash.bind(this, 'new')}
placeholder="[dashboard name]"
/>
</Modal.Body>
<Modal.Footer>
<Button
type="button"
id="btn_modal_save"
className="btn pull-left"
onClick={this.saveOrOverwrite.bind(this, false)}
>
Save
</Button>
<Button
type="button"
id="btn_modal_save_goto_dash"
className="btn btn-primary pull-left gotodash"
disabled={this.state.addToDash === 'noSave'}
onClick={this.saveOrOverwrite.bind(this, true)}
>
Save & go to dashboard
</Button>
</Modal.Footer>
</Modal>
);
}
}
SaveModal.propTypes = propTypes;
function mapStateToProps(state) {
return {
datasource: state.datasource,
slice: state.slice,
can_overwrite: state.can_overwrite,
user_id: state.user_id,
dashboards: state.dashboards,
alert: state.saveModalAlert,
};
}
export { SaveModal };
export default connect(mapStateToProps, () => ({}))(SaveModal);