mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-03 19:36:20 +00:00 
			
		
		
		
	feat: introduce useClipboard hook to remove dependency (#16751)
This commit is contained in:
		
							parent
							
								
									750b6c8e8f
								
							
						
					
					
						commit
						e233d8afdc
					
				@ -17,7 +17,7 @@ Borrowed from [`@radix-ui/react-use-callback-ref`](https://www.npmjs.com/package
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
```jsx
 | 
			
		||||
import { useCallbackRef } from 'path/to/hooks';
 | 
			
		||||
import { useCallbackRef } from '@strapi/helper-plugin';
 | 
			
		||||
 | 
			
		||||
const MyComponent = ({ callbackFromSomewhere }) => {
 | 
			
		||||
  const mySafeCallback = useCallbackRef(callbackFromSomewhere);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								docs/docs/docs/01-core/helper-plugin/hooks/use-clipboard.mdx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								docs/docs/docs/01-core/helper-plugin/hooks/use-clipboard.mdx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
---
 | 
			
		||||
title: useClipboard
 | 
			
		||||
description: API reference for the useClipboard hook in Strapi
 | 
			
		||||
tags:
 | 
			
		||||
  - hooks
 | 
			
		||||
  - helper-plugin
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
A small abstraction around the [`navigation.clipboard`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) API.
 | 
			
		||||
Currently we only expose a `copy` method which abstracts the `writeText` method of the clipboard API.
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
```jsx
 | 
			
		||||
import { useClipboard } from '@strapi/helper-plugin';
 | 
			
		||||
 | 
			
		||||
const MyComponent = () => {
 | 
			
		||||
  const { copy } = useClipboard();
 | 
			
		||||
  const handleClick = async () => {
 | 
			
		||||
    const didCopy = await copy('hello world');
 | 
			
		||||
 | 
			
		||||
    if (didCopy) {
 | 
			
		||||
      alert('copied!');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return <button onClick={handleClick}>Copy text</button>;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Typescript
 | 
			
		||||
 | 
			
		||||
```ts
 | 
			
		||||
function useClipboard(): {
 | 
			
		||||
  copy: (text: string) => Promise<boolean>;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
@ -201,3 +201,16 @@ Object.defineProperty(window, 'PointerEvent', {
 | 
			
		||||
window.HTMLElement.prototype.scrollIntoView = jest.fn();
 | 
			
		||||
window.HTMLElement.prototype.releasePointerCapture = jest.fn();
 | 
			
		||||
window.HTMLElement.prototype.hasPointerCapture = jest.fn();
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------------------------------------------------------------
 | 
			
		||||
 * Navigator
 | 
			
		||||
 * -----------------------------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Navigator is a large object so we only mock the properties we need.
 | 
			
		||||
 */
 | 
			
		||||
Object.assign(navigator, {
 | 
			
		||||
  clipboard: {
 | 
			
		||||
    writeText: jest.fn(),
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import { useNotification, useTracking } from '@strapi/helper-plugin';
 | 
			
		||||
import { useNotification, useTracking, useClipboard } from '@strapi/helper-plugin';
 | 
			
		||||
import { Box, Icon, Typography } from '@strapi/design-system';
 | 
			
		||||
import { Check } from '@strapi/icons';
 | 
			
		||||
import CardButton from './CardButton';
 | 
			
		||||
@ -17,14 +17,18 @@ const InstallPluginButton = ({
 | 
			
		||||
  const toggleNotification = useNotification();
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
  const { trackUsage } = useTracking();
 | 
			
		||||
  const { copy } = useClipboard();
 | 
			
		||||
 | 
			
		||||
  const handleCopy = () => {
 | 
			
		||||
    navigator.clipboard.writeText(commandToCopy);
 | 
			
		||||
    trackUsage('willInstallPlugin');
 | 
			
		||||
    toggleNotification({
 | 
			
		||||
      type: 'success',
 | 
			
		||||
      message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
 | 
			
		||||
    });
 | 
			
		||||
  const handleCopy = async () => {
 | 
			
		||||
    const didCopy = await copy(commandToCopy);
 | 
			
		||||
 | 
			
		||||
    if (didCopy) {
 | 
			
		||||
      trackUsage('willInstallPlugin');
 | 
			
		||||
      toggleNotification({
 | 
			
		||||
        type: 'success',
 | 
			
		||||
        message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Already installed
 | 
			
		||||
 | 
			
		||||
@ -1,44 +1,46 @@
 | 
			
		||||
import React, { useRef } from 'react';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import { ContentBox, useNotification, useTracking } from '@strapi/helper-plugin';
 | 
			
		||||
import { ContentBox, useNotification, useTracking, useClipboard } from '@strapi/helper-plugin';
 | 
			
		||||
import { IconButton } from '@strapi/design-system';
 | 
			
		||||
import { Duplicate, Key } from '@strapi/icons';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
 | 
			
		||||
 | 
			
		||||
const TokenBox = ({ token, tokenType }) => {
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
  const toggleNotification = useNotification();
 | 
			
		||||
  const { trackUsage } = useTracking();
 | 
			
		||||
  const trackUsageRef = useRef(trackUsage);
 | 
			
		||||
 | 
			
		||||
  const { copy } = useClipboard();
 | 
			
		||||
 | 
			
		||||
  const handleClick = (token) => async () => {
 | 
			
		||||
    const didCopy = await copy(token);
 | 
			
		||||
 | 
			
		||||
    if (didCopy) {
 | 
			
		||||
      trackUsage.current('didCopyTokenKey', {
 | 
			
		||||
        tokenType,
 | 
			
		||||
      });
 | 
			
		||||
      toggleNotification({
 | 
			
		||||
        type: 'success',
 | 
			
		||||
        message: { id: 'Settings.tokens.notification.copied' },
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ContentBox
 | 
			
		||||
      endAction={
 | 
			
		||||
        token && (
 | 
			
		||||
          <span style={{ alignSelf: 'start' }}>
 | 
			
		||||
            <CopyToClipboard
 | 
			
		||||
              onCopy={() => {
 | 
			
		||||
                trackUsageRef.current('didCopyTokenKey', {
 | 
			
		||||
                  tokenType,
 | 
			
		||||
                });
 | 
			
		||||
                toggleNotification({
 | 
			
		||||
                  type: 'success',
 | 
			
		||||
                  message: { id: 'Settings.tokens.notification.copied' },
 | 
			
		||||
                });
 | 
			
		||||
              }}
 | 
			
		||||
              text={token}
 | 
			
		||||
            >
 | 
			
		||||
              <IconButton
 | 
			
		||||
                label={formatMessage({
 | 
			
		||||
                  id: 'app.component.CopyToClipboard.label',
 | 
			
		||||
                  defaultMessage: 'Copy to clipboard',
 | 
			
		||||
                })}
 | 
			
		||||
                noBorder
 | 
			
		||||
                icon={<Duplicate />}
 | 
			
		||||
                style={{ padding: 0, height: '1rem' }}
 | 
			
		||||
              />
 | 
			
		||||
            </CopyToClipboard>
 | 
			
		||||
            <IconButton
 | 
			
		||||
              label={formatMessage({
 | 
			
		||||
                id: 'app.component.CopyToClipboard.label',
 | 
			
		||||
                defaultMessage: 'Copy to clipboard',
 | 
			
		||||
              })}
 | 
			
		||||
              onClick={handleClick(token)}
 | 
			
		||||
              noBorder
 | 
			
		||||
              icon={<Duplicate />}
 | 
			
		||||
              style={{ padding: 0, height: '1rem' }}
 | 
			
		||||
            />
 | 
			
		||||
          </span>
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -1,30 +1,32 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { IconButton } from '@strapi/design-system';
 | 
			
		||||
import { useNotification, ContentBox } from '@strapi/helper-plugin';
 | 
			
		||||
import { useNotification, ContentBox, useClipboard } from '@strapi/helper-plugin';
 | 
			
		||||
import { Duplicate } from '@strapi/icons';
 | 
			
		||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
const MagicLinkWrapper = ({ children, target }) => {
 | 
			
		||||
  const toggleNotification = useNotification();
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
 | 
			
		||||
  const handleCopy = () => {
 | 
			
		||||
    toggleNotification({ type: 'info', message: { id: 'notification.link-copied' } });
 | 
			
		||||
  };
 | 
			
		||||
  const { copy } = useClipboard();
 | 
			
		||||
 | 
			
		||||
  const copyLabel = formatMessage({
 | 
			
		||||
    id: 'app.component.CopyToClipboard.label',
 | 
			
		||||
    defaultMessage: 'Copy to clipboard',
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const handleClick = async () => {
 | 
			
		||||
    const didCopy = await copy(target);
 | 
			
		||||
 | 
			
		||||
    if (didCopy) {
 | 
			
		||||
      toggleNotification({ type: 'info', message: { id: 'notification.link-copied' } });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ContentBox
 | 
			
		||||
      endAction={
 | 
			
		||||
        <CopyToClipboard onCopy={handleCopy} text={target}>
 | 
			
		||||
          <IconButton label={copyLabel} noBorder icon={<Duplicate />} />
 | 
			
		||||
        </CopyToClipboard>
 | 
			
		||||
        <IconButton label={copyLabel} noBorder icon={<Duplicate />} onClick={handleClick} />
 | 
			
		||||
      }
 | 
			
		||||
      title={target}
 | 
			
		||||
      titleEllipsis
 | 
			
		||||
 | 
			
		||||
@ -110,7 +110,6 @@
 | 
			
		||||
    "prop-types": "^15.7.2",
 | 
			
		||||
    "qs": "6.11.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-copy-to-clipboard": "^5.1.0",
 | 
			
		||||
    "react-dnd": "15.1.2",
 | 
			
		||||
    "react-dnd-html5-backend": "15.1.3",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,6 @@ const aliasExactMatch = [
 | 
			
		||||
  'qs',
 | 
			
		||||
  'lodash',
 | 
			
		||||
  'react',
 | 
			
		||||
  'react-copy-to-clipboard',
 | 
			
		||||
  'react-dnd',
 | 
			
		||||
  'react-dnd-html5-backend',
 | 
			
		||||
  'react-dom',
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,23 @@
 | 
			
		||||
import { renderHook } from '@testing-library/react-hooks';
 | 
			
		||||
 | 
			
		||||
import { useClipboard } from '../useClipboard';
 | 
			
		||||
 | 
			
		||||
describe('useClipboard', () => {
 | 
			
		||||
  it('should return false if the value passed to the function is not a string or number', async () => {
 | 
			
		||||
    const { result } = renderHook(() => useClipboard());
 | 
			
		||||
 | 
			
		||||
    expect(await result.current.copy({})).toBe(false);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should return false if the value passed to copy is an empty string', async () => {
 | 
			
		||||
    const { result } = renderHook(() => useClipboard());
 | 
			
		||||
 | 
			
		||||
    expect(await result.current.copy('')).toBe(false);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should return true if the copy was successful', async () => {
 | 
			
		||||
    const { result } = renderHook(() => useClipboard());
 | 
			
		||||
 | 
			
		||||
    expect(await result.current.copy('test')).toBe(true);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/core/helper-plugin/src/hooks/useClipboard.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/core/helper-plugin/src/hooks/useClipboard.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
import { useCallback } from 'react';
 | 
			
		||||
 | 
			
		||||
export const useClipboard = () => {
 | 
			
		||||
  const copy = useCallback(async (value) => {
 | 
			
		||||
    try {
 | 
			
		||||
      // only strings and numbers casted to strings can be copied to clipboard
 | 
			
		||||
      if (typeof value !== 'string' && typeof value !== 'number') {
 | 
			
		||||
        throw new Error(`Cannot copy typeof ${typeof value} to clipboard, must be a string`);
 | 
			
		||||
      }
 | 
			
		||||
      // empty strings are also considered invalid
 | 
			
		||||
      else if (value === '') {
 | 
			
		||||
        throw new Error(`Cannot copy empty string to clipboard.`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const stringifiedValue = value.toString();
 | 
			
		||||
 | 
			
		||||
      await navigator.clipboard.writeText(stringifiedValue);
 | 
			
		||||
 | 
			
		||||
      return true;
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      /**
 | 
			
		||||
       * Realistically this isn't useful in production as there's nothing the user can do.
 | 
			
		||||
       */
 | 
			
		||||
      if (process.env.NODE_ENV === 'development') {
 | 
			
		||||
        console.warn('Copy failed', error);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  return { copy };
 | 
			
		||||
};
 | 
			
		||||
@ -67,6 +67,7 @@ export * from './hooks/useAPIErrorHandler';
 | 
			
		||||
export { useFilter } from './hooks/useFilter';
 | 
			
		||||
export { useCollator } from './hooks/useCollator';
 | 
			
		||||
export { useCallbackRef } from './hooks/useCallbackRef';
 | 
			
		||||
export { useClipboard } from './hooks/useClipboard';
 | 
			
		||||
 | 
			
		||||
export { default as useQueryParams } from './hooks/useQueryParams';
 | 
			
		||||
export { default as useRBAC } from './hooks/useRBAC';
 | 
			
		||||
 | 
			
		||||
@ -2,37 +2,39 @@ import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import { IconButton } from '@strapi/design-system';
 | 
			
		||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
 | 
			
		||||
import { useNotification } from '@strapi/helper-plugin';
 | 
			
		||||
import { useNotification, useClipboard } from '@strapi/helper-plugin';
 | 
			
		||||
import { Link as LinkIcon } from '@strapi/icons';
 | 
			
		||||
import getTrad from '../../utils/getTrad';
 | 
			
		||||
 | 
			
		||||
export const CopyLinkButton = ({ url }) => {
 | 
			
		||||
  const toggleNotification = useNotification();
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
  const { copy } = useClipboard();
 | 
			
		||||
 | 
			
		||||
  const handleClick = async () => {
 | 
			
		||||
    const didCopy = await copy(url);
 | 
			
		||||
 | 
			
		||||
    if (didCopy) {
 | 
			
		||||
      toggleNotification({
 | 
			
		||||
        type: 'success',
 | 
			
		||||
        message: {
 | 
			
		||||
          id: 'notification.link-copied',
 | 
			
		||||
          defaultMessage: 'Link copied into the clipboard',
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <CopyToClipboard
 | 
			
		||||
      text={url}
 | 
			
		||||
      onCopy={() => {
 | 
			
		||||
        toggleNotification({
 | 
			
		||||
          type: 'success',
 | 
			
		||||
          message: {
 | 
			
		||||
            id: 'notification.link-copied',
 | 
			
		||||
            defaultMessage: 'Link copied into the clipboard',
 | 
			
		||||
          },
 | 
			
		||||
        });
 | 
			
		||||
      }}
 | 
			
		||||
    <IconButton
 | 
			
		||||
      label={formatMessage({
 | 
			
		||||
        id: getTrad('control-card.copy-link'),
 | 
			
		||||
        defaultMessage: 'Copy link',
 | 
			
		||||
      })}
 | 
			
		||||
      onClick={handleClick}
 | 
			
		||||
    >
 | 
			
		||||
      <IconButton
 | 
			
		||||
        label={formatMessage({
 | 
			
		||||
          id: getTrad('control-card.copy-link'),
 | 
			
		||||
          defaultMessage: 'Copy link',
 | 
			
		||||
        })}
 | 
			
		||||
      >
 | 
			
		||||
        <LinkIcon />
 | 
			
		||||
      </IconButton>
 | 
			
		||||
    </CopyToClipboard>
 | 
			
		||||
      <LinkIcon />
 | 
			
		||||
    </IconButton>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
 | 
			
		||||
import { ThemeProvider, lightTheme } from '@strapi/design-system';
 | 
			
		||||
import { IntlProvider } from 'react-intl';
 | 
			
		||||
import { QueryClient, QueryClientProvider } from 'react-query';
 | 
			
		||||
import { NotificationsProvider, TrackingProvider } from '@strapi/helper-plugin';
 | 
			
		||||
import { NotificationsProvider } from '@strapi/helper-plugin';
 | 
			
		||||
import { EditAssetDialog } from '../index';
 | 
			
		||||
import en from '../../../translations/en.json';
 | 
			
		||||
import { downloadFile } from '../../../utils/downloadFile';
 | 
			
		||||
@ -93,15 +93,13 @@ const queryClient = new QueryClient({
 | 
			
		||||
const renderCompo = (props = { canUpdate: true, canCopyLink: true, canDownload: true }) =>
 | 
			
		||||
  render(
 | 
			
		||||
    <QueryClientProvider client={queryClient}>
 | 
			
		||||
      <TrackingProvider>
 | 
			
		||||
        <ThemeProvider theme={lightTheme}>
 | 
			
		||||
          <IntlProvider locale="en" messages={messageForPlugin} defaultLocale="en">
 | 
			
		||||
            <NotificationsProvider>
 | 
			
		||||
              <EditAssetDialog asset={asset} onClose={jest.fn()} {...props} />
 | 
			
		||||
            </NotificationsProvider>
 | 
			
		||||
          </IntlProvider>
 | 
			
		||||
        </ThemeProvider>
 | 
			
		||||
      </TrackingProvider>
 | 
			
		||||
      <ThemeProvider theme={lightTheme}>
 | 
			
		||||
        <IntlProvider locale="en" messages={messageForPlugin} defaultLocale="en">
 | 
			
		||||
          <NotificationsProvider>
 | 
			
		||||
            <EditAssetDialog asset={asset} onClose={jest.fn()} {...props} />
 | 
			
		||||
          </NotificationsProvider>
 | 
			
		||||
        </IntlProvider>
 | 
			
		||||
      </ThemeProvider>
 | 
			
		||||
    </QueryClientProvider>,
 | 
			
		||||
    { container: document.getElementById('app') }
 | 
			
		||||
  );
 | 
			
		||||
@ -183,12 +181,14 @@ describe('<EditAssetDialog />', () => {
 | 
			
		||||
      expect(screen.queryByLabelText('Delete')).not.toBeInTheDocument();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('copies the link and shows a notification when pressing "Copy link" and the user has permission to copy', () => {
 | 
			
		||||
    it('copies the link and shows a notification when pressing "Copy link" and the user has permission to copy', async () => {
 | 
			
		||||
      renderCompo({ canUpdate: false, canCopyLink: true, canDownload: false });
 | 
			
		||||
 | 
			
		||||
      fireEvent.click(screen.getByLabelText('Copy link'));
 | 
			
		||||
 | 
			
		||||
      expect(screen.getByText('Link copied into the clipboard')).toBeInTheDocument();
 | 
			
		||||
      await waitFor(() =>
 | 
			
		||||
        expect(screen.getByText('Link copied into the clipboard')).toBeInTheDocument()
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('hides the copy link button when the user is not allowed to see it', () => {
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { render, screen, fireEvent } from '@testing-library/react';
 | 
			
		||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
 | 
			
		||||
import { ThemeProvider, lightTheme } from '@strapi/design-system';
 | 
			
		||||
import { IntlProvider } from 'react-intl';
 | 
			
		||||
import { QueryClient, QueryClientProvider } from 'react-query';
 | 
			
		||||
@ -145,12 +145,14 @@ describe('<EditAssetDialog />', () => {
 | 
			
		||||
      expect(screen.getByText('Are you sure you want to delete this?')).toBeVisible();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('copies the link and shows a notification when pressing "Copy link"', () => {
 | 
			
		||||
    it('copies the link and shows a notification when pressing "Copy link"', async () => {
 | 
			
		||||
      renderCompo();
 | 
			
		||||
 | 
			
		||||
      fireEvent.click(screen.getByLabelText('Copy link'));
 | 
			
		||||
 | 
			
		||||
      expect(screen.getByText('Link copied into the clipboard')).toBeInTheDocument();
 | 
			
		||||
      await waitFor(() =>
 | 
			
		||||
        expect(screen.getByText('Link copied into the clipboard')).toBeInTheDocument()
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('downloads the file when pressing "Download"', () => {
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,6 @@
 | 
			
		||||
    "mime-types": "2.1.35",
 | 
			
		||||
    "prop-types": "^15.7.2",
 | 
			
		||||
    "qs": "6.11.1",
 | 
			
		||||
    "react-copy-to-clipboard": "^5.1.0",
 | 
			
		||||
    "react-dnd": "15.1.2",
 | 
			
		||||
    "react-helmet": "^6.1.0",
 | 
			
		||||
    "react-intl": "6.4.1",
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,6 @@
 | 
			
		||||
    "lodash": "4.17.21",
 | 
			
		||||
    "path-to-regexp": "6.2.1",
 | 
			
		||||
    "pluralize": "8.0.0",
 | 
			
		||||
    "react-copy-to-clipboard": "^5.1.0",
 | 
			
		||||
    "react-helmet": "^6.1.0",
 | 
			
		||||
    "react-intl": "6.4.1",
 | 
			
		||||
    "react-query": "3.24.3",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								yarn.lock
									
									
									
									
									
								
							@ -7825,7 +7825,6 @@ __metadata:
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    qs: 6.11.1
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
    react-copy-to-clipboard: ^5.1.0
 | 
			
		||||
    react-dnd: 15.1.2
 | 
			
		||||
    react-dnd-html5-backend: 15.1.3
 | 
			
		||||
    react-dom: ^17.0.2
 | 
			
		||||
@ -8187,7 +8186,6 @@ __metadata:
 | 
			
		||||
    path-to-regexp: 6.2.1
 | 
			
		||||
    pluralize: 8.0.0
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
    react-copy-to-clipboard: ^5.1.0
 | 
			
		||||
    react-dom: ^17.0.2
 | 
			
		||||
    react-helmet: ^6.1.0
 | 
			
		||||
    react-intl: 6.4.1
 | 
			
		||||
@ -8354,7 +8352,6 @@ __metadata:
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    qs: 6.11.1
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
    react-copy-to-clipboard: ^5.1.0
 | 
			
		||||
    react-dnd: 15.1.2
 | 
			
		||||
    react-dom: ^17.0.2
 | 
			
		||||
    react-helmet: ^6.1.0
 | 
			
		||||
@ -14412,15 +14409,6 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"copy-to-clipboard@npm:^3.3.1":
 | 
			
		||||
  version: 3.3.1
 | 
			
		||||
  resolution: "copy-to-clipboard@npm:3.3.1"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    toggle-selection: ^1.0.6
 | 
			
		||||
  checksum: 3c7b1c333dc6a4b2e9905f52e4df6bbd34ff9f9c97ecd3ca55378a6bc1c191bb12a3252e6289c7b436e9188cff0360d393c0161626851d2301607860bbbdcfd5
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"copy-to@npm:^2.0.1":
 | 
			
		||||
  version: 2.0.1
 | 
			
		||||
  resolution: "copy-to@npm:2.0.1"
 | 
			
		||||
@ -27844,18 +27832,6 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"react-copy-to-clipboard@npm:^5.1.0":
 | 
			
		||||
  version: 5.1.0
 | 
			
		||||
  resolution: "react-copy-to-clipboard@npm:5.1.0"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    copy-to-clipboard: ^3.3.1
 | 
			
		||||
    prop-types: ^15.8.1
 | 
			
		||||
  peerDependencies:
 | 
			
		||||
    react: ^15.3.0 || 16 || 17 || 18
 | 
			
		||||
  checksum: f00a4551b9b63c944a041a6ab46af5ef20ba1106b3bc25173e7ef9bffbfba17a613368682ab8820cfe8d4b3acc5335cd9ce20229145bcc1e6aa8d1db04c512e5
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"react-dnd-html5-backend@npm:15.1.3":
 | 
			
		||||
  version: 15.1.3
 | 
			
		||||
  resolution: "react-dnd-html5-backend@npm:15.1.3"
 | 
			
		||||
@ -31702,13 +31678,6 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"toggle-selection@npm:^1.0.6":
 | 
			
		||||
  version: 1.0.6
 | 
			
		||||
  resolution: "toggle-selection@npm:1.0.6"
 | 
			
		||||
  checksum: a90dc80ed1e7b18db8f4e16e86a5574f87632dc729cfc07d9ea3ced50021ad42bb4e08f22c0913e0b98e3837b0b717e0a51613c65f30418e21eb99da6556a74c
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"toidentifier@npm:1.0.1":
 | 
			
		||||
  version: 1.0.1
 | 
			
		||||
  resolution: "toidentifier@npm:1.0.1"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user