client/app/pages/dashboards/components/ShareDashboardDialog.jsx (115 lines of code) (raw):
import { replace } from "lodash";
import React from "react";
import { axios } from "@/services/axios";
import PropTypes from "prop-types";
import Switch from "antd/lib/switch";
import Modal from "antd/lib/modal";
import Form from "antd/lib/form";
import Alert from "antd/lib/alert";
import notification from "@/services/notification";
import { wrap as wrapDialog, DialogPropType } from "@/components/DialogWrapper";
import InputWithCopy from "@/components/InputWithCopy";
import HelpTrigger from "@/components/HelpTrigger";
const API_SHARE_URL = "api/dashboards/{id}/share";
class ShareDashboardDialog extends React.Component {
static propTypes = {
dashboard: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
hasOnlySafeQueries: PropTypes.bool.isRequired,
dialog: DialogPropType.isRequired,
};
formItemProps = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
style: { marginBottom: 7 },
};
constructor(props) {
super(props);
const { dashboard } = this.props;
this.state = {
saving: false,
};
this.apiUrl = replace(API_SHARE_URL, "{id}", dashboard.id);
this.enabled = this.props.hasOnlySafeQueries || dashboard.publicAccessEnabled;
}
static get headerContent() {
return (
<React.Fragment>
Share Dashboard
<div className="modal-header-desc">
Allow public access to this dashboard with a secret address. <HelpTrigger type="SHARE_DASHBOARD" />
</div>
</React.Fragment>
);
}
enableAccess = () => {
const { dashboard } = this.props;
this.setState({ saving: true });
axios
.post(this.apiUrl)
.then(data => {
dashboard.publicAccessEnabled = true;
dashboard.public_url = data.public_url;
})
.catch(() => {
notification.error("Failed to turn on sharing for this dashboard");
})
.finally(() => {
this.setState({ saving: false });
});
};
disableAccess = () => {
const { dashboard } = this.props;
this.setState({ saving: true });
axios
.delete(this.apiUrl)
.then(() => {
dashboard.publicAccessEnabled = false;
delete dashboard.public_url;
})
.catch(() => {
notification.error("Failed to turn off sharing for this dashboard");
})
.finally(() => {
this.setState({ saving: false });
});
};
onChange = checked => {
if (checked) {
this.enableAccess();
} else {
this.disableAccess();
}
};
render() {
const { dialog, dashboard } = this.props;
return (
<Modal {...dialog.props} title={this.constructor.headerContent} footer={null}>
<Form layout="horizontal">
{!this.props.hasOnlySafeQueries && (
<Form.Item>
<Alert
message="For your security, sharing is currently not supported for dashboards containing queries with text parameters. Consider changing the text parameters in your query to a different type."
type="error"
/>
</Form.Item>
)}
<Form.Item label="Allow public access" {...this.formItemProps}>
<Switch
checked={dashboard.publicAccessEnabled}
onChange={this.onChange}
loading={this.state.saving}
disabled={!this.enabled}
data-test="PublicAccessEnabled"
/>
</Form.Item>
{dashboard.public_url && (
<Form.Item label="Secret address" {...this.formItemProps}>
<InputWithCopy value={dashboard.public_url} data-test="SecretAddress" />
</Form.Item>
)}
</Form>
</Modal>
);
}
}
export default wrapDialog(ShareDashboardDialog);