mirror of
https://github.com/apache/superset.git
synced 2024-09-18 03:29:38 -04:00
refactor: Extract copy functionality to utils (#11928)
* Extract copy functionality to utils * Refactor * Revert bind * WIP * Absolute path * Fix lint * Remove unused resolve
This commit is contained in:
parent
fa68288d61
commit
64d6fb9f6f
@ -21,6 +21,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { t } from '@superset-ui/core';
|
import { t } from '@superset-ui/core';
|
||||||
import { Tooltip } from 'src/common/components/Tooltip';
|
import { Tooltip } from 'src/common/components/Tooltip';
|
||||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||||
|
import copyTextToClipboard from 'src/utils/copy';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
copyNode: PropTypes.node,
|
copyNode: PropTypes.node,
|
||||||
@ -83,40 +84,20 @@ class CopyToClipboard extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard(textToCopy) {
|
copyToClipboard(textToCopy) {
|
||||||
const selection = document.getSelection();
|
copyTextToClipboard(textToCopy)
|
||||||
selection.removeAllRanges();
|
.then(() => {
|
||||||
document.activeElement.blur();
|
this.setState({ hasCopied: true });
|
||||||
const range = document.createRange();
|
})
|
||||||
const span = document.createElement('span');
|
.catch(() => {
|
||||||
span.textContent = textToCopy;
|
this.props.addDangerToast(
|
||||||
span.style.all = 'unset';
|
t(
|
||||||
span.style.position = 'fixed';
|
'Sorry, your browser does not support copying. Use Ctrl / Cmd + C!',
|
||||||
span.style.top = 0;
|
),
|
||||||
span.style.clip = 'rect(0, 0, 0, 0)';
|
);
|
||||||
span.style.whiteSpace = 'pre';
|
})
|
||||||
|
.finally(() => {
|
||||||
document.body.appendChild(span);
|
this.props.onCopyEnd();
|
||||||
range.selectNode(span);
|
});
|
||||||
selection.addRange(range);
|
|
||||||
try {
|
|
||||||
if (!document.execCommand('copy')) {
|
|
||||||
throw new Error(t('Not successful'));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.props.addDangerToast(
|
|
||||||
t('Sorry, your browser does not support copying. Use Ctrl / Cmd + C!'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.removeChild(span);
|
|
||||||
if (selection.removeRange) {
|
|
||||||
selection.removeRange(range);
|
|
||||||
} else {
|
|
||||||
selection.removeAllRanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ hasCopied: true });
|
|
||||||
this.props.onCopyEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tooltipText() {
|
tooltipText() {
|
||||||
|
56
superset-frontend/src/utils/copy.ts
Normal file
56
superset-frontend/src/utils/copy.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const copyTextToClipboard = (text: string) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const selection: Selection | null = document.getSelection();
|
||||||
|
if (selection) {
|
||||||
|
selection.removeAllRanges();
|
||||||
|
const range = document.createRange();
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.textContent = text;
|
||||||
|
span.style.position = 'fixed';
|
||||||
|
span.style.top = '0';
|
||||||
|
span.style.clip = 'rect(0, 0, 0, 0)';
|
||||||
|
span.style.whiteSpace = 'pre';
|
||||||
|
|
||||||
|
document.body.appendChild(span);
|
||||||
|
range.selectNode(span);
|
||||||
|
selection.addRange(range);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!document.execCommand('copy')) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(span);
|
||||||
|
if (selection.removeRange) {
|
||||||
|
selection.removeRange(range);
|
||||||
|
} else {
|
||||||
|
selection.removeAllRanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
export default copyTextToClipboard;
|
@ -27,6 +27,7 @@ import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
|
|||||||
import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
|
||||||
import { ToastProps } from 'src/messageToasts/enhancers/withToasts';
|
import { ToastProps } from 'src/messageToasts/enhancers/withToasts';
|
||||||
import Icon from 'src/components/Icon';
|
import Icon from 'src/components/Icon';
|
||||||
|
import copyTextToClipboard from 'src/utils/copy';
|
||||||
|
|
||||||
SyntaxHighlighter.registerLanguage('sql', sqlSyntax);
|
SyntaxHighlighter.registerLanguage('sql', sqlSyntax);
|
||||||
SyntaxHighlighter.registerLanguage('markdown', markdownSyntax);
|
SyntaxHighlighter.registerLanguage('markdown', markdownSyntax);
|
||||||
@ -61,41 +62,17 @@ export default function SyntaxHighlighterCopy({
|
|||||||
language: 'sql' | 'markdown' | 'html' | 'json';
|
language: 'sql' | 'markdown' | 'html' | 'json';
|
||||||
}) {
|
}) {
|
||||||
function copyToClipboard(textToCopy: string) {
|
function copyToClipboard(textToCopy: string) {
|
||||||
const selection: Selection | null = document.getSelection();
|
copyTextToClipboard(textToCopy)
|
||||||
if (selection) {
|
.then(() => {
|
||||||
selection.removeAllRanges();
|
|
||||||
const range = document.createRange();
|
|
||||||
const span = document.createElement('span');
|
|
||||||
span.textContent = textToCopy;
|
|
||||||
span.style.position = 'fixed';
|
|
||||||
span.style.top = '0';
|
|
||||||
span.style.clip = 'rect(0, 0, 0, 0)';
|
|
||||||
span.style.whiteSpace = 'pre';
|
|
||||||
|
|
||||||
document.body.appendChild(span);
|
|
||||||
range.selectNode(span);
|
|
||||||
selection.addRange(range);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!document.execCommand('copy')) {
|
|
||||||
throw new Error(t('Not successful'));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (addDangerToast) {
|
if (addDangerToast) {
|
||||||
addDangerToast(t('Sorry, your browser does not support copying.'));
|
addDangerToast(t('Sorry, your browser does not support copying.'));
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.catch(() => {
|
||||||
document.body.removeChild(span);
|
if (addSuccessToast) {
|
||||||
if (selection.removeRange) {
|
addSuccessToast(t('SQL Copied!'));
|
||||||
selection.removeRange(range);
|
}
|
||||||
} else {
|
});
|
||||||
selection.removeAllRanges();
|
|
||||||
}
|
|
||||||
if (addSuccessToast) {
|
|
||||||
addSuccessToast(t('SQL Copied!'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<SyntaxHighlighterWrapper>
|
<SyntaxHighlighterWrapper>
|
||||||
|
@ -40,6 +40,7 @@ import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
|
|||||||
import { IconName } from 'src/components/Icon';
|
import { IconName } from 'src/components/Icon';
|
||||||
import { commonMenuData } from 'src/views/CRUD/data/common';
|
import { commonMenuData } from 'src/views/CRUD/data/common';
|
||||||
import { SavedQueryObject } from 'src/views/CRUD/types';
|
import { SavedQueryObject } from 'src/views/CRUD/types';
|
||||||
|
import copyTextToClipboard from 'src/utils/copy';
|
||||||
import SavedQueryPreviewModal from './SavedQueryPreviewModal';
|
import SavedQueryPreviewModal from './SavedQueryPreviewModal';
|
||||||
|
|
||||||
const PAGE_SIZE = 25;
|
const PAGE_SIZE = 25;
|
||||||
@ -154,39 +155,15 @@ function SavedQueryList({
|
|||||||
|
|
||||||
const copyQueryLink = useCallback(
|
const copyQueryLink = useCallback(
|
||||||
(id: number) => {
|
(id: number) => {
|
||||||
const selection: Selection | null = document.getSelection();
|
copyTextToClipboard(
|
||||||
|
`${window.location.origin}/superset/sqllab?savedQueryId=${id}`,
|
||||||
if (selection) {
|
)
|
||||||
selection.removeAllRanges();
|
.then(() => {
|
||||||
const range = document.createRange();
|
addSuccessToast(t('Link Copied!'));
|
||||||
const span = document.createElement('span');
|
})
|
||||||
span.textContent = `${window.location.origin}/superset/sqllab?savedQueryId=${id}`;
|
.catch(() => {
|
||||||
span.style.position = 'fixed';
|
|
||||||
span.style.top = '0';
|
|
||||||
span.style.clip = 'rect(0, 0, 0, 0)';
|
|
||||||
span.style.whiteSpace = 'pre';
|
|
||||||
|
|
||||||
document.body.appendChild(span);
|
|
||||||
range.selectNode(span);
|
|
||||||
selection.addRange(range);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!document.execCommand('copy')) {
|
|
||||||
throw new Error(t('Not successful'));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
addDangerToast(t('Sorry, your browser does not support copying.'));
|
addDangerToast(t('Sorry, your browser does not support copying.'));
|
||||||
}
|
});
|
||||||
|
|
||||||
document.body.removeChild(span);
|
|
||||||
if (selection.removeRange) {
|
|
||||||
selection.removeRange(range);
|
|
||||||
} else {
|
|
||||||
selection.removeAllRanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
addSuccessToast(t('Link Copied!'));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[addDangerToast, addSuccessToast],
|
[addDangerToast, addSuccessToast],
|
||||||
);
|
);
|
||||||
|
@ -24,6 +24,7 @@ import { createErrorHandler } from 'src/views/CRUD/utils';
|
|||||||
import { FetchDataConfig } from 'src/components/ListView';
|
import { FetchDataConfig } from 'src/components/ListView';
|
||||||
import { FilterValue } from 'src/components/ListView/types';
|
import { FilterValue } from 'src/components/ListView/types';
|
||||||
import Chart, { Slice } from 'src/types/Chart';
|
import Chart, { Slice } from 'src/types/Chart';
|
||||||
|
import copyTextToClipboard from 'src/utils/copy';
|
||||||
import { FavoriteStatus } from './types';
|
import { FavoriteStatus } from './types';
|
||||||
|
|
||||||
interface ListViewResourceState<D extends object = any> {
|
interface ListViewResourceState<D extends object = any> {
|
||||||
@ -435,36 +436,13 @@ export const copyQueryLink = (
|
|||||||
addDangerToast: (arg0: string) => void,
|
addDangerToast: (arg0: string) => void,
|
||||||
addSuccessToast: (arg0: string) => void,
|
addSuccessToast: (arg0: string) => void,
|
||||||
) => {
|
) => {
|
||||||
const selection: Selection | null = document.getSelection();
|
copyTextToClipboard(
|
||||||
|
`${window.location.origin}/superset/sqllab?savedQueryId=${id}`,
|
||||||
if (selection) {
|
)
|
||||||
selection.removeAllRanges();
|
.then(() => {
|
||||||
const range = document.createRange();
|
addSuccessToast(t('Link Copied!'));
|
||||||
const span = document.createElement('span');
|
})
|
||||||
span.textContent = `${window.location.origin}/superset/sqllab?savedQueryId=${id}`;
|
.catch(() => {
|
||||||
span.style.position = 'fixed';
|
|
||||||
span.style.top = '0';
|
|
||||||
span.style.clip = 'rect(0, 0, 0, 0)';
|
|
||||||
span.style.whiteSpace = 'pre';
|
|
||||||
|
|
||||||
document.body.appendChild(span);
|
|
||||||
range.selectNode(span);
|
|
||||||
selection.addRange(range);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!document.execCommand('copy')) {
|
|
||||||
throw new Error(t('Not successful'));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
addDangerToast(t('Sorry, your browser does not support copying.'));
|
addDangerToast(t('Sorry, your browser does not support copying.'));
|
||||||
}
|
});
|
||||||
|
|
||||||
document.body.removeChild(span);
|
|
||||||
if (selection.removeRange) {
|
|
||||||
selection.removeRange(range);
|
|
||||||
} else {
|
|
||||||
selection.removeAllRanges();
|
|
||||||
}
|
|
||||||
addSuccessToast(t('Link Copied!'));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user