]> source.dussan.org Git - sonarqube.git/commitdiff
Migrate App to tsx and clean up measures related types
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Tue, 16 Jan 2018 12:49:10 +0000 (13:49 +0100)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Thu, 25 Jan 2018 14:16:50 +0000 (15:16 +0100)
12 files changed:
server/sonar-web/src/main/js/api/measures.ts
server/sonar-web/src/main/js/api/time-machine.ts
server/sonar-web/src/main/js/app/types.ts
server/sonar-web/src/main/js/apps/code/types.ts
server/sonar-web/src/main/js/apps/overview/components/App.js [deleted file]
server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js [deleted file]
server/sonar-web/src/main/js/apps/portfolio/components/Summary.tsx
server/sonar-web/src/main/js/components/measure/Measure.tsx
server/sonar-web/src/main/js/components/measure/utils.ts
server/sonar-web/src/main/js/helpers/l10n.ts
server/sonar-web/src/main/js/helpers/measures.ts
server/sonar-web/src/main/js/helpers/periods.ts

index c423492abdeb56f44b64b7d4f08b7ce56a415cc3..2f5ae506503e3a42aef0d1d9ca24adc17556813c 100644 (file)
  */
 import { getJSON, RequestData } from '../helpers/request';
 import throwGlobalError from '../app/utils/throwGlobalError';
+import { Measure, MeasurePeriod } from '../helpers/measures';
+import { Metric } from '../app/types';
+import { Period } from '../helpers/periods';
 
 export function getMeasures(
   componentKey: string,
   metrics: string[],
   branch?: string
-): Promise<Array<{ metric: string; value?: string }>> {
+): Promise<{ metric: string; value?: string }[]> {
   const url = '/api/measures/component';
   const data = { componentKey, metricKeys: metrics.join(','), branch };
   return getJSON(url, data).then(r => r.component.measures, throwGlobalError);
 }
 
+interface MeasureComponent {
+  key: string;
+  description?: string;
+  measures: Measure[];
+  name: string;
+  qualifier: string;
+}
+
 export function getMeasuresAndMeta(
   componentKey: string,
   metrics: string[],
   additional: RequestData = {}
-): Promise<any> {
+): Promise<{ component: MeasureComponent; metrics?: Metric[]; periods?: Period[] }> {
   const data = { ...additional, componentKey, metricKeys: metrics.join(',') };
   return getJSON('/api/measures/component', data);
 }
 
