mirror of
https://github.com/apache/superset.git
synced 2024-09-18 03:29:38 -04:00
fix: Download as image not working on Dashboard view (#11778)
* Fix download as image not working on Dashboard view * Fix menu not closing before making a screenshot * Move hardcoded selectors to variables * Fix linting issue * Add comments * Close menu before taking a screenshot on Explore view * Use style.visibility instead of timeout to hide menu for screenshot * Change const name to uppercase * Move variable declarations to case
This commit is contained in:
parent
9dd33d5566
commit
5ebc09b339
@ -61,6 +61,7 @@ export const MenuItem = styled(AntdMenu.Item)`
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
transition-duration: 0s;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -87,6 +87,8 @@ const DropdownButton = styled.div`
|
|||||||
margin-left: ${({ theme }) => theme.gridUnit * 2.5}px;
|
margin-left: ${({ theme }) => theme.gridUnit * 2.5}px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const SCREENSHOT_NODE_SELECTOR = '.dashboard';
|
||||||
|
|
||||||
class HeaderActionsDropdown extends React.PureComponent {
|
class HeaderActionsDropdown extends React.PureComponent {
|
||||||
static discardChanges() {
|
static discardChanges() {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
@ -144,9 +146,21 @@ class HeaderActionsDropdown extends React.PureComponent {
|
|||||||
case MENU_KEYS.EDIT_PROPERTIES:
|
case MENU_KEYS.EDIT_PROPERTIES:
|
||||||
this.props.showPropertiesModal();
|
this.props.showPropertiesModal();
|
||||||
break;
|
break;
|
||||||
case MENU_KEYS.DOWNLOAD_AS_IMAGE:
|
case MENU_KEYS.DOWNLOAD_AS_IMAGE: {
|
||||||
downloadAsImage('.dashboard', this.props.dashboardTitle)(domEvent);
|
// menu closes with a delay, we need to hide it manually,
|
||||||
|
// so that we don't capture it on the screenshot
|
||||||
|
const menu = document.querySelector(
|
||||||
|
'.ant-dropdown:not(.ant-dropdown-hidden)',
|
||||||
|
);
|
||||||
|
menu.style.visibility = 'hidden';
|
||||||
|
downloadAsImage(
|
||||||
|
SCREENSHOT_NODE_SELECTOR,
|
||||||
|
this.props.dashboardTitle,
|
||||||
|
)(domEvent).then(() => {
|
||||||
|
menu.style.visibility = 'visible';
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MENU_KEYS.TOGGLE_FULLSCREEN: {
|
case MENU_KEYS.TOGGLE_FULLSCREEN: {
|
||||||
const hasStandalone = window.location.search.includes(
|
const hasStandalone = window.location.search.includes(
|
||||||
'standalone=true',
|
'standalone=true',
|
||||||
@ -294,7 +308,13 @@ class HeaderActionsDropdown extends React.PureComponent {
|
|||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<NoAnimationDropdown overlay={menu} trigger={['click']}>
|
<NoAnimationDropdown
|
||||||
|
overlay={menu}
|
||||||
|
trigger={['click']}
|
||||||
|
getPopupContainer={triggerNode =>
|
||||||
|
triggerNode.closest(SCREENSHOT_NODE_SELECTOR)
|
||||||
|
}
|
||||||
|
>
|
||||||
<DropdownButton id="save-dash-split-button" role="button">
|
<DropdownButton id="save-dash-split-button" role="button">
|
||||||
<Icon name="more-horiz" />
|
<Icon name="more-horiz" />
|
||||||
</DropdownButton>
|
</DropdownButton>
|
||||||
|
@ -87,6 +87,8 @@ const RefreshTooltip = styled.div`
|
|||||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const SCREENSHOT_NODE_SELECTOR = '.dashboard-component-chart-holder';
|
||||||
|
|
||||||
const VerticalDotsTrigger = () => (
|
const VerticalDotsTrigger = () => (
|
||||||
<VerticalDotsContainer>
|
<VerticalDotsContainer>
|
||||||
<span className="dot" />
|
<span className="dot" />
|
||||||
@ -139,12 +141,21 @@ class SliceHeaderControls extends React.PureComponent {
|
|||||||
case MENU_KEYS.RESIZE_LABEL:
|
case MENU_KEYS.RESIZE_LABEL:
|
||||||
this.props.handleToggleFullSize();
|
this.props.handleToggleFullSize();
|
||||||
break;
|
break;
|
||||||
case MENU_KEYS.DOWNLOAD_AS_IMAGE:
|
case MENU_KEYS.DOWNLOAD_AS_IMAGE: {
|
||||||
|
// menu closes with a delay, we need to hide it manually,
|
||||||
|
// so that we don't capture it on the screenshot
|
||||||
|
const menu = document.querySelector(
|
||||||
|
'.ant-dropdown:not(.ant-dropdown-hidden)',
|
||||||
|
);
|
||||||
|
menu.style.visibility = 'hidden';
|
||||||
downloadAsImage(
|
downloadAsImage(
|
||||||
'.dashboard-component-chart-holder',
|
SCREENSHOT_NODE_SELECTOR,
|
||||||
this.props.slice.slice_name,
|
this.props.slice.slice_name,
|
||||||
)(domEvent);
|
)(domEvent).then(() => {
|
||||||
|
menu.style.visibility = 'visible';
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -232,6 +243,9 @@ class SliceHeaderControls extends React.PureComponent {
|
|||||||
dropdownAlign={{
|
dropdownAlign={{
|
||||||
offset: [-40, 4],
|
offset: [-40, 4],
|
||||||
}}
|
}}
|
||||||
|
getPopupContainer={triggerNode =>
|
||||||
|
triggerNode.closest(SCREENSHOT_NODE_SELECTOR)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<a id={`slice_${slice.slice_id}-controls`} role="button">
|
<a id={`slice_${slice.slice_id}-controls`} role="button">
|
||||||
<VerticalDotsTrigger />
|
<VerticalDotsTrigger />
|
||||||
|
@ -90,6 +90,7 @@ export const DisplayQueryButton = props => {
|
|||||||
datasource && datasource.split('__')[1] === 'table',
|
datasource && datasource.split('__')[1] === 'table',
|
||||||
);
|
);
|
||||||
const [isPropertiesModalOpen, setIsPropertiesModalOpen] = useState(false);
|
const [isPropertiesModalOpen, setIsPropertiesModalOpen] = useState(false);
|
||||||
|
const [menuVisible, setMenuVisible] = useState(false);
|
||||||
|
|
||||||
const tableData = useMemo(() => {
|
const tableData = useMemo(() => {
|
||||||
if (!data?.length) {
|
if (!data?.length) {
|
||||||
@ -150,6 +151,7 @@ export const DisplayQueryButton = props => {
|
|||||||
|
|
||||||
const handleMenuClick = ({ key, domEvent }) => {
|
const handleMenuClick = ({ key, domEvent }) => {
|
||||||
const { chartHeight, slice, onOpenInEditor, latestQueryFormData } = props;
|
const { chartHeight, slice, onOpenInEditor, latestQueryFormData } = props;
|
||||||
|
setMenuVisible(false);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case MENU_KEYS.EDIT_PROPERTIES:
|
case MENU_KEYS.EDIT_PROPERTIES:
|
||||||
openPropertiesModal();
|
openPropertiesModal();
|
||||||
@ -273,6 +275,7 @@ export const DisplayQueryButton = props => {
|
|||||||
const { slice } = props;
|
const { slice } = props;
|
||||||
return (
|
return (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
|
open={menuVisible}
|
||||||
noCaret
|
noCaret
|
||||||
data-test="query-dropdown"
|
data-test="query-dropdown"
|
||||||
title={
|
title={
|
||||||
@ -284,6 +287,7 @@ export const DisplayQueryButton = props => {
|
|||||||
bsSize="sm"
|
bsSize="sm"
|
||||||
pullRight
|
pullRight
|
||||||
id="query"
|
id="query"
|
||||||
|
onToggle={setMenuVisible}
|
||||||
>
|
>
|
||||||
<Menu onClick={handleMenuClick} selectable={false}>
|
<Menu onClick={handleMenuClick} selectable={false}>
|
||||||
{slice && [
|
{slice && [
|
||||||
|
Loading…
Reference in New Issue
Block a user