]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16760 [891731] Purpose of link is not clear in context
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Wed, 3 Aug 2022 14:39:27 +0000 (16:39 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 4 Aug 2022 20:03:08 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/overview/branches/DebtValue.tsx
server/sonar-web/src/main/js/apps/overview/branches/DrilldownMeasureValue.tsx
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/DebtValue-test.tsx.snap
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/DrilldownMeasureValue-test.tsx.snap
server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx
server/sonar-web/src/main/js/apps/overview/components/MeasurementLabel.tsx
server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/IssueLabel-test.tsx.snap
server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/MeasurementLabel-test.tsx.snap
server/sonar-web/src/main/js/components/shared/DrilldownLink.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 32f7311144f2fdb948e627190d2ce49b370b261c..e9219dfb5f7757094fddcdb9cc0024fd877d9dc9 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { getLeakValue } from '../../../components/measure/utils';
 import DrilldownLink from '../../../components/shared/DrilldownLink';
-import { getLocalizedMetricName, translate } from '../../../helpers/l10n';
+import { getLocalizedMetricName, translate, translateWithParameters } from '../../../helpers/l10n';
 import { findMeasure, formatMeasure, localizeMetric } from '../../../helpers/measures';
 import { BranchLike } from '../../../types/branch-like';
 import { MetricKey } from '../../../types/metrics';
@@ -35,13 +35,18 @@ export interface DebtValueProps {
 
 export function DebtValue(props: DebtValueProps) {
   const { branchLike, component, measures, useDiffMetric = false } = props;
-  const metric = useDiffMetric ? MetricKey.new_technical_debt : MetricKey.sqale_index;
-  const measure = findMeasure(measures, metric);
+  const metricKey = useDiffMetric ? MetricKey.new_technical_debt : MetricKey.sqale_index;
+  const measure = findMeasure(measures, metricKey);
 
   let value;
+  let metricName;
   if (measure) {
     value = useDiffMetric ? getLeakValue(measure) : measure.value;
+    metricName = getLocalizedMetricName(measure.metric, true);
+  } else {
+    metricName = localizeMetric(metricKey);
   }
+  const formattedValue = formatMeasure(value, 'WORK_DUR');
 
   return (
     <>
@@ -49,16 +54,19 @@ export function DebtValue(props: DebtValueProps) {
         <span aria-label={translate('no_data')} className="overview-measures-empty-value" />
       ) : (
         <DrilldownLink
+          ariaLabel={translateWithParameters(
+            'overview.see_more_details_on_x_of_y',
+            formattedValue,
+            metricName
+          )}
           branchLike={branchLike}
           className="overview-measures-value text-light"
           component={component.key}
-          metric={metric}>
-          {formatMeasure(value, 'WORK_DUR')}
+          metric={metricKey}>
+          {formattedValue}
         </DrilldownLink>
       )}
-      <span className="big-spacer-left">
-        {measure ? getLocalizedMetricName(measure.metric, true) : localizeMetric(metric)}
-      </span>
+      <span className="big-spacer-left">{metricName}</span>
     </>
   );
 }
index 700d5b681dbd36a15a94eb4f5b4b0b228ed775bb..87846f3f6c92590bb452d6f1e9d4cf8051a608fa 100644 (file)
@@ -19,8 +19,8 @@
  */
 import * as React from 'react';
 import DrilldownLink from '../../../components/shared/DrilldownLink';
-import { getLocalizedMetricName } from '../../../helpers/l10n';
-import { findMeasure, formatMeasure } from '../../../helpers/measures';
+import { getLocalizedMetricName, translateWithParameters } from '../../../helpers/l10n';
+import { findMeasure, formatMeasure, localizeMetric } from '../../../helpers/measures';
 import { BranchLike } from '../../../types/branch-like';
 import { MetricKey } from '../../../types/metrics';
 import { Component, MeasureEnhanced } from '../../../types/types';
@@ -37,12 +37,17 @@ export function DrilldownMeasureValue(props: DrilldownMeasureValueProps) {
   const measure = findMeasure(measures, metric);
 
   let content;
-  if (!measure) {
+  if (!measure || measure.value === undefined) {
     content = <span className="overview-measures-value text-light">-</span>;
   } else {
     content = (
       <span>
         <DrilldownLink
+          ariaLabel={translateWithParameters(
+            'overview.see_more_details_on_x_y',
+            measure.value,
+            localizeMetric(metric)
+          )}
           branchLike={branchLike}
           className="overview-measures-value text-light"
           component={component.key}
index a96ac567ff1d6693c9f8f750d40add21afe8587a..ebc700f4a770aa3559b2be00e4a1d4cd5345138f 100644 (file)
@@ -3,6 +3,7 @@
 exports[`should render correctly 1`] = `
 <Fragment>
   <DrilldownLink
+    ariaLabel="overview.see_more_details_on_x_of_y.work_duration.x_minutes.1.Sqale_index"
     branchLike={
       Object {
         "analysisDate": "2018-01-01",
@@ -28,6 +29,7 @@ exports[`should render correctly 1`] = `
 exports[`should render correctly 2`] = `
 <Fragment>
   <DrilldownLink
+    ariaLabel="overview.see_more_details_on_x_of_y.work_duration.x_minutes.1.New_technical_debt"
     branchLike={
       Object {
         "analysisDate": "2018-01-01",
index 210bb6293e250aed0eeb26d2c9e0b88db653fa1e..fbea0639b08eb7b166e3975481f438c5f3775af7 100644 (file)
@@ -6,6 +6,7 @@ exports[`should render correctly: default 1`] = `
 >
   <span>
     <DrilldownLink
+      ariaLabel="overview.see_more_details_on_x_y.1.0.metric.tests.name"
       branchLike={
         Object {
           "analysisDate": "2018-01-01",
index 858d3a168da99173c8ace4aa3cd0519d6e725a25..0c47a3e1e572aba94d879f12fede2b2e1ecee8c9 100644 (file)
@@ -22,7 +22,7 @@ import { Link } from 'react-router-dom';
 import HelpTooltip from '../../../components/controls/HelpTooltip';
 import { getLeakValue } from '../../../components/measure/utils';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
-import { translate } from '../../../helpers/l10n';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { findMeasure, formatMeasure, localizeMetric } from '../../../helpers/measures';
 import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls';
 import { BranchLike } from '../../../types/branch-like';
@@ -41,8 +41,8 @@ export interface IssueLabelProps {
 
 export function IssueLabel(props: IssueLabelProps) {
   const { branchLike, component, helpTooltip, measures, type, useDiffMetric = false } = props;
-  const metric = getIssueMetricKey(type, useDiffMetric);
-  const measure = findMeasure(measures, metric);
+  const metricKey = getIssueMetricKey(type, useDiffMetric);
+  const measure = findMeasure(measures, metricKey);
   const iconClass = getIssueIconClass(type);
 
   let value;
@@ -57,23 +57,29 @@ export function IssueLabel(props: IssueLabelProps) {
     inNewCodePeriod: useDiffMetric ? 'true' : 'false'
   };
 
+  const url =
+    type === IssueType.SecurityHotspot
+      ? getComponentSecurityHotspotsUrl(component.key, params)
+      : getComponentIssuesUrl(component.key, params);
+
   return (
     <>
       {value === undefined ? (
         <span aria-label={translate('no_data')} className="overview-measures-empty-value" />
       ) : (
         <Link
+          aria-label={translateWithParameters(
+            'overview.see_list_of_x_y_issues',
+            value,
+            localizeMetric(metricKey)
+          )}
           className="overview-measures-value text-light"
-          to={
-            type === IssueType.SecurityHotspot
-              ? getComponentSecurityHotspotsUrl(component.key, params)
-              : getComponentIssuesUrl(component.key, params)
-          }>
+          to={url}>
           {formatMeasure(value, 'SHORT_INT')}
         </Link>
       )}
       {React.createElement(iconClass, { className: 'big-spacer-left little-spacer-right' })}
-      {localizeMetric(metric)}
+      {localizeMetric(metricKey)}
       {helpTooltip && <HelpTooltip className="little-spacer-left" overlay={helpTooltip} />}
     </>
   );
index 9f265a6d1a0bb31805aa86a532a4c81d890299d4..9532e2e18b31486798695738f40d94a18ef3bc94 100644 (file)
@@ -21,8 +21,8 @@ import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { getLeakValue } from '../../../components/measure/utils';
 import DrilldownLink from '../../../components/shared/DrilldownLink';
-import { translate } from '../../../helpers/l10n';
-import { findMeasure, formatMeasure } from '../../../helpers/measures';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { findMeasure, formatMeasure, localizeMetric } from '../../../helpers/measures';
 import { BranchLike } from '../../../types/branch-like';
 import { Component, MeasureEnhanced } from '../../../types/types';
 import {
@@ -51,34 +51,34 @@ export default class MeasurementLabel extends React.Component<Props> {
 
     if (!measure) {
       return translate(labelKey);
-    } else {
-      const value = useDiffMetric ? getLeakValue(measure) : measure.value;
-
-      return (
-        <FormattedMessage
-          defaultMessage={translate(expandedLabelKey)}
-          id={expandedLabelKey}
-          values={{
-            count: (
-              <DrilldownLink
-                branchLike={branchLike}
-                className="big"
-                component={component.key}
-                metric={linesMetric}>
-                {formatMeasure(value, 'SHORT_INT')}
-              </DrilldownLink>
-            )
-          }}
-        />
-      );
     }
+
+    const value = useDiffMetric ? getLeakValue(measure) : measure.value;
+
+    return (
+      <FormattedMessage
+        defaultMessage={translate(expandedLabelKey)}
+        id={expandedLabelKey}
+        values={{
+          count: (
+            <DrilldownLink
+              branchLike={branchLike}
+              className="big"
+              component={component.key}
+              metric={linesMetric}>
+              {formatMeasure(value, 'SHORT_INT')}
+            </DrilldownLink>
+          )
+        }}
+      />
+    );
   };
 
   render() {
     const { branchLike, centered, component, measures, type, useDiffMetric = false } = this.props;
     const iconClass = getMeasurementIconClass(type);
-    const metric = getMeasurementMetricKey(type, useDiffMetric);
-    const measure = findMeasure(measures, metric);
+    const metricKey = getMeasurementMetricKey(type, useDiffMetric);
+    const measure = findMeasure(measures, metricKey);
 
     let value;
     if (measure) {
@@ -95,13 +95,22 @@ export default class MeasurementLabel extends React.Component<Props> {
     }
 
     const icon = React.createElement(iconClass, { size: 'big', value: Number(value) });
+    const formattedValue = formatMeasure(value, 'PERCENT', {
+      decimals: 2,
+      omitExtraDecimalZeros: true
+    });
     const link = (
       <DrilldownLink
+        ariaLabel={translateWithParameters(
+          'overview.see_more_details_on_x_of_y',
+          formattedValue,
+          localizeMetric(metricKey)
+        )}
         branchLike={branchLike}
         className="overview-measures-value text-light"
         component={component.key}
-        metric={metric}>
-        {formatMeasure(value, 'PERCENT', { decimals: 2, omitExtraDecimalZeros: true })}
+        metric={metricKey}>
+        {formattedValue}
       </DrilldownLink>
     );
     const label = this.getLabelText();
index 07600034dc30a752c64cf165a54c347a1d42827b..ebba3879584c032d840fec644b6405be9f48751a 100644 (file)
@@ -3,6 +3,7 @@
 exports[`should render correctly for bugs 1`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.bugs.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -24,6 +25,7 @@ exports[`should render correctly for bugs 1`] = `
 exports[`should render correctly for bugs 2`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.new_bugs.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -45,6 +47,7 @@ exports[`should render correctly for bugs 2`] = `
 exports[`should render correctly for code smells 1`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.code_smells.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -66,6 +69,7 @@ exports[`should render correctly for code smells 1`] = `
 exports[`should render correctly for code smells 2`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.new_code_smells.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -87,6 +91,7 @@ exports[`should render correctly for code smells 2`] = `
 exports[`should render correctly for hotspots 1`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.security_hotspots.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -112,6 +117,7 @@ exports[`should render correctly for hotspots 1`] = `
 exports[`should render correctly for hotspots 2`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.new_security_hotspots.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -137,6 +143,7 @@ exports[`should render correctly for hotspots 2`] = `
 exports[`should render correctly for vulnerabilities 1`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.vulnerabilities.name"
     className="overview-measures-value text-light"
     to={
       Object {
@@ -158,6 +165,7 @@ exports[`should render correctly for vulnerabilities 1`] = `
 exports[`should render correctly for vulnerabilities 2`] = `
 <Fragment>
   <Link
+    aria-label="overview.see_list_of_x_y_issues.1.0.metric.new_vulnerabilities.name"
     className="overview-measures-value text-light"
     to={
       Object {
index 732fe6a4674348b1509dfa61922795ecd418e76b..f6f0bb6f716a473b544c481d010a0610167ff342 100644 (file)
@@ -17,6 +17,7 @@ exports[`should render correctly for coverage 1`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.coverage.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -60,6 +61,7 @@ exports[`should render correctly for coverage 2`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.coverage.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -127,6 +129,7 @@ exports[`should render correctly for coverage 3`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.new_coverage.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -194,6 +197,7 @@ exports[`should render correctly for duplications 1`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.duplicated_lines_density.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -237,6 +241,7 @@ exports[`should render correctly for duplications 2`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.duplicated_lines_density.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -304,6 +309,7 @@ exports[`should render correctly for duplications 3`] = `
   >
     <span>
       <DrilldownLink
+        ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.new_duplicated_lines_density.name"
         branchLike={
           Object {
             "analysisDate": "2018-01-01",
@@ -370,6 +376,7 @@ exports[`should render correctly when centered 1`] = `
       />
     </span>
     <DrilldownLink
+      ariaLabel="overview.see_more_details_on_x_of_y.1.0%.metric.coverage.name"
       branchLike={
         Object {
           "analysisDate": "2018-01-01",
index 56ed2212faf47d30e920b5a65e80ca5e8ee1cdc2..def276b3bee3de27a6616eeef4e433fc7ab1a10b 100644 (file)
@@ -22,57 +22,59 @@ import { Link } from 'react-router-dom';
 import { getBranchLikeQuery } from '../../helpers/branch-like';
 import { getComponentDrilldownUrl, getComponentIssuesUrl } from '../../helpers/urls';
 import { BranchLike } from '../../types/branch-like';
+import { MetricKey } from '../../types/metrics';
 import { Dict } from '../../types/types';
 
 const ISSUE_MEASURES = [
-  'violations',
-  'new_violations',
-  'blocker_violations',
-  'critical_violations',
-  'major_violations',
-  'minor_violations',
-  'info_violations',
-  'new_blocker_violations',
-  'new_critical_violations',
-  'new_major_violations',
-  'new_minor_violations',
-  'new_info_violations',
-  'open_issues',
-  'reopened_issues',
-  'confirmed_issues',
-  'false_positive_issues',
-  'code_smells',
-  'new_code_smells',
-  'bugs',
-  'new_bugs',
-  'vulnerabilities',
-  'new_vulnerabilities'
+  MetricKey.violations,
+  MetricKey.new_violations,
+  MetricKey.blocker_violations,
+  MetricKey.critical_violations,
+  MetricKey.major_violations,
+  MetricKey.minor_violations,
+  MetricKey.info_violations,
+  MetricKey.new_blocker_violations,
+  MetricKey.new_critical_violations,
+  MetricKey.new_major_violations,
+  MetricKey.new_minor_violations,
+  MetricKey.new_info_violations,
+  MetricKey.open_issues,
+  MetricKey.reopened_issues,
+  MetricKey.confirmed_issues,
+  MetricKey.false_positive_issues,
+  MetricKey.code_smells,
+  MetricKey.new_code_smells,
+  MetricKey.bugs,
+  MetricKey.new_bugs,
+  MetricKey.vulnerabilities,
+  MetricKey.new_vulnerabilities
 ];
 
 const issueParamsPerMetric: Dict<Dict<string>> = {
-  blocker_violations: { resolved: 'false', severities: 'BLOCKER' },
-  new_blocker_violations: { resolved: 'false', severities: 'BLOCKER' },
-  critical_violations: { resolved: 'false', severities: 'CRITICAL' },
-  new_critical_violations: { resolved: 'false', severities: 'CRITICAL' },
-  major_violations: { resolved: 'false', severities: 'MAJOR' },
-  new_major_violations: { resolved: 'false', severities: 'MAJOR' },
-  minor_violations: { resolved: 'false', severities: 'MINOR' },
-  new_minor_violations: { resolved: 'false', severities: 'MINOR' },
-  info_violations: { resolved: 'false', severities: 'INFO' },
-  new_info_violations: { resolved: 'false', severities: 'INFO' },
-  open_issues: { resolved: 'false', statuses: 'OPEN' },
-  reopened_issues: { resolved: 'false', statuses: 'REOPENED' },
-  confirmed_issues: { resolved: 'false', statuses: 'CONFIRMED' },
-  false_positive_issues: { resolutions: 'FALSE-POSITIVE' },
-  code_smells: { resolved: 'false', types: 'CODE_SMELL' },
-  new_code_smells: { resolved: 'false', types: 'CODE_SMELL' },
-  bugs: { resolved: 'false', types: 'BUG' },
-  new_bugs: { resolved: 'false', types: 'BUG' },
-  vulnerabilities: { resolved: 'false', types: 'VULNERABILITY' },
-  new_vulnerabilities: { resolved: 'false', types: 'VULNERABILITY' }
+  [MetricKey.blocker_violations]: { resolved: 'false', severities: 'BLOCKER' },
+  [MetricKey.new_blocker_violations]: { resolved: 'false', severities: 'BLOCKER' },
+  [MetricKey.critical_violations]: { resolved: 'false', severities: 'CRITICAL' },
+  [MetricKey.new_critical_violations]: { resolved: 'false', severities: 'CRITICAL' },
+  [MetricKey.major_violations]: { resolved: 'false', severities: 'MAJOR' },
+  [MetricKey.new_major_violations]: { resolved: 'false', severities: 'MAJOR' },
+  [MetricKey.minor_violations]: { resolved: 'false', severities: 'MINOR' },
+  [MetricKey.new_minor_violations]: { resolved: 'false', severities: 'MINOR' },
+  [MetricKey.info_violations]: { resolved: 'false', severities: 'INFO' },
+  [MetricKey.new_info_violations]: { resolved: 'false', severities: 'INFO' },
+  [MetricKey.open_issues]: { resolved: 'false', statuses: 'OPEN' },
+  [MetricKey.reopened_issues]: { resolved: 'false', statuses: 'REOPENED' },
+  [MetricKey.confirmed_issues]: { resolved: 'false', statuses: 'CONFIRMED' },
+  [MetricKey.false_positive_issues]: { resolutions: 'FALSE-POSITIVE' },
+  [MetricKey.code_smells]: { resolved: 'false', types: 'CODE_SMELL' },
+  [MetricKey.new_code_smells]: { resolved: 'false', types: 'CODE_SMELL' },
+  [MetricKey.bugs]: { resolved: 'false', types: 'BUG' },
+  [MetricKey.new_bugs]: { resolved: 'false', types: 'BUG' },
+  [MetricKey.vulnerabilities]: { resolved: 'false', types: 'VULNERABILITY' },
+  [MetricKey.new_vulnerabilities]: { resolved: 'false', types: 'VULNERABILITY' }
 };
 
 interface Props {
+  ariaLabel?: string;
   branchLike?: BranchLike;
   children?: React.ReactNode;
   className?: string;
@@ -83,7 +85,7 @@ interface Props {
 
 export default class DrilldownLink extends React.PureComponent<Props> {
   isIssueMeasure = () => {
-    return ISSUE_MEASURES.indexOf(this.props.metric) !== -1;
+    return ISSUE_MEASURES.indexOf(this.props.metric as MetricKey) !== -1;
   };
 
   propsToIssueParams = () => {
@@ -99,14 +101,16 @@ export default class DrilldownLink extends React.PureComponent<Props> {
   };
 
   renderIssuesLink = () => {
-    const url = getComponentIssuesUrl(this.props.component, {
+    const { ariaLabel, className, component, children, branchLike } = this.props;
+
+    const url = getComponentIssuesUrl(component, {
       ...this.propsToIssueParams(),
-      ...getBranchLikeQuery(this.props.branchLike)
+      ...getBranchLikeQuery(branchLike)
     });
 
     return (
-      <Link className={this.props.className} to={url}>
-        {this.props.children}
+      <Link aria-label={ariaLabel} className={className} to={url}>
+        {children}
       </Link>
     );
   };
@@ -115,16 +119,17 @@ export default class DrilldownLink extends React.PureComponent<Props> {
     if (this.isIssueMeasure()) {
       return this.renderIssuesLink();
     }
+    const { ariaLabel, className, metric, component, children, branchLike } = this.props;
 
     const url = getComponentDrilldownUrl({
-      componentKey: this.props.component,
-      metric: this.props.metric,
-      branchLike: this.props.branchLike,
+      componentKey: component,
+      metric,
+      branchLike,
       listView: true
     });
     return (
-      <Link className={this.props.className} to={url}>
-        {this.props.children}
+      <Link aria-label={ariaLabel} className={className} to={url}>
+        {children}
       </Link>
     );
   }
index 7b8d1526bb7bd6715ae01d7a09f811c82c7ae31f..33b62b45f1b6867fb7018422bdabf60d8a2add3c 100644 (file)
@@ -3117,6 +3117,9 @@ overview.started_on_x=Started on {0}
 overview.previous_analysis_on_x=Previous analysis on {0}
 overview.on_new_code=On New Code
 overview.on_new_code_long=Conditions on New Code
+overview.see_list_of_x_y_issues=See the list of {0} {1}
+overview.see_more_details_on_x_of_y=See more details on {0} of {1}
+overview.see_more_details_on_x_y=See more details on {0} {1}
 overview.about_this_portfolio=About This Portfolio
 overview.about_this_project.APP=About This Application
 overview.about_this_project.TRK=About This Project