diff --git a/superset-frontend/spec/javascripts/explore/components/DisplayQueryButton_spec.jsx b/superset-frontend/spec/javascripts/explore/components/DisplayQueryButton_spec.jsx index 25f16a1b73064..4885266b54ddd 100644 --- a/superset-frontend/spec/javascripts/explore/components/DisplayQueryButton_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/DisplayQueryButton_spec.jsx @@ -20,6 +20,7 @@ import React from 'react'; import { mount } from 'enzyme'; import ModalTrigger from 'src/components/ModalTrigger'; import { DisplayQueryButton } from 'src/explore/components/DisplayQueryButton'; +import { MenuItem } from 'react-bootstrap'; describe('DisplayQueryButton', () => { const defaultProps = { @@ -43,5 +44,6 @@ describe('DisplayQueryButton', () => { it('renders a dropdown', () => { const wrapper = mount(); expect(wrapper.find(ModalTrigger)).toHaveLength(3); + expect(wrapper.find(MenuItem)).toHaveLength(5); }); }); diff --git a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx index 95189a1bc652d..da574e0d105bc 100644 --- a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx +++ b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx @@ -28,7 +28,7 @@ import SaveModal from './SaveModal'; import injectCustomCss from '../util/injectCustomCss'; import { SAVE_TYPE_NEWDASHBOARD } from '../util/constants'; import URLShortLinkModal from '../../components/URLShortLinkModal'; -import downloadAsImage from '../util/downloadAsImage'; +import downloadAsImage from '../../utils/downloadAsImage'; import getDashboardUrl from '../util/getDashboardUrl'; import { getActiveFilters } from '../util/activeDashboardFilters'; diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 50fc8a754cae0..9a820810ac8f7 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -22,7 +22,7 @@ import moment from 'moment'; import { Dropdown, MenuItem } from 'react-bootstrap'; import { t } from '@superset-ui/translation'; import URLShortLinkModal from '../../components/URLShortLinkModal'; -import downloadAsImage from '../util/downloadAsImage'; +import downloadAsImage from '../../utils/downloadAsImage'; import getDashboardUrl from '../util/getDashboardUrl'; import { getActiveFilters } from '../util/activeDashboardFilters'; diff --git a/superset-frontend/src/explore/components/DisplayQueryButton.jsx b/superset-frontend/src/explore/components/DisplayQueryButton.jsx index 9dac5bdc753a8..aa41f1186d829 100644 --- a/superset-frontend/src/explore/components/DisplayQueryButton.jsx +++ b/superset-frontend/src/explore/components/DisplayQueryButton.jsx @@ -41,7 +41,7 @@ import { t } from '@superset-ui/translation'; import getClientErrorObject from '../../utils/getClientErrorObject'; import CopyToClipboard from './../../components/CopyToClipboard'; import { getChartDataRequest } from '../../chart/chartAction'; - +import downloadAsImage from '../../utils/downloadAsImage'; import Loading from '../../components/Loading'; import ModalTrigger from './../../components/ModalTrigger'; import Button from '../../components/Button'; @@ -63,6 +63,7 @@ const propTypes = { animation: PropTypes.bool, queryResponse: PropTypes.object, chartStatus: PropTypes.string, + chartHeight: PropTypes.string.isRequired, latestQueryFormData: PropTypes.object.isRequired, slice: PropTypes.object, }; @@ -219,7 +220,7 @@ export class DisplayQueryButton extends React.PureComponent { return null; } render() { - const { animation, slice } = this.props; + const { animation, chartHeight, slice } = this.props; return ( )} + + {t('Download as image')} + ); } diff --git a/superset-frontend/src/explore/components/ExploreActionButtons.jsx b/superset-frontend/src/explore/components/ExploreActionButtons.jsx index 77bf6d8dd240f..52a6430d3ce17 100644 --- a/superset-frontend/src/explore/components/ExploreActionButtons.jsx +++ b/superset-frontend/src/explore/components/ExploreActionButtons.jsx @@ -31,6 +31,7 @@ const propTypes = { canDownload: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]) .isRequired, chartStatus: PropTypes.string, + chartHeight: PropTypes.string.isRequired, latestQueryFormData: PropTypes.object, queryResponse: PropTypes.object, slice: PropTypes.object, @@ -39,6 +40,7 @@ const propTypes = { export default function ExploreActionButtons({ actions, canDownload, + chartHeight, chartStatus, latestQueryFormData, queryResponse, @@ -95,6 +97,7 @@ export default function ExploreActionButtons({ )} diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx index 5f40192520850..409ce5e81010c 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx @@ -102,6 +102,7 @@ class ExploreChartPanel extends React.PureComponent { addHistory={this.props.addHistory} can_overwrite={this.props.can_overwrite} can_download={this.props.can_download} + chartHeight={this.props.height} isStarred={this.props.isStarred} slice={this.props.slice} sliceName={this.props.sliceName} diff --git a/superset-frontend/src/dashboard/util/downloadAsImage.ts b/superset-frontend/src/utils/downloadAsImage.ts similarity index 92% rename from superset-frontend/src/dashboard/util/downloadAsImage.ts rename to superset-frontend/src/utils/downloadAsImage.ts index 2be12cc4be67a..f21eea5217a34 100644 --- a/superset-frontend/src/dashboard/util/downloadAsImage.ts +++ b/superset-frontend/src/utils/downloadAsImage.ts @@ -17,7 +17,7 @@ * under the License. */ import { SyntheticEvent } from 'react'; -import domToImage from 'dom-to-image'; +import domToImage, { Options } from 'dom-to-image'; import kebabCase from 'lodash/kebabCase'; import { t } from '@superset-ui/translation'; import { addWarningToast } from 'src/messageToasts/actions'; @@ -52,7 +52,7 @@ const generateFileStem = (description: string, date = new Date()) => { export default function downloadAsImage( selector: string, description: string, - backgroundColor = GRAY_BACKGROUND_COLOR, + domToImageOptions: Options = {}, ) { return (event: SyntheticEvent) => { const elementToPrint = event.currentTarget.closest(selector); @@ -63,7 +63,11 @@ export default function downloadAsImage( ); return domToImage - .toJpeg(elementToPrint, { quality: 0.95, bgcolor: backgroundColor }) + .toJpeg(elementToPrint, { + quality: 0.95, + bgcolor: GRAY_BACKGROUND_COLOR, + ...domToImageOptions, + }) .then(dataUrl => { const link = document.createElement('a'); link.download = `${generateFileStem(description)}.jpg`;