]> source.dussan.org Git - sonarqube.git/commitdiff
[NO-JIRA] Fix tooltip translations for copy actions
authorstanislavh <stanislav.honcharov@sonarsource.com>
Wed, 24 May 2023 09:41:00 +0000 (11:41 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 24 May 2023 20:03:14 +0000 (20:03 +0000)
server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx
server/sonar-web/design-system/src/components/__tests__/__snapshots__/CodeSnippet-test.tsx.snap
server/sonar-web/design-system/src/components/__tests__/clipboard-test.tsx
server/sonar-web/design-system/src/components/clipboard.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx

index 41e98ce716d04d3feac0b76b8bd47fe98142e4d4..87bca8a7bdc53638eb2466a1109c199ce2b48b9b 100644 (file)
@@ -25,14 +25,14 @@ import { CodeSnippet } from '../CodeSnippet';
 
 it('should show full size when multiline with no editting', () => {
   const { container } = setupWithProps();
-  const copyButton = screen.getByRole('button', { name: 'copy' });
+  const copyButton = screen.getByRole('button', { name: 'Copy' });
   expect(copyButton).toHaveStyle('top: 1.5rem');
   expect(container).toMatchSnapshot();
 });
 
 it('should show reduced size when single line with no editting', () => {
   const { container } = setupWithProps({ isOneLine: true, snippet: 'foobar' });
-  const copyButton = screen.getByRole('button', { name: 'copy' });
+  const copyButton = screen.getByRole('button', { name: 'Copy' });
   expect(copyButton).toHaveStyle('top: 1.5rem');
   expect(container).toMatchSnapshot();
 });
index 715c4e4d72d6090e23e9f86b09b15c01adf211b9..663207115400f293dc2c6b5a8bb19a3a91787587 100644 (file)
@@ -212,7 +212,7 @@ bar"
           d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
         />
       </svg>
-      copy
+      Copy
     </button>
     <pre
       class=" emotion-6 emotion-7"
@@ -451,7 +451,7 @@ exports[`should show reduced size when single line with no editting 1`] = `
           d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"
         />
       </svg>
-      copy
+      Copy
     </button>
     <pre
       class=" emotion-6 emotion-7"
index 84a44f103b123d537d45d681390c38c7d4aca76e..0eb60da20ff2403edd4a619ee2520741ddb09092 100644 (file)
@@ -39,13 +39,13 @@ describe('ClipboardButton', () => {
     const user = userEvent.setup({ delay: null });
     renderClipboardButton();
 
-    expect(screen.getByRole('button', { name: 'copy' })).toBeInTheDocument();
+    expect(screen.getByRole('button', { name: 'Copy' })).toBeInTheDocument();
 
-    await user.click(screen.getByRole('button', { name: 'copy' }));
+    await user.click(screen.getByRole('button', { name: 'Copy' }));
 
-    expect(await screen.findByText('copied_action')).toBeVisible();
+    expect(await screen.findByText('Copied')).toBeVisible();
 
-    await waitForElementToBeRemoved(() => screen.queryByText('copied_action'));
+    await waitForElementToBeRemoved(() => screen.queryByText('Copied'));
     jest.runAllTimers();
   });
 
@@ -63,7 +63,7 @@ describe('ClipboardIconButton', () => {
   it('should display correctly', () => {
     renderWithContext(<ClipboardIconButton copyValue="foo" />);
 
-    const copyButton = screen.getByRole('button', { name: 'copy_to_clipboard' });
+    const copyButton = screen.getByRole('button', { name: 'Copy to clipboard' });
     expect(copyButton).toBeInTheDocument();
   });
 });
index 50141fd929fad715466c943948f4b3b670c18723..47135a16bf2740463ebc36bb46e485c7076d6e5f 100644 (file)
@@ -22,12 +22,11 @@ import classNames from 'classnames';
 import Clipboard from 'clipboard';
 import React from 'react';
 import { INTERACTIVE_TOOLTIP_DELAY } from '../helpers/constants';
-import { translate } from '../helpers/l10n';
+import { DiscreetInteractiveIcon, InteractiveIcon, InteractiveIconSize } from './InteractiveIcon';
+import Tooltip from './Tooltip';
 import { ButtonSecondary } from './buttons';
 import { CopyIcon } from './icons/CopyIcon';
 import { IconProps } from './icons/Icon';
-import { DiscreetInteractiveIcon, InteractiveIcon, InteractiveIconSize } from './InteractiveIcon';
-import Tooltip from './Tooltip';
 
 const COPY_SUCCESS_NOTIFICATION_LIFESPAN = 1000;
 
@@ -101,6 +100,8 @@ export class ClipboardBase extends React.PureComponent<BaseProps, State> {
 interface ButtonProps {
   children?: React.ReactNode;
   className?: string;
+  copiedLabel?: string;
+  copyLabel?: string;
   copyValue: string;
   icon?: React.ReactNode;
 }
@@ -110,18 +111,20 @@ export function ClipboardButton({
   className,
   children,
   copyValue,
+  copiedLabel = 'Copied',
+  copyLabel = 'Copy',
 }: ButtonProps) {
   return (
     <ClipboardBase>
       {({ setCopyButton, copySuccess }) => (
-        <Tooltip overlay={translate('copied_action')} visible={copySuccess}>
+        <Tooltip overlay={copiedLabel} visible={copySuccess}>
           <ButtonSecondary
             className={classNames('sw-select-none', className)}
             data-clipboard-text={copyValue}
             icon={icon}
             innerRef={setCopyButton}
           >
-            {children ?? translate('copy')}
+            {children ?? copyLabel}
           </ButtonSecondary>
         </Tooltip>
       )}
@@ -133,13 +136,23 @@ interface IconButtonProps {
   Icon?: React.ComponentType<IconProps>;
   'aria-label'?: string;
   className?: string;
+  copiedLabel?: string;
+  copyLabel?: string;
   copyValue: string;
   discreet?: boolean;
   size?: InteractiveIconSize;
 }
 
 export function ClipboardIconButton(props: IconButtonProps) {
-  const { className, copyValue, discreet, size = 'small', Icon = CopyIcon } = props;
+  const {
+    className,
+    copyValue,
+    discreet,
+    size = 'small',
+    Icon = CopyIcon,
+    copiedLabel = 'Copied',
+    copyLabel = 'Copy to clipboard',
+  } = props;
   const InteractiveIconComponent = discreet ? DiscreetInteractiveIcon : InteractiveIcon;
 
   return (
@@ -150,14 +163,14 @@ export function ClipboardIconButton(props: IconButtonProps) {
             mouseEnterDelay={INTERACTIVE_TOOLTIP_DELAY}
             overlay={
               <div className="sw-w-abs-150 sw-text-center">
-                {translate(copySuccess ? 'copied_action' : 'copy_to_clipboard')}
+                {copySuccess ? copiedLabel : copyLabel}
               </div>
             }
             {...(copySuccess ? { visible: copySuccess } : undefined)}
           >
             <InteractiveIconComponent
               Icon={Icon}
-              aria-label={props['aria-label'] ?? translate('copy_to_clipboard')}
+              aria-label={props['aria-label'] ?? copyLabel}
               className={className}
               data-clipboard-text={copyValue}
               innerRef={setCopyButton}
index 68a89666f6bedb3e9b7bae58ca71d910d50e3498..7b8094d136dfbdf99b254f4c7dd48031f2bbc0a1 100644 (file)
@@ -35,6 +35,7 @@ import {
 import React from 'react';
 import { IssueMessageHighlighting } from '../../../components/issue/IssueMessageHighlighting';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
+import { translate } from '../../../helpers/l10n';
 import {
   getComponentSecurityHotspotsUrl,
   getPathUrlAsString,
@@ -96,6 +97,8 @@ export function HotspotHeader(props: HotspotHeaderProps) {
             </LightPrimary>
             <ClipboardIconButton
               Icon={LinkIcon}
+              copiedLabel={translate('copied_action')}
+              copyLabel={translate('copy_to_clipboard')}
               className="sw-ml-2"
               copyValue={permalink}
               discreet={true}
index 7b75a6e90f82a224038e1d9e80031a9a6980a156..ddf494953fc21827db60714b320f24e38b878350 100644 (file)
@@ -67,7 +67,8 @@ function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
         </span>
 
         <ClipboardIconButton
-          aria-label={translate('component_viewer.copy_path_to_clipboard')}
+          copyLabel={translate('component_viewer.copy_path_to_clipboard')}
+          copiedLabel={translate('copied_action')}
           copyValue={path}
         />
       </Note>