diff --git a/packages/nc-gui/assets/style.scss b/packages/nc-gui/assets/style.scss index 154c54bb75..f669139043 100644 --- a/packages/nc-gui/assets/style.scss +++ b/packages/nc-gui/assets/style.scss @@ -311,3 +311,10 @@ a { @apply block bg-red-500 } } + + +.nc-copy-failed-modal .ant-modal-confirm-content{ + @apply pt-4 overflow-auto; + white-space: pre; + user-select: auto; +} diff --git a/packages/nc-gui/composables/useCopy.ts b/packages/nc-gui/composables/useCopy.ts index 1703c77ab4..296128435b 100644 --- a/packages/nc-gui/composables/useCopy.ts +++ b/packages/nc-gui/composables/useCopy.ts @@ -1,6 +1,9 @@ -import { useClipboard } from '#imports' +import { Modal } from 'ant-design-vue' +import { useClipboard, useI18n } from '#imports' + +export const useCopy = (showDialogIfFailed = false) => { + const { t } = useI18n() -export const useCopy = () => { /** fallback for copy if clipboard api is not supported */ const copyFallback = async (text: string, retryCount = 0): Promise => { try { @@ -12,7 +15,15 @@ export const useCopy = () => { document.body.removeChild(textAreaEl) if (!result && retryCount < 3) { // retry if copy failed - return new Promise((resolve) => setTimeout(() => resolve(copyFallback(text, retryCount + 1)), 100)) + return new Promise((resolve, reject) => + setTimeout( + () => + copyFallback(text, retryCount + 1) + .then(resolve) + .catch(reject), + 100, + ), + ) } if (!result) { @@ -20,8 +31,15 @@ export const useCopy = () => { } return result } catch (e) { - throw new Error('Clipboard copy failed, please copy it from console log') - console.log(text) + if (!showDialogIfFailed) throw new Error(t('msg.error.copyToClipboardError')) + + Modal.info({ + title: 'Copy failed, please manually copy it from here', + content: text, + class: 'nc-copy-failed-modal', + width: '550px', + }) + return false } } @@ -32,12 +50,10 @@ export const useCopy = () => { if (isSupported.value) { await _copy(text) return true - } else { - return copyFallback(text) } - } catch (e) { - return copyFallback(text) - } + } catch {} + + return copyFallback(text) } return { copy } diff --git a/packages/nc-gui/pages/[projectType]/[projectId]/index.vue b/packages/nc-gui/pages/[projectType]/[projectId]/index.vue index 567b31fb99..cf00edd2dc 100644 --- a/packages/nc-gui/pages/[projectType]/[projectId]/index.vue +++ b/packages/nc-gui/pages/[projectType]/[projectId]/index.vue @@ -52,7 +52,7 @@ const { clearTabs, addTab } = useTabs() const { isUIAllowed } = useUIPermission() -const { copy } = useCopy() +const { copy } = useCopy(true) // create a new sidebar state const { isOpen, toggle, toggleHasSidebar } = useSidebar('nc-left-sidebar', { hasSidebar: false, isOpen: false }) @@ -128,15 +128,17 @@ const copyProjectInfo = async () => { try { await loadProjectMetaInfo() - await copy( - Object.entries(projectMetaInfo.value!) - .map(([k, v]) => `${k}: **${v}**`) - .join('\n'), - ) - - // Copied to clipboard - message.info(t('msg.info.copiedToClipboard')) - } catch (e: any) { + if ( + await copy( + Object.entries(projectMetaInfo.value!) + .map(([k, v]) => `${k}: **${v}**`) + .join('\n'), + ) + ) { + // Copied to clipboard + message.info(t('msg.info.copiedToClipboard')) + } + } catch (e) { console.error(e) message.error(e.message) } @@ -144,9 +146,10 @@ const copyProjectInfo = async () => { const copyAuthToken = async () => { try { - await copy(token.value!) - // Copied to clipboard - message.info(t('msg.info.copiedToClipboard')) + if (await copy(token.value!)) { + // Copied to clipboard + message.info(t('msg.info.copiedToClipboard')) + } } catch (e: any) { console.error(e) message.error(e.message)