]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20023 Add external doc URL to tooltips and small visual improvements for Issue...
authorstanislavh <stanislav.honcharov@sonarsource.com>
Wed, 2 Aug 2023 09:13:09 +0000 (11:13 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 18 Aug 2023 20:02:47 +0000 (20:02 +0000)
12 files changed:
server/sonar-web/design-system/src/components/Pill.tsx
server/sonar-web/design-system/src/components/__tests__/Pill-test.tsx
server/sonar-web/src/main/js/components/icons/SoftwareImpactSeverityIcon.tsx
server/sonar-web/src/main/js/components/issue/components/DeprecatedFieldTooltip.tsx
server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.tsx
server/sonar-web/src/main/js/components/issue/components/IssueSeverity.tsx
server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.tsx
server/sonar-web/src/main/js/components/issue/components/IssueType.tsx
server/sonar-web/src/main/js/components/issue/components/IssueView.tsx
server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx
server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index c6b5cb00cf755e6d212e75cd40916b2257a79fce..bc28d26fd63b788721071074d64b119742b0a14b 100644 (file)
@@ -33,21 +33,15 @@ const variantThemeColors: Record<PillVariant, ThemeColors> = {
 };
 
 interface PillProps {
+  ['aria-label']?: string;
   children: ReactNode;
   className?: string;
-  title?: string;
   variant: PillVariant;
 }
 
-export function Pill({ className, children, title, variant }: PillProps) {
-  const commonProps = {
-    'aria-label': title ?? children?.toString(),
-    className,
-    role: 'status',
-    title,
-  };
+export function Pill({ children, variant, ...rest }: PillProps) {
   return (
-    <StyledPill color={variantThemeColors[variant]} {...commonProps}>
+    <StyledPill color={variantThemeColors[variant]} {...rest}>
       {children}
     </StyledPill>
   );
index e76446c5f85005831a8ea4d5c6bf93eb2932a3f3..8c0f28eb87cd9018c9b2e680a8f83df32428b982 100644 (file)
@@ -23,15 +23,5 @@ import { Pill } from '../Pill';
 
 it('should render correctly', () => {
   render(<Pill variant="neutral">23</Pill>);
-  expect(screen.getByRole('status')).toBeInTheDocument();
-  expect(screen.getByRole('status')).toHaveAttribute('aria-label', '23');
-});
-
-it('should accept overriding label', () => {
-  render(
-    <Pill title="23 foo in bucket" variant="danger">
-      23
-    </Pill>
-  );
-  expect(screen.getByRole('status')).toHaveAttribute('aria-label', '23 foo in bucket');
+  expect(screen.getByText('23')).toBeInTheDocument();
 });
index 2a5bbed5852d3418cb5580f1c5bd1d77d64f8b84..b86b19786625fba5b76d48691c2129158d9c0965 100644 (file)
@@ -23,6 +23,7 @@ import {
   SoftwareImpactSeverityMediumIcon,
 } from 'design-system';
 import * as React from 'react';
+import { translate } from '../../helpers/l10n';
 import { SoftwareImpactSeverity } from '../../types/issues';
 import { Dict } from '../../types/types';
 import { IconProps } from './Icon';
@@ -43,5 +44,5 @@ export default function SoftwareImpactSeverityIcon({ severity, ...iconProps }: P
   }
 
   const DesiredIcon = severityIcons[severity];
-  return <DesiredIcon {...iconProps} />;
+  return <DesiredIcon {...iconProps} aria-label={translate('severity', severity)} />;
 }
index 1dcb8389b04c86b22e9831ad797d4b086818ca57..c705f69b6d3037db87b5cd14b18f9dff246a2b98 100644 (file)
@@ -27,14 +27,20 @@ export interface DeprecatedTooltipProps {
   field: 'type' | 'severity';
 }
 
+const FILTERS_LIST = {
+  type: ['issue.clean_code_attributes', 'issue.software_qualities'],
+  severity: ['issue.software_qualities', 'issue.severity.new'],
+};
+
 export function DeprecatedFieldTooltip({ field, docUrl }: DeprecatedTooltipProps) {
   return (
     <>
       <p className="sw-mb-4">{translate('issue', field, 'deprecation.title')}</p>
       <p>{translate('issue', field, 'deprecation.filter_by')}</p>
       <ul className="sw-list-disc sw-ml-6">
-        <li>{translate('issue.clean_code_attributes')}</li>
-        <li>{translate('issue.software_qualities')}</li>
+        {FILTERS_LIST[field].map((key) => (
+          <li key={key}>{translate(key)}</li>
+        ))}
       </ul>
       <hr className="sw-w-full sw-mx-0 sw-my-4" />
       <FormattedMessage
index 77fa8032852ec6b6056852ad868b48d7eda49649..2b3e6a300a491e6f4d248517d47d5697b9fc964d 100644 (file)
@@ -136,10 +136,9 @@ export default function IssueActionsBar(props: Props) {
         </li>
 
         <li className="sw-flex sw-gap-3">
-          {issue.impacts.map(({ severity, softwareQuality }, index) => (
+          {issue.impacts.map(({ severity, softwareQuality }) => (
             <SoftwareImpactPill
-              key={index}
-              cleanCodeAttributeCategory={issue.cleanCodeAttributeCategory}
+              key={softwareQuality}
               severity={severity}
               quality={softwareQuality}
             />
index 43712bc000491fc502273a963d4583fa255c1f30..43a7f69021e31ff8fc79c77fd1a941ea2c30019e 100644 (file)
@@ -32,10 +32,13 @@ interface Props {
 }
 
 export default function IssueSeverity({ issue }: Props) {
-  const docUrl = useDocUrl('/');
+  const docUrl = useDocUrl('/user-guide/clean-code');
 
   return (
-    <Tooltip overlay={<DeprecatedFieldTooltip field="type" docUrl={docUrl} />}>
+    <Tooltip
+      mouseLeaveDelay={0.25}
+      overlay={<DeprecatedFieldTooltip field="severity" docUrl={docUrl} />}
+    >
       <DisabledText className="sw-flex sw-items-center sw-gap-1 sw-cursor-not-allowed">
         <IssueSeverityIcon
           fill="iconSeverityDisabled"
index 06fe08be293eef3adcff3346ac82059563427076..bbfd98d5cc65c2759a92ae7ca49286ad095b712e 100644 (file)
@@ -43,7 +43,7 @@ export default function IssueTitleBar(props: IssueTitleBarProps) {
     <div className="sw-flex sw-items-end">
       <div className="sw-w-full sw-flex sw-flex-col">
         <CleanCodeAttributePill
-          className="sw-mb-1"
+          className="sw-mb-2"
           cleanCodeAttributeCategory={issue.cleanCodeAttributeCategory}
         />
         <div className="sw-w-fit">
index 410d3a4cf027a0b2b6791c71df53095c9cc5818c..12a1cd4cdd52b0667c8a982599e84c4a6853da84 100644 (file)
@@ -31,10 +31,13 @@ interface Props {
 }
 
 export default function IssueType({ issue }: Props) {
-  const docUrl = useDocUrl('/');
+  const docUrl = useDocUrl('/user-guide/clean-code');
 
   return (
-    <Tooltip overlay={<DeprecatedFieldTooltip field="type" docUrl={docUrl} />}>
+    <Tooltip
+      mouseLeaveDelay={0.25}
+      overlay={<DeprecatedFieldTooltip field="type" docUrl={docUrl} />}
+    >
       <DisabledText className="sw-flex sw-items-center sw-gap-1 sw-cursor-not-allowed">
         <IssueTypeIcon fill="iconTypeDisabled" type={issue.type} aria-hidden />
         {translate('issue.type', issue.type)}
index 61acc232fe841117d3a4c6940621ce3d7fd2c2e4..1feec1505cd2b77306cffb59d8b6a94b82ae41b7 100644 (file)
@@ -99,7 +99,7 @@ export default class IssueView extends React.PureComponent<Props> {
       >
         <div className="sw-flex sw-w-full sw-px-2 sw-gap-4">
           {hasCheckbox && (
-            <span className="sw-mt-6 sw-self-start">
+            <span className="sw-mt-7 sw-self-start">
               <Checkbox
                 checked={checked ?? false}
                 onCheck={this.handleCheck}
@@ -109,7 +109,7 @@ export default class IssueView extends React.PureComponent<Props> {
             </span>
           )}
 
-          <div className="sw-flex sw-flex-col sw-grow sw-gap-2">
+          <div className="sw-flex sw-flex-col sw-grow sw-gap-4">
             <IssueTitleBar
               currentPopup={currentPopup}
               branchLike={branchLike}
index a652f2e8551e6075ac43bec17bcb2bc7ed6b01d5..3b83c2caf71a10e0f9d21574b5cc180af427e924 100644 (file)
@@ -34,10 +34,11 @@ export interface Props {
 export function CleanCodeAttributePill(props: Props) {
   const { className, cleanCodeAttributeCategory } = props;
 
-  const docUrl = useDocUrl('/');
+  const docUrl = useDocUrl('/user-guide/clean-code');
 
   return (
     <Tooltip
+      mouseLeaveDelay={0.25}
       overlay={
         <>
           <p className="sw-mb-4">
@@ -61,11 +62,9 @@ export function CleanCodeAttributePill(props: Props) {
         </>
       }
     >
-      <span className="sw-w-fit">
-        <Pill variant="neutral" className={classNames('sw-mr-2', className)}>
-          {translate('issue.clean_code_attribute_category', cleanCodeAttributeCategory, 'issue')}
-        </Pill>
-      </span>
+      <Pill variant="neutral" className={classNames('sw-mr-2', className)}>
+        {translate('issue.clean_code_attribute_category', cleanCodeAttributeCategory, 'issue')}
+      </Pill>
     </Tooltip>
   );
 }
index f011bf3d35d598a93a10182bd16da37aa53feef1..7f6795a3aa39923c112a61e5c6851c0ebcb8b082 100644 (file)
@@ -23,25 +23,20 @@ import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { useDocUrl } from '../../helpers/docs';
 import { translate } from '../../helpers/l10n';
-import {
-  CleanCodeAttributeCategory,
-  SoftwareImpactSeverity,
-  SoftwareQuality,
-} from '../../types/issues';
+import { SoftwareImpactSeverity, SoftwareQuality } from '../../types/issues';
 import Tooltip from '../controls/Tooltip';
 import SoftwareImpactSeverityIcon from '../icons/SoftwareImpactSeverityIcon';
 
 export interface Props {
   className?: string;
-  cleanCodeAttributeCategory: CleanCodeAttributeCategory;
   severity: SoftwareImpactSeverity;
   quality: SoftwareQuality;
 }
 
 export default function SoftwareImpactPill(props: Props) {
-  const { cleanCodeAttributeCategory, className, severity, quality } = props;
+  const { className, severity, quality } = props;
 
-  const docUrl = useDocUrl('/');
+  const docUrl = useDocUrl('/user-guide/clean-code');
 
   const variant = {
     [SoftwareImpactSeverity.High]: 'danger',
@@ -52,25 +47,17 @@ export default function SoftwareImpactPill(props: Props) {
   return (
     <div>
       <Tooltip
+        mouseLeaveDelay={0.25}
         overlay={
           <>
-            <p className="sw-mb-4">
-              {translate(
-                'issue.clean_code_attribute_category',
-                cleanCodeAttributeCategory,
-                'title'
-              )}
-            </p>
-            <p>
-              <FormattedMessage
-                id="issue.impact.severity.tooltip"
-                defaultMessage={translate('issue.impact.severity.tooltip')}
-                values={{
-                  severity: translate('severity', severity).toLowerCase(),
-                  quality: translate('issue.software_quality', quality).toLowerCase(),
-                }}
-              />
-            </p>
+            <FormattedMessage
+              id="issue.impact.severity.tooltip"
+              defaultMessage={translate('issue.impact.severity.tooltip')}
+              values={{
+                severity: translate('severity', severity).toLowerCase(),
+                quality: translate('issue.software_quality', quality).toLowerCase(),
+              }}
+            />
             <hr className="sw-w-full sw-mx-0 sw-my-4" />
             <FormattedMessage
               defaultMessage={translate('learn_more_x')}
@@ -86,15 +73,13 @@ export default function SoftwareImpactPill(props: Props) {
           </>
         }
       >
-        <span>
-          <Pill
-            className={classNames('sw-flex sw-gap-1 sw-items-center', className)}
-            variant={variant}
-          >
-            {translate('issue.software_quality', quality)}
-            <SoftwareImpactSeverityIcon severity={severity} />
-          </Pill>
-        </span>
+        <Pill
+          className={classNames('sw-flex sw-gap-1 sw-items-center', className)}
+          variant={variant}
+        >
+          {translate('issue.software_quality', quality)}
+          <SoftwareImpactSeverityIcon severity={severity} />
+        </Pill>
       </Tooltip>
     </div>
   );
index 4bebe9bff0d00e6961c3fc90228eed4162187b0a..7069f1ffbe96ecb44f4ccf760ba8843f80958a7b 100644 (file)
@@ -972,6 +972,7 @@ issue.type.deprecation.documentation=Documentation
 issue.severity.deprecation.title=Severities are now directly tied to the software quality impacted. This old severity is deprecated and can no longer be modified.
 issue.severity.deprecation.filter_by=You can now filter issues by:
 issue.severity.deprecation.documentation=Documentation
+issue.severity.new=The new severities
 
 issue.software_qualities=Software qualities
 issue.software_quality.SECURITY=Security
@@ -3060,7 +3061,7 @@ projects_role.groups=Groups
 projects_role.admin=Administer
 projects_role.admin.desc=Access project settings and perform administration tasks (for private projects, users also need the "Browse" permission)
 projects_role.issueadmin=Administer Issues
-projects_role.issueadmin.desc=Change the type and severity of issues, resolve issues as being "fixed", "won't fix" or "false-positive" (for private projects, users also need the "Browse" permission).
+projects_role.issueadmin.desc=Resolve issues as being "fixed", "won't fix" or "false-positive" (for private projects, users also need the "Browse" permission).
 projects_role.securityhotspotadmin=Administer Security Hotspots
 projects_role.securityhotspotadmin.desc=Resolve a Security Hotspot as reviewed (fixed or safe), reset it as to review (for private projects, users also need the "Browse" permission).
 projects_role.user=Browse