-export interface Period {
-  index: number;
-  value: string;
-}
-
-export interface Measure {
+interface MeasuresForProjects {
   component: string;
   metric: string;
-  periods?: Period[];
+  periods?: MeasurePeriod[];
   value?: string;
 }
 
 export function getMeasuresForProjects(
   projectKeys: string[],
   metricKeys: string[]
-): Promise<Measure[]> {
+): Promise<MeasuresForProjects[]> {
   return getJSON('/api/measures/search', {
     projectKeys: projectKeys.join(),
     metricKeys: metricKeys.join()
index 31f3b0681ec3c37b2053f700f573e2ad89252769..e6c01eba852bcdb12763ed6d8a917fdf098db42d 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { getJSON } from '../helpers/request';
+import { Paging } from '../app/types';
+
+export interface HistoryItem {
+  date: Date;
+  value: string;
+}
+
+export interface History {
+  [metric: string]: HistoryItem[];
+}
 
 interface TimeMachineResponse {
-  measures: Array<{
+  measures: {
     metric: string;
-    history: Array<{ date: string; value: string }>;
-  }>;
-  paging: { pageIndex: number; pageSize: number; total: number };
+    history: HistoryItem[];
+  }[];
+  paging: Paging;
 }
 
 export function getTimeMachineData(
   component: string,
   metrics: string[],
-  other?: { p?: number; ps?: number; from?: string; to?: string }
+  other?: { branch?: string; p?: number; ps?: number; from?: string; to?: string }
 ): Promise<TimeMachineResponse> {
   return getJSON('/api/measures/search_history', {
     component,
@@ -43,7 +53,7 @@ export function getTimeMachineData(
 export function getAllTimeMachineData(
   component: string,
   metrics: Array<string>,
-  other?: { p?: number; from?: string; to?: string },
+  other?: { branch?: string; p?: number; from?: string; to?: string },
   prev?: TimeMachineResponse
 ): Promise<TimeMachineResponse> {
   return getTimeMachineData(component, metrics, { ...other, ps: 1000 }).then(r => {
index 11394b158ad7c3d568d3c2c1ebde89d6d3678555..7a2a64d4e2605938adac5f41f459ebf965ba29d6 100644 (file)
@@ -105,7 +105,7 @@ export interface Metric {
   domain?: string;
   hidden?: boolean;
   key: string;
-  name: string;
+  name?: string;
   qualitative?: boolean;
   type: string;
 }
index 0c7040622e8c78ff2ffb9ce66be5ee912786e74a..3a226f8127d6df649ce72632ee8b4b21ca517c44 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-interface Measure {
-  metric: string;
-  value: string;
-  periods?: Period[];
-}
 
-interface Period {
-  index: number;
-  value: string;
-}
+import { Measure } from '../../helpers/measures';
 
 export interface Component extends Breadcrumb {
   measures?: Measure[];
diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.js b/server/sonar-web/src/main/js/apps/overview/components/App.js
deleted file mode 100644 (file)
index 2d4067b..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import PropTypes from 'prop-types';
-import OverviewApp from './OverviewApp';
-import EmptyOverview from './EmptyOverview';
-import { getBranchName, isShortLivingBranch } from '../../../helpers/branches';
-import { getProjectBranchUrl, getCodeUrl } from '../../../helpers/urls';
-
-/*::
-type Props = {
-  branch?: { name: string },
-  component: {
-    analysisDate?: string,
-    breadcrumbs: Array<{ key: string }>,
-    id: string,
-    key: string,
-    qualifier: string,
-    tags: Array<string>,
-    organization?: string
-  },
-  isInProgress?: bool,
-  isPending?: bool,
-  onComponentChange: {} => void,
-  router: Object
-};
-*/
-
-export default class App extends React.PureComponent {
-  /*:: props: Props; */
-  /*:: state: Object; */
-
-  static contextTypes = {
-    router: PropTypes.object
-  };
-
-  componentDidMount() {
-    const { branch, component } = this.props;
-
-    if (this.isPortfolio()) {
-      this.context.router.replace({
-        pathname: '/portfolio',
-        query: { id: component.key }
-      });
-    } else if (this.isFile()) {
-      this.context.router.replace(
-        getCodeUrl(component.breadcrumbs[0].key, getBranchName(branch), component.key)
-      );
-    } else if (isShortLivingBranch(branch)) {
-      this.context.router.replace(getProjectBranchUrl(component.key, branch));
-    }
-  }
-
-  isPortfolio() {
-    return ['VW', 'SVW'].includes(this.props.component.qualifier);
-  }
-
-  isFile() {
-    return ['FIL', 'UTS'].includes(this.props.component.qualifier);
-  }
-
-  render() {
-    const { branch, component } = this.props;
-
-    if (this.isPortfolio() || this.isFile() || isShortLivingBranch(branch)) {
-      return null;
-    }
-
-    if (!component.analysisDate) {
-      return (
-        <EmptyOverview
-          component={component.key}
-          showWarning={!this.props.isPending && !this.props.isInProgress}
-        />
-      );
-    }
-
-    return (
-      <OverviewApp
-        branch={branch}
-        component={component}
-        onComponentChange={this.props.onComponentChange}
-      />
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js
deleted file mode 100644 (file)
index 09c4aea..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import { mount, shallow } from 'enzyme';
-import App from '../App';
-import OverviewApp from '../OverviewApp';
-import EmptyOverview from '../EmptyOverview';
-
-it('should render OverviewApp', () => {
-  const component = { key: 'foo', analysisDate: '2016-01-01' };
-  const output = shallow(<App component={component} />);
-  expect(output.type()).toBe(OverviewApp);
-});
-
-it('should render EmptyOverview', () => {
-  const component = { key: 'foo' };
-  const output = shallow(<App component={component} />);
-  expect(output.type()).toBe(EmptyOverview);
-});
-
-it('redirects on Code page for files', () => {
-  const branch = { isMain: false, name: 'b' };
-  const component = {
-    breadcrumbs: [{ key: 'project' }, { key: 'foo' }],
-    key: 'foo',
-    qualifier: 'FIL'
-  };
-  const replace = jest.fn();
-  mount(<App branch={branch} component={component} />, { context: { router: { replace } } });
-  expect(replace).toBeCalledWith({
-    pathname: '/code',
-    query: { branch: 'b', id: 'project', selected: 'foo' }
-  });
-});
index a19cd99b2a4fc593b4465998dee8967794ef9724..3279b530d70853aad6ee8c8ce9f37f4db2257d1f 100644 (file)
@@ -30,8 +30,7 @@ interface Props {
 }
 
 export default function Summary({ component, measures }: Props) {
-  const projects = measures['projects'];
-  const ncloc = measures['ncloc'];
+  const { projects, ncloc } = measures;
   const nclocDistribution = measures['ncloc_language_distribution'];
 
   return (
index 7836b86e1d6709e6d83b46058f067d10ad1d8e1a..200035f80169e9adebf419e32bab44eb1b7896c8 100644 (file)
@@ -21,8 +21,8 @@ import * as React from 'react';
 import Rating from '../ui/Rating';
 import Level from '../ui/Level';
 import Tooltips from '../controls/Tooltip';
-import { formatMeasure, isDiffMetric } from '../../helpers/measures';
-import { formatLeak, getRatingTooltip, MeasureEnhanced } from './utils';
+import { formatMeasure, isDiffMetric, MeasureEnhanced } from '../../helpers/measures';
+import { formatLeak, getRatingTooltip } from './utils';
 
 interface Props {
   className?: string;
@@ -35,7 +35,7 @@ export default function Measure({ className, decimals, measure }: Props) {
     return <span>{'–'}</span>;
   }
 
-  const metric = measure.metric;
+  const { metric } = measure;
   const value = isDiffMetric(metric.key) ? measure.leak : measure.value;
 
   if (value === undefined) {
index a526a8443c4ce5e3832c9a6095871f53335ca98e..8e932892152f538d3ce60989bf60ecc92d6420d3 100644 (file)
@@ -21,33 +21,20 @@ import {
   formatMeasure,
   formatMeasureVariation,
   getRatingTooltip as nextGetRatingTooltip,
-  isDiffMetric
+  isDiffMetric,
+  Measure,
+  MeasureEnhanced
 } from '../../helpers/measures';
 import { Metric } from '../../app/types';
 
 const KNOWN_RATINGS = ['sqale_rating', 'reliability_rating', 'security_rating'];
 
-export interface MeasureIntern {
-  value?: string;
-  periods?: Array<{ index: number; value: string }>;
-}
-
-export interface Measure extends MeasureIntern {
-  metric: string;
-}
-
-export interface MeasureEnhanced extends MeasureIntern {
-  metric: { key: string; type: string };
-  leak?: string | undefined | undefined;
-}
-
 export function enhanceMeasure(
   measure: Measure,
   metrics: { [key: string]: Metric }
 ): MeasureEnhanced {
   return {
-    value: measure.value,
-    periods: measure.periods,
+    ...measure,
     metric: metrics[measure.metric],
     leak: getLeakValue(measure)
   };
index 522bffcc922b0799c7837fbf946b62f5473d2f11..df95089855fa93ecbcb73c946a930e9cfaa15b0f 100644 (file)
@@ -153,18 +153,21 @@ export function getLocalizedDashboardName(baseName: string) {
 }
 
 export function getLocalizedMetricName(
-  metric: { key: string; name: string },
+  metric: { key: string; name?: string },
   short?: boolean
 ): string {
   const bundleKey = `metric.${metric.key}.${short ? 'short_name' : 'name'}`;
   const fromBundle = translate(bundleKey);
   if (fromBundle === bundleKey) {
-    return short ? getLocalizedMetricName(metric) : metric.name;
+    if (short) {
+      return getLocalizedMetricName(metric);
+    }
+    return metric.name || metric.key;
   }
   return fromBundle;
 }
 
-export function getLocalizedCategoryMetricName(metric: { key: string; name: string }) {
+export function getLocalizedCategoryMetricName(metric: { key: string; name?: string }) {
   const bundleKey = `metric.${metric.key}.extra_short_name`;
   const fromBundle = translate(bundleKey);
   return fromBundle === bundleKey ? getLocalizedMetricName(metric, true) : fromBundle;
index a12d45dbd421e38492fb656f037125977455791a..edb05d8ce851f5e8d28a9947aa71cff4bd443dc8 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { translate, translateWithParameters, getCurrentLocale } from './l10n';
+import { Metric } from '../app/types';
 
 const HOURS_IN_DAY = 8;
 
-interface Measure {
-  metric: string;
-  periods?: any[];
+export interface MeasurePeriod {
+  index: number;
+  value: string;
 }
 
-interface EnhancedMeasure {
-  metric: Metric;
+export interface MeasureIntern {
+  value?: string;
+  periods?: MeasurePeriod[];
+}
+
+export interface Measure extends MeasureIntern {
+  metric: string;
 }
 
-interface Metric {
-  key: string;
+export interface MeasureEnhanced extends MeasureIntern {
+  metric: Metric;
+  leak?: string;
 }
 
 interface Formatter {
@@ -76,7 +83,7 @@ export function getShortType(type: string): string {
 export function enhanceMeasuresWithMetrics(
   measures: Measure[],
   metrics: Metric[]
-): EnhancedMeasure[] {
+): MeasureEnhanced[] {
   return measures.map(measure => {
     const metric = metrics.find(metric => metric.key === measure.metric) as Metric;
     return { ...measure, metric };
index 53a5435256d6f4198b445c8a697d8bcc02356b58..110eb67cf2addf84c6f18497ca3c58f380be9060 100644 (file)
@@ -20,7 +20,7 @@
 import { translate, translateWithParameters } from './l10n';
 import { parseDate } from './dates';
 
-interface Period {
+export interface Period {
   date: string;
   index: number;
   mode: string;