]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12632 Extract measure and history buttons from portfolio to shared components
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Thu, 19 Dec 2019 09:38:12 +0000 (10:38 +0100)
committerSonarTech <sonartech@sonarsource.com>
Mon, 10 Feb 2020 19:46:14 +0000 (20:46 +0100)
20 files changed:
server/sonar-web/src/main/js/apps/portfolio/components/App.tsx
server/sonar-web/src/main/js/apps/portfolio/components/HistoryButtonLink.tsx [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/MeasuresButtonLink.tsx [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/MetricBox.tsx
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/HistoryButtonLink-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/MeasuresButtonLink-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/App-test.tsx.snap
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/HistoryButtonLink-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/MeasuresButtonLink-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/MetricBox-test.tsx.snap
server/sonar-web/src/main/js/apps/portfolio/styles.css
server/sonar-web/src/main/js/components/common/ActivityLink.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/ActivityLink.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/MeasuresLink.css [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/MeasuresLink.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/__tests__/ActivityLink-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/__tests__/MeasuresLink-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ActivityLink-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/MeasuresLink-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/urls.ts

index 0565f4289241c0fad4faf26721a89e6d231569b7..3fb63f2f92766a47a8cf23b5c0edb8a293d40263 100644 (file)
@@ -22,13 +22,13 @@ import { connect } from 'react-redux';
 import { translate } from 'sonar-ui-common/helpers/l10n';
 import { getChildren } from '../../../api/components';
 import { getMeasures } from '../../../api/measures';
+import MeasuresLink from '../../../components/common/MeasuresLink';
 import Measure from '../../../components/measure/Measure';
 import { fetchMetrics } from '../../../store/rootActions';
 import { getMetrics, Store } from '../../../store/rootReducer';
 import '../styles.css';
 import { SubComponent } from '../types';
 import { convertMeasures, PORTFOLIO_METRICS, SUB_COMPONENTS_METRICS } from '../utils';
-import MeasuresButtonLink from './MeasuresButtonLink';
 import MetricBox from './MetricBox';
 import Report from './Report';
 import WorstProjects from './WorstProjects';
@@ -183,7 +183,7 @@ export class App extends React.PureComponent<Props, State> {
             </div>
             <div className="portfolio-breakdown-box-link">
               <div>
-                <MeasuresButtonLink component={component.key} metric="projects" />
+                <MeasuresLink component={component.key} metric="projects" />
               </div>
             </div>
           </div>
@@ -198,7 +198,7 @@ export class App extends React.PureComponent<Props, State> {
             </div>
             <div className="portfolio-breakdown-box-link">
               <div>
-                <MeasuresButtonLink
+                <MeasuresLink
                   component={component.key}
                   label={translate('portfolio.language_breakdown_link')}
                   metric="ncloc"
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/HistoryButtonLink.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/HistoryButtonLink.tsx
deleted file mode 100644 (file)
index 07b485b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { Link } from 'react-router';
-import HistoryIcon from 'sonar-ui-common/components/icons/HistoryIcon';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { getMeasureHistoryUrl } from '../../../helpers/urls';
-
-interface Props {
-  component: string;
-  metric: string;
-}
-
-export default function HistoryButtonLink({ component, metric }: Props) {
-  return (
-    <Link to={getMeasureHistoryUrl(component, metric)}>
-      <HistoryIcon className="little-spacer-right" size={14} />
-      <span>{translate('portfolio.activity_link')}</span>
-    </Link>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/MeasuresButtonLink.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/MeasuresButtonLink.tsx
deleted file mode 100644 (file)
index cd875e0..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { Link } from 'react-router';
-import MeasuresIcon from 'sonar-ui-common/components/icons/MeasuresIcon';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { getComponentDrilldownUrl } from '../../../helpers/urls';
-
-interface Props {
-  component: string;
-  label?: string;
-  metric: string;
-}
-
-export default function MeasuresButtonLink({ component, label, metric }: Props) {
-  return (
-    <Link to={getComponentDrilldownUrl({ componentKey: component, metric })}>
-      <MeasuresIcon className="little-spacer-right" size={14} />
-      <span>{label || translate('portfolio.measures_link')}</span>
-    </Link>
-  );
-}
index e2715d3c5deb9387af245b2bdba08f0b88a0664d..9a4cfcd42966f77bcbcf0b0d6eebf98454eba1dd 100644 (file)
@@ -22,13 +22,13 @@ import { Link } from 'react-router';
 import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
 import Level from 'sonar-ui-common/components/ui/Level';
 import { translate } from 'sonar-ui-common/helpers/l10n';
+import ActivityLink from '../../../components/common/ActivityLink';
+import MeasuresLink from '../../../components/common/MeasuresLink';
 import Measure from '../../../components/measure/Measure';
 import { getComponentDrilldownUrl } from '../../../helpers/urls';
 import { METRICS_PER_TYPE } from '../utils';
 import Effort from './Effort';
-import HistoryButtonLink from './HistoryButtonLink';
 import MainRating from './MainRating';
-import MeasuresButtonLink from './MeasuresButtonLink';
 import RatingFreshness from './RatingFreshness';
 
 export interface MetricBoxProps {
@@ -113,10 +113,10 @@ export default function MetricBox({ component, measures, metricKey }: MetricBoxP
 
       <div className="portfolio-box-links">
         <div>
-          <MeasuresButtonLink component={component} metric={keys.measuresMetric} />
+          <MeasuresLink component={component} metric={keys.measuresMetric} />
         </div>
         <div>
-          <HistoryButtonLink component={component} metric={keys.activity || keys.rating} />
+          <ActivityLink component={component} metric={keys.activity || keys.rating} />
         </div>
       </div>
     </div>
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/HistoryButtonLink-test.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/HistoryButtonLink-test.tsx
deleted file mode 100644 (file)
index 185d2bd..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import HistoryButtonLink from '../HistoryButtonLink';
-
-it('renders', () => {
-  expect(shallow(<HistoryButtonLink component="foo" metric="security_rating" />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/MeasuresButtonLink-test.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/MeasuresButtonLink-test.tsx
deleted file mode 100644 (file)
index 8e2552a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import MeasuresButtonLink from '../MeasuresButtonLink';
-
-it('renders', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ label: 'Foo' })).toMatchSnapshot();
-});
-
-function shallowRender(props = {}) {
-  return shallow(<MeasuresButtonLink component="foo" metric="security_rating" {...props} />);
-}
index 898a5bf3a71a1f271b05916b6518b736bf449588..97f174df1ea05d8e19fcb3f5936f20118507a9b3 100644 (file)
@@ -101,7 +101,7 @@ exports[`renders 1`] = `
         className="portfolio-breakdown-box-link"
       >
         <div>
-          <MeasuresButtonLink
+          <MeasuresLink
             component="foo"
             metric="projects"
           />
@@ -129,7 +129,7 @@ exports[`renders 1`] = `
         className="portfolio-breakdown-box-link"
       >
         <div>
-          <MeasuresButtonLink
+          <MeasuresLink
             component="foo"
             label="portfolio.language_breakdown_link"
             metric="ncloc"
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/HistoryButtonLink-test.tsx.snap b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/HistoryButtonLink-test.tsx.snap
deleted file mode 100644 (file)
index 7cf000e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<Link
-  onlyActiveOnIndex={false}
-  style={Object {}}
-  to={
-    Object {
-      "pathname": "/project/activity",
-      "query": Object {
-        "custom_metrics": "security_rating",
-        "graph": "custom",
-        "id": "foo",
-      },
-    }
-  }
->
-  <HistoryIcon
-    className="little-spacer-right"
-    size={14}
-  />
-  <span>
-    portfolio.activity_link
-  </span>
-</Link>
-`;
diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/MeasuresButtonLink-test.tsx.snap b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/__snapshots__/MeasuresButtonLink-test.tsx.snap
deleted file mode 100644 (file)
index 4c62daa..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<Link
-  onlyActiveOnIndex={false}
-  style={Object {}}
-  to={
-    Object {
-      "pathname": "/component_measures",
-      "query": Object {
-        "id": "foo",
-        "metric": "security_rating",
-      },
-    }
-  }
->
-  <MeasuresIcon
-    className="little-spacer-right"
-    size={14}
-  />
-  <span>
-    portfolio.measures_link
-  </span>
-</Link>
-`;
-
-exports[`renders 2`] = `
-<Link
-  onlyActiveOnIndex={false}
-  style={Object {}}
-  to={
-    Object {
-      "pathname": "/component_measures",
-      "query": Object {
-        "id": "foo",
-        "metric": "security_rating",
-      },
-    }
-  }
->
-  <MeasuresIcon
-    className="little-spacer-right"
-    size={14}
-  />
-  <span>
-    Foo
-  </span>
-</Link>
-`;
index 8da87d3a6ca1dad6311b63ec76f0d354a604ed8e..58b528b0d45ee890e689bd2cffd46206749fbee6 100644 (file)
@@ -42,13 +42,13 @@ exports[`should render correctly 1`] = `
     className="portfolio-box-links"
   >
     <div>
-      <MeasuresButtonLink
+      <MeasuresLink
         component="foo"
         metric="Reliability"
       />
     </div>
     <div>
-      <HistoryButtonLink
+      <ActivityLink
         component="foo"
         metric="reliability_rating"
       />
@@ -122,13 +122,13 @@ exports[`should render correctly for releasability 1`] = `
     className="portfolio-box-links"
   >
     <div>
-      <MeasuresButtonLink
+      <MeasuresLink
         component="foo"
         metric="Releasability"
       />
     </div>
     <div>
-      <HistoryButtonLink
+      <ActivityLink
         component="foo"
         metric="releasability_rating"
       />
@@ -202,13 +202,13 @@ exports[`should render correctly for releasability 2`] = `
     className="portfolio-box-links"
   >
     <div>
-      <MeasuresButtonLink
+      <MeasuresLink
         component="foo"
         metric="Releasability"
       />
     </div>
     <div>
-      <HistoryButtonLink
+      <ActivityLink
         component="foo"
         metric="releasability_rating"
       />
@@ -246,13 +246,13 @@ exports[`should render correctly when no effort 1`] = `
     className="portfolio-box-links"
   >
     <div>
-      <MeasuresButtonLink
+      <MeasuresLink
         component="foo"
         metric="Releasability"
       />
     </div>
     <div>
-      <HistoryButtonLink
+      <ActivityLink
         component="foo"
         metric="releasability_rating"
       />
index 9519e0de151421d94fffd731c28aac3fb59476bf..afb3f2df0a84428f95d0a2e063a42dfc2749b8c5 100644 (file)
   border-right: 1px solid var(--barBorderColor);
 }
 
-.portfolio-box-links a,
-.portfolio-breakdown-box-link a {
-  border: none;
-}
-
 .portfolio-box-links svg,
 .portfolio-breakdown-box-link svg {
   vertical-align: middle;
 }
 
-.portfolio-box-links a > span,
-.portfolio-breakdown-box-link a > span {
-  border-bottom: 1px solid #cae3f2;
-}
-
 .portfolio-breakdown {
   display: flex;
 }
diff --git a/server/sonar-web/src/main/js/components/common/ActivityLink.css b/server/sonar-web/src/main/js/components/common/ActivityLink.css
new file mode 100644 (file)
index 0000000..dbf4eca
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+a.activity-link {
+  border: none;
+}
+
+.activity-link > span {
+  border-bottom: 1px solid var(--lightBlue);
+}
diff --git a/server/sonar-web/src/main/js/components/common/ActivityLink.tsx b/server/sonar-web/src/main/js/components/common/ActivityLink.tsx
new file mode 100644 (file)
index 0000000..07dd3eb
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as React from 'react';
+import { Link } from 'react-router';
+import HistoryIcon from 'sonar-ui-common/components/icons/HistoryIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getActivityUrl, getMeasureHistoryUrl } from '../../helpers/urls';
+import { BranchLike } from '../../types/branch-like';
+import { GraphType } from '../../types/project-activity';
+import { isCustomGraph } from '../activity-graph/utils';
+import './ActivityLink.css';
+
+export interface ActivityLinkProps {
+  branchLike?: BranchLike;
+  component: string;
+  graph?: GraphType;
+  label?: string;
+  metric?: string;
+}
+
+export default function ActivityLink(props: ActivityLinkProps) {
+  const { branchLike, component, graph, label, metric } = props;
+  return (
+    <Link
+      className="activity-link"
+      to={
+        metric !== undefined && graph !== undefined && isCustomGraph(graph)
+          ? getMeasureHistoryUrl(component, metric, branchLike)
+          : getActivityUrl(component, branchLike, graph)
+      }>
+      <HistoryIcon className="little-spacer-right" size={14} />
+      <span>{label || translate('portfolio.activity_link')}</span>
+    </Link>
+  );
+}
diff --git a/server/sonar-web/src/main/js/components/common/MeasuresLink.css b/server/sonar-web/src/main/js/components/common/MeasuresLink.css
new file mode 100644 (file)
index 0000000..edb364b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+.measures-link {
+  border: none;
+}
+
+.measures-link > span {
+  border-bottom: 1px solid var(--lightBlue);
+}
diff --git a/server/sonar-web/src/main/js/components/common/MeasuresLink.tsx b/server/sonar-web/src/main/js/components/common/MeasuresLink.tsx
new file mode 100644 (file)
index 0000000..c1b8e14
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as classNames from 'classnames';
+import * as React from 'react';
+import { Link } from 'react-router';
+import MeasuresIcon from 'sonar-ui-common/components/icons/MeasuresIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getComponentDrilldownUrl } from '../../helpers/urls';
+import { BranchLike } from '../../types/branch-like';
+import './MeasuresLink.css';
+
+export interface MeasuresLinkProps {
+  branchLike?: BranchLike;
+  className?: string;
+  component: string;
+  label?: string;
+  metric: string;
+}
+
+export default function MeasuresLink(props: MeasuresLinkProps) {
+  const { branchLike, className, component, label, metric } = props;
+  return (
+    <Link
+      className={classNames('measures-link', className)}
+      to={getComponentDrilldownUrl({ branchLike, componentKey: component, metric })}>
+      <MeasuresIcon className="little-spacer-right" size={14} />
+      <span>{label || translate('portfolio.measures_link')}</span>
+    </Link>
+  );
+}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/ActivityLink-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/ActivityLink-test.tsx
new file mode 100644 (file)
index 0000000..063f04b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockBranch } from '../../../helpers/mocks/branch-like';
+import { GraphType } from '../../../types/project-activity';
+import ActivityLink, { ActivityLinkProps } from '../ActivityLink';
+
+it('renders correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ label: 'Foo', branchLike: mockBranch() })).toMatchSnapshot();
+  expect(shallowRender({ graph: GraphType.coverage })).toMatchSnapshot();
+  expect(shallowRender({ graph: GraphType.custom, metric: 'new_bugs,bugs' })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<ActivityLinkProps> = {}) {
+  return shallow(<ActivityLink component="foo" {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/MeasuresLink-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/MeasuresLink-test.tsx
new file mode 100644 (file)
index 0000000..f4b7daa
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockMainBranch } from '../../../helpers/mocks/branch-like';
+import MeasuresLink, { MeasuresLinkProps } from '../MeasuresLink';
+
+it('renders', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ label: 'Foo' })).toMatchSnapshot();
+  expect(shallowRender({ branchLike: mockMainBranch() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<MeasuresLinkProps> = {}) {
+  return shallow(<MeasuresLink component="foo" metric="security_rating" {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ActivityLink-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ActivityLink-test.tsx.snap
new file mode 100644 (file)
index 0000000..e61f19c
--- /dev/null
@@ -0,0 +1,103 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<Link
+  className="activity-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/project/activity",
+      "query": Object {
+        "graph": undefined,
+        "id": "foo",
+      },
+    }
+  }
+>
+  <HistoryIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    portfolio.activity_link
+  </span>
+</Link>
+`;
+
+exports[`renders correctly 2`] = `
+<Link
+  className="activity-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/project/activity",
+      "query": Object {
+        "branch": "branch-6.7",
+        "graph": undefined,
+        "id": "foo",
+      },
+    }
+  }
+>
+  <HistoryIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    Foo
+  </span>
+</Link>
+`;
+
+exports[`renders correctly 3`] = `
+<Link
+  className="activity-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/project/activity",
+      "query": Object {
+        "graph": "coverage",
+        "id": "foo",
+      },
+    }
+  }
+>
+  <HistoryIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    portfolio.activity_link
+  </span>
+</Link>
+`;
+
+exports[`renders correctly 4`] = `
+<Link
+  className="activity-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/project/activity",
+      "query": Object {
+        "custom_metrics": "new_bugs,bugs",
+        "graph": "custom",
+        "id": "foo",
+      },
+    }
+  }
+>
+  <HistoryIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    portfolio.activity_link
+  </span>
+</Link>
+`;
diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/MeasuresLink-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/MeasuresLink-test.tsx.snap
new file mode 100644 (file)
index 0000000..e874481
--- /dev/null
@@ -0,0 +1,76 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<Link
+  className="measures-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/component_measures",
+      "query": Object {
+        "id": "foo",
+        "metric": "security_rating",
+      },
+    }
+  }
+>
+  <MeasuresIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    portfolio.measures_link
+  </span>
+</Link>
+`;
+
+exports[`renders 2`] = `
+<Link
+  className="measures-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/component_measures",
+      "query": Object {
+        "id": "foo",
+        "metric": "security_rating",
+      },
+    }
+  }
+>
+  <MeasuresIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    Foo
+  </span>
+</Link>
+`;
+
+exports[`renders 3`] = `
+<Link
+  className="measures-link"
+  onlyActiveOnIndex={false}
+  style={Object {}}
+  to={
+    Object {
+      "pathname": "/component_measures",
+      "query": Object {
+        "id": "foo",
+        "metric": "security_rating",
+      },
+    }
+  }
+>
+  <MeasuresIcon
+    className="little-spacer-right"
+    size={14}
+  />
+  <span>
+    portfolio.measures_link
+  </span>
+</Link>
+`;
index 5daea42ff6e33b1aca3448ba59a824ff29e22f92..21cac8461c24a9e27cdd98fb4d291ebeaa12f749 100644 (file)
@@ -20,6 +20,7 @@
 import { getBaseUrl, Location } from 'sonar-ui-common/helpers/urls';
 import { getProfilePath } from '../apps/quality-profiles/utils';
 import { BranchLike } from '../types/branch-like';
+import { GraphType } from '../types/project-activity';
 import { getBranchLikeQuery, isBranch, isMainBranch, isPullRequest } from './branch-like';
 
 type Query = Location['query'];
@@ -118,10 +119,10 @@ export function getMeasureTreemapUrl(componentKey: string, metric: string) {
   return getComponentDrilldownUrl({ componentKey, metric, treemapView: true });
 }
 
-export function getActivityUrl(component: string, branchLike?: BranchLike) {
+export function getActivityUrl(component: string, branchLike?: BranchLike, graph?: GraphType) {
   return {
     pathname: '/project/activity',
-    query: { id: component, ...getBranchLikeQuery(branchLike) }
+    query: { id: component, graph, ...getBranchLikeQuery(branchLike) }
   };
 }