blob: 3b020ae170009d76f7150c89b30e4c7b4d8e8a54 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useState } from 'react';
import cx from 'classnames';
import { t } from '@superset-ui/core';
import Icons from 'src/components/Icons';
import { Tooltip } from 'src/components/Tooltip';
import copyTextToClipboard from 'src/utils/copy';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import { useUrlShortener } from 'src/common/hooks/useUrlShortener';
import EmbedCodeButton from './EmbedCodeButton';
import { exportChart, getExploreLongUrl } from '../exploreUtils';
import ExploreAdditionalActionsMenu from './ExploreAdditionalActionsMenu';
type ActionButtonProps = {
icon: React.ReactElement;
text?: string;
tooltip: string;
className?: string;
onClick: React.MouseEventHandler<HTMLElement>;
onTooltipVisibilityChange?: (visible: boolean) => void;
'data-test'?: string;
};
type ExploreActionButtonsProps = {
actions: { redirectSQLLab: () => void; openPropertiesModal: () => void };
canDownloadCSV: boolean;
chartStatus: string;
latestQueryFormData: {};
queriesResponse: {};
slice: { slice_name: string };
addDangerToast: Function;
};
const ActionButton = (props: ActionButtonProps) => {
const {
icon,
text,
tooltip,
className,
onTooltipVisibilityChange,
...rest
} = props;
return (
<Tooltip
id={`${icon}-tooltip`}
placement="top"
title={tooltip}
trigger={['hover']}
onVisibleChange={onTooltipVisibilityChange}
>
<div
role="button"
tabIndex={0}
css={{
display: 'flex',
alignItems: 'center',
'&:focus, &:focus:active': { outline: 0 },
}}
className={className || 'btn btn-default btn-sm'}
style={{ height: 30 }}
{...rest}
>
{icon}
{text && <span style={{ marginLeft: 5 }}>{text}</span>}
</div>
</Tooltip>
);
};
const ExploreActionButtons = (props: ExploreActionButtonsProps) => {
const {
actions,
canDownloadCSV,
chartStatus,
latestQueryFormData,
slice,
addDangerToast,
} = props;
const copyTooltipText = t('Copy chart URL to clipboard');
const [copyTooltip, setCopyTooltip] = useState(copyTooltipText);
const longUrl = getExploreLongUrl(latestQueryFormData);
const getShortUrl = useUrlShortener(longUrl);
const doCopyLink = async () => {
try {
setCopyTooltip(t('Loading...'));
const shortUrl = await getShortUrl();
await copyTextToClipboard(shortUrl);
setCopyTooltip(t('Copied to clipboard!'));
} catch (error) {
setCopyTooltip(t('Sorry, your browser does not support copying.'));
}
};
const doShareEmail = async () => {
try {
const subject = t('Superset Chart');
const shortUrl = await getShortUrl();
const body = t('%s%s', 'Check out this chart: ', shortUrl);
window.location.href = `mailto:?Subject=${subject}%20&Body=${body}`;
} catch (error) {
addDangerToast(t('Sorry, something went wrong. Try again later.'));
}
};
const doExportCSV = canDownloadCSV
? exportChart.bind(this, {
formData: latestQueryFormData,
resultType: 'results',
resultFormat: 'csv',
})
: null;
const doExportJson = exportChart.bind(this, {
formData: latestQueryFormData,
resultType: 'results',
resultFormat: 'json',
});
const exportToCSVClasses = cx('btn btn-default btn-sm', {
disabled: !canDownloadCSV,
});
return (
<div
className="btn-group results"
role="group"
data-test="btn-group-results"
>
{latestQueryFormData && (
<>
<ActionButton
icon={<Icons.Link iconSize="l" />}
tooltip={copyTooltip}
onClick={doCopyLink}
data-test="short-link-button"
onTooltipVisibilityChange={value =>
!value && setTimeout(() => setCopyTooltip(copyTooltipText), 200)
}
/>
<ActionButton
icon={<Icons.Email iconSize="l" />}
tooltip={t('Share chart by email')}
onClick={doShareEmail}
/>
<EmbedCodeButton latestQueryFormData={latestQueryFormData} />
<ActionButton
icon={<Icons.FileTextOutlined iconSize="m" />}
text=".JSON"
tooltip={t('Export to .JSON format')}
onClick={doExportJson}
/>
<ActionButton
icon={<Icons.FileExcelOutlined iconSize="m" />}
text=".CSV"
tooltip={t('Export to .CSV format')}
onClick={doExportCSV}
className={exportToCSVClasses}
/>
</>
)}
<ExploreAdditionalActionsMenu
latestQueryFormData={latestQueryFormData}
chartStatus={chartStatus}
onOpenInEditor={actions.redirectSQLLab}
onOpenPropertiesModal={actions.openPropertiesModal}
slice={slice}
/>
</div>
);
};
export default withToasts(ExploreActionButtons);