]> source.dussan.org Git - sonarqube.git/commitdiff
rewrite about app in ts
authorStas Vilchik <stas.vilchik@sonarsource.com>
Thu, 20 Sep 2018 09:44:42 +0000 (11:44 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 21 Sep 2018 18:20:55 +0000 (20:20 +0200)
26 files changed:
server/sonar-web/src/main/js/apps/about/actions.js [deleted file]
server/sonar-web/src/main/js/apps/about/actions.ts [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutApp.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutLanguages.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutProjects.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutProjects.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutScanners.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutScanners.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutStandards.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/AboutStandards.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/ReadMore.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/ReadMore.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/store/values/actions.js [deleted file]
server/sonar-web/src/main/js/apps/settings/store/values/actions.ts [new file with mode: 0644]

diff --git a/server/sonar-web/src/main/js/apps/about/actions.js b/server/sonar-web/src/main/js/apps/about/actions.js
deleted file mode 100644 (file)
index a60d730..0000000
+++ /dev/null
@@ -1,29 +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 { getValues } from '../../api/settings';
-import { receiveValues } from '../settings/store/values/actions';
-
-export const fetchAboutPageSettings = () => dispatch => {
-  const keys = ['sonar.lf.aboutText'];
-
-  return getValues({ keys: keys.join() }).then(values => {
-    dispatch(receiveValues(values));
-  });
-};
diff --git a/server/sonar-web/src/main/js/apps/about/actions.ts b/server/sonar-web/src/main/js/apps/about/actions.ts
new file mode 100644 (file)
index 0000000..515d951
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 { Dispatch } from 'redux';
+import { getValues } from '../../api/settings';
+import { receiveValues } from '../settings/store/values/actions';
+import { Store } from '../../store/rootReducer';
+
+export const fetchAboutPageSettings = () => (dispatch: Dispatch<Store>) => {
+  const keys = ['sonar.lf.aboutText'];
+
+  return getValues({ keys: keys.join() }).then(values => {
+    dispatch(receiveValues(values));
+  });
+};
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js
deleted file mode 100644 (file)
index 941db10..0000000
+++ /dev/null
@@ -1,227 +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 { connect } from 'react-redux';
-import { keyBy } from 'lodash';
-import { Link } from 'react-router';
-import AboutProjects from './AboutProjects';
-import EntryIssueTypes from './EntryIssueTypes';
-import AboutLanguages from './AboutLanguages';
-import AboutCleanCode from './AboutCleanCode';
-import AboutQualityModel from './AboutQualityModel';
-import AboutQualityGates from './AboutQualityGates';
-import AboutLeakPeriod from './AboutLeakPeriod';
-import AboutStandards from './AboutStandards';
-import AboutScanners from './AboutScanners';
-import { searchProjects } from '../../../api/components';
-import { getFacet } from '../../../api/issues';
-import GlobalContainer from '../../../app/components/GlobalContainer';
-import { getAppState, getCurrentUser, getGlobalSettingValue } from '../../../store/rootReducer';
-import { translate } from '../../../helpers/l10n';
-import { fetchAboutPageSettings } from '../actions';
-import { isSonarCloud } from '../../../helpers/system';
-import { IssueType } from '../../../app/types';
-import '../styles.css';
-
-/*::
-type State = {
-  loading: boolean,
-  projectsCount: number,
-  issueTypes?: {
-    [key: string]: ?{
-      count: number
-    }
-  }
-};
-*/
-
-class AboutApp extends React.PureComponent {
-  /*:: mounted: boolean; */
-
-  /*:: props: {
-    appState: {
-      defaultOrganization: string,
-      organizationsEnabled: boolean
-    },
-    currentUser: { isLoggedIn: boolean },
-    customText?: string,
-    fetchAboutPageSettings: () => Promise<*>,
-    location: { pathname: string }
-  };
-*/
-
-  state /*: State */ = {
-    loading: true,
-    projectsCount: 0
-  };
-
-  componentDidMount() {
-    this.mounted = true;
-    if (isSonarCloud()) {
-      window.location = 'https://about.sonarcloud.io';
-    } else {
-      this.loadData();
-      // $FlowFixMe
-      document.body.classList.add('white-page');
-      // $FlowFixMe
-      document.documentElement.classList.add('white-page');
-    }
-  }
-
-  componentWillUnmount() {
-    this.mounted = false;
-    // $FlowFixMe
-    document.body.classList.remove('white-page');
-    // $FlowFixMe
-    document.documentElement.classList.remove('white-page');
-  }
-
-  loadProjects() {
-    return searchProjects({ ps: 1 }).then(r => r.paging.total);
-  }
-
-  loadIssues() {
-    return getFacet({ resolved: false }, 'types');
-  }
-
-  loadCustomText() {
-    return this.props.fetchAboutPageSettings();
-  }
-
-  loadData() {
-    Promise.all([this.loadProjects(), this.loadIssues(), this.loadCustomText()]).then(
-      responses => {
-        if (this.mounted) {
-          const [projectsCount, issues] = responses;
-          const issueTypes = keyBy(issues.facet, 'val');
-          this.setState({
-            projectsCount,
-            issueTypes,
-            loading: false
-          });
-        }
-      },
-      () => {
-        if (this.mounted) {
-          this.setState({ loading: false });
-        }
-      }
-    );
-  }
-
-  render() {
-    const { customText } = this.props;
-    const { loading, issueTypes, projectsCount } = this.state;
-
-    if (isSonarCloud()) {
-      return null;
-    }
-
-    let bugs;
-    let vulnerabilities;
-    let codeSmells;
-    if (!loading && issueTypes) {
-      bugs = issueTypes[IssueType.Bug] && issueTypes[IssueType.Bug].count;
-      vulnerabilities =
-        issueTypes[IssueType.Vulnerability] && issueTypes[IssueType.Vulnerability].count;
-      codeSmells = issueTypes[IssueType.CodeSmell] && issueTypes[IssueType.CodeSmell].count;
-    }
-
-    return (
-      <GlobalContainer location={this.props.location}>
-        <div className="page page-limited about-page" id="about-page">
-          <div className="about-page-entry">
-            <div className="about-page-intro">
-              <h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1>
-              {!this.props.currentUser.isLoggedIn && (
-                <Link className="button button-active big-spacer-right" to="/sessions/new">
-                  {translate('layout.login')}
-                </Link>
-              )}
-              <a
-                className="button"
-                href="https://redirect.sonarsource.com/doc/home.html"
-                rel="noopener noreferrer"
-                target="_blank">
-                {translate('about_page.read_documentation')}
-              </a>
-            </div>
-
-            <div className="about-page-instance">
-              <AboutProjects count={projectsCount} loading={loading} />
-              <EntryIssueTypes
-                bugs={bugs}
-                codeSmells={codeSmells}
-                loading={loading}
-                vulnerabilities={vulnerabilities}
-              />
-            </div>
-          </div>
-
-          {customText != null &&
-            customText.value && (
-              <div
-                className="about-page-section"
-                dangerouslySetInnerHTML={{ __html: customText.value }}
-              />
-            )}
-
-          <AboutLanguages />
-
-          <AboutQualityModel />
-
-          <div className="flex-columns">
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutCleanCode />
-            </div>
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutLeakPeriod />
-            </div>
-          </div>
-
-          <div className="flex-columns">
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutQualityGates />
-            </div>
-            <div className="flex-column flex-column-half about-page-group-boxes">
-              <AboutStandards appState={this.props.appState} />
-            </div>
-          </div>
-
-          <AboutScanners />
-        </div>
-      </GlobalContainer>
-    );
-  }
-}
-
-const mapStateToProps = state => ({
-  appState: getAppState(state),
-  currentUser: getCurrentUser(state),
-  customText: getGlobalSettingValue(state, 'sonar.lf.aboutText')
-});
-
-const mapDispatchToProps = { fetchAboutPageSettings };
-
-export default connect(
-  mapStateToProps,
-  mapDispatchToProps
-)(AboutApp);
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutApp.tsx
new file mode 100644 (file)
index 0000000..40737d5
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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 * as React from 'react';
+import { connect } from 'react-redux';
+import { keyBy } from 'lodash';
+import { Link } from 'react-router';
+import { Location } from 'history';
+import AboutProjects from './AboutProjects';
+import EntryIssueTypes from './EntryIssueTypes';
+import AboutLanguages from './AboutLanguages';
+import AboutCleanCode from './AboutCleanCode';
+import AboutQualityModel from './AboutQualityModel';
+import AboutQualityGates from './AboutQualityGates';
+import AboutLeakPeriod from './AboutLeakPeriod';
+import AboutStandards from './AboutStandards';
+import AboutScanners from './AboutScanners';
+import { searchProjects } from '../../../api/components';
+import { getFacet } from '../../../api/issues';
+import GlobalContainer from '../../../app/components/GlobalContainer';
+import {
+  getAppState,
+  getCurrentUser,
+  getGlobalSettingValue,
+  Store
+} from '../../../store/rootReducer';
+import { translate } from '../../../helpers/l10n';
+import { fetchAboutPageSettings } from '../actions';
+import { IssueType, AppState, CurrentUser } from '../../../app/types';
+import '../styles.css';
+
+interface Props {
+  appState: Pick<AppState, 'defaultOrganization' | 'organizationsEnabled'>;
+  currentUser: CurrentUser;
+  customText?: { value: string };
+  fetchAboutPageSettings: () => Promise<void>;
+  location: Location;
+}
+
+interface State {
+  issueTypes?: { [key: string]: { count: number } };
+  loading: boolean;
+  projectsCount: number;
+}
+
+class AboutApp extends React.PureComponent<Props, State> {
+  mounted = false;
+
+  state: State = {
+    loading: true,
+    projectsCount: 0
+  };
+
+  componentDidMount() {
+    this.mounted = true;
+    this.loadData();
+    document.body.classList.add('white-page');
+    document.documentElement.classList.add('white-page');
+  }
+
+  componentWillUnmount() {
+    this.mounted = false;
+    document.body.classList.remove('white-page');
+    document.documentElement.classList.remove('white-page');
+  }
+
+  loadProjects() {
+    return searchProjects({ ps: 1 }).then(r => r.paging.total);
+  }
+
+  loadIssues() {
+    return getFacet({ resolved: false }, 'types');
+  }
+
+  loadCustomText() {
+    return this.props.fetchAboutPageSettings();
+  }
+
+  loadData() {
+    Promise.all([this.loadProjects(), this.loadIssues(), this.loadCustomText()]).then(
+      responses => {
+        if (this.mounted) {
+          const [projectsCount, issues] = responses;
+          const issueTypes = keyBy(issues.facet, 'val');
+          this.setState({ projectsCount, issueTypes, loading: false });
+        }
+      },
+      () => {
+        if (this.mounted) {
+          this.setState({ loading: false });
+        }
+      }
+    );
+  }
+
+  render() {
+    const { customText } = this.props;
+    const { loading, issueTypes, projectsCount } = this.state;
+
+    let bugs;
+    let vulnerabilities;
+    let codeSmells;
+    if (!loading && issueTypes) {
+      bugs = issueTypes[IssueType.Bug] && issueTypes[IssueType.Bug].count;
+      vulnerabilities =
+        issueTypes[IssueType.Vulnerability] && issueTypes[IssueType.Vulnerability].count;
+      codeSmells = issueTypes[IssueType.CodeSmell] && issueTypes[IssueType.CodeSmell].count;
+    }
+
+    return (
+      <GlobalContainer location={this.props.location}>
+        <div className="page page-limited about-page" id="about-page">
+          <div className="about-page-entry">
+            <div className="about-page-intro">
+              <h1 className="big-spacer-bottom">{translate('layout.sonar.slogan')}</h1>
+              {!this.props.currentUser.isLoggedIn && (
+                <Link className="button button-active big-spacer-right" to="/sessions/new">
+                  {translate('layout.login')}
+                </Link>
+              )}
+              <a
+                className="button"
+                href="https://redirect.sonarsource.com/doc/home.html"
+                rel="noopener noreferrer"
+                target="_blank">
+                {translate('about_page.read_documentation')}
+              </a>
+            </div>
+
+            <div className="about-page-instance">
+              <AboutProjects count={projectsCount} loading={loading} />
+              <EntryIssueTypes
+                bugs={bugs}
+                codeSmells={codeSmells}
+                loading={loading}
+                vulnerabilities={vulnerabilities}
+              />
+            </div>
+          </div>
+
+          {customText != null &&
+            customText.value && (
+              <div
+                className="about-page-section"
+                dangerouslySetInnerHTML={{ __html: customText.value }}
+              />
+            )}
+
+          <AboutLanguages />
+
+          <AboutQualityModel />
+
+          <div className="flex-columns">
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutCleanCode />
+            </div>
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutLeakPeriod />
+            </div>
+          </div>
+
+          <div className="flex-columns">
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutQualityGates />
+            </div>
+            <div className="flex-column flex-column-half about-page-group-boxes">
+              <AboutStandards appState={this.props.appState} />
+            </div>
+          </div>
+
+          <AboutScanners />
+        </div>
+      </GlobalContainer>
+    );
+  }
+}
+
+const mapStateToProps = (state: Store) => ({
+  appState: getAppState(state),
+  currentUser: getCurrentUser(state),
+  customText: getGlobalSettingValue(state, 'sonar.lf.aboutText')
+});
+
+const mapDispatchToProps = { fetchAboutPageSettings } as any;
+
+export default connect(
+  mapStateToProps,
+  mapDispatchToProps
+)(AboutApp);
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js
deleted file mode 100644 (file)
index c98cd4e..0000000
+++ /dev/null
@@ -1,36 +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 ReadMore from './ReadMore';
-import { translate } from '../../../helpers/l10n';
-
-const link = 'https://redirect.sonarsource.com/doc/issues.html';
-
-export default function AboutCleanCode() {
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.clean_code')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.clean_code.text')}</p>
-        <ReadMore link={link} />
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.tsx
new file mode 100644 (file)
index 0000000..29ad172
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 * as React from 'react';
+import ReadMore from './ReadMore';
+import { translate } from '../../../helpers/l10n';
+
+const link = 'https://redirect.sonarsource.com/doc/issues.html';
+
+export default function AboutCleanCode() {
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.clean_code')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.clean_code.text')}</p>
+        <ReadMore link={link} />
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js
deleted file mode 100644 (file)
index 1fecd6d..0000000
+++ /dev/null
@@ -1,70 +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 { translate } from '../../../helpers/l10n';
-
-const languages = [
-  { name: 'Java', url: 'https://redirect.sonarsource.com/plugins/java.html' },
-  { name: 'C/C++', url: 'https://redirect.sonarsource.com/plugins/cpp.html' },
-  { name: 'C#', url: 'https://redirect.sonarsource.com/plugins/csharp.html' },
-  { name: 'COBOL', url: 'https://redirect.sonarsource.com/plugins/cobol.html' },
-  { name: 'ABAP', url: 'https://redirect.sonarsource.com/plugins/abap.html' },
-  { name: 'HTML', url: 'https://redirect.sonarsource.com/plugins/web.html' },
-  { name: 'RPG', url: 'https://redirect.sonarsource.com/plugins/rpg.html' },
-  { name: 'JavaScript', url: 'https://redirect.sonarsource.com/plugins/javascript.html' },
-  { name: 'TypeScript', url: 'https://redirect.sonarsource.com/plugins/typescript.html' },
-  { name: 'Objective C', url: 'https://redirect.sonarsource.com/plugins/objectivec.html' },
-  { name: 'XML', url: 'https://redirect.sonarsource.com/plugins/xml.html' },
-  { name: 'VB.NET', url: 'https://redirect.sonarsource.com/plugins/vbnet.html' },
-  { name: 'PL/SQL', url: 'https://redirect.sonarsource.com/plugins/plsql.html' },
-  { name: 'T-SQL', url: 'https://redirect.sonarsource.com/plugins/tsql.html' },
-  { name: 'Flex', url: 'https://redirect.sonarsource.com/plugins/flex.html' },
-  { name: 'Python', url: 'https://redirect.sonarsource.com/plugins/python.html' },
-  { name: 'Groovy', url: 'https://redirect.sonarsource.com/plugins/groovy.html' },
-  { name: 'PHP', url: 'https://redirect.sonarsource.com/plugins/php.html' },
-  { name: 'Swift', url: 'https://redirect.sonarsource.com/plugins/swift.html' },
-  { name: 'Visual Basic', url: 'https://redirect.sonarsource.com/plugins/vb.html' },
-  { name: 'PL/I', url: 'https://redirect.sonarsource.com/plugins/pli.html' }
-];
-
-const half = (languages.length + 1) / 2;
-
-export default function AboutLanguages() {
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.languages')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.languages.text')}</p>
-        <ul className="about-page-languages">
-          {languages.slice(0, half).map((language, index) => (
-            <li key={index}>
-              <a href={languages[index].url}>{languages[index].name}</a>
-              <br />
-              {index + half < languages.length && (
-                <a href={languages[index + half].url}>{languages[index + half].name}</a>
-              )}
-            </li>
-          ))}
-        </ul>
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.tsx
new file mode 100644 (file)
index 0000000..d770ba0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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 * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+
+const languages = [
+  { name: 'Java', url: 'https://redirect.sonarsource.com/plugins/java.html' },
+  { name: 'C/C++', url: 'https://redirect.sonarsource.com/plugins/cpp.html' },
+  { name: 'C#', url: 'https://redirect.sonarsource.com/plugins/csharp.html' },
+  { name: 'COBOL', url: 'https://redirect.sonarsource.com/plugins/cobol.html' },
+  { name: 'ABAP', url: 'https://redirect.sonarsource.com/plugins/abap.html' },
+  { name: 'HTML', url: 'https://redirect.sonarsource.com/plugins/web.html' },
+  { name: 'RPG', url: 'https://redirect.sonarsource.com/plugins/rpg.html' },
+  { name: 'JavaScript', url: 'https://redirect.sonarsource.com/plugins/javascript.html' },
+  { name: 'TypeScript', url: 'https://redirect.sonarsource.com/plugins/typescript.html' },
+  { name: 'Objective C', url: 'https://redirect.sonarsource.com/plugins/objectivec.html' },
+  { name: 'XML', url: 'https://redirect.sonarsource.com/plugins/xml.html' },
+  { name: 'VB.NET', url: 'https://redirect.sonarsource.com/plugins/vbnet.html' },
+  { name: 'PL/SQL', url: 'https://redirect.sonarsource.com/plugins/plsql.html' },
+  { name: 'T-SQL', url: 'https://redirect.sonarsource.com/plugins/tsql.html' },
+  { name: 'Flex', url: 'https://redirect.sonarsource.com/plugins/flex.html' },
+  { name: 'Python', url: 'https://redirect.sonarsource.com/plugins/python.html' },
+  { name: 'Groovy', url: 'https://redirect.sonarsource.com/plugins/groovy.html' },
+  { name: 'PHP', url: 'https://redirect.sonarsource.com/plugins/php.html' },
+  { name: 'Swift', url: 'https://redirect.sonarsource.com/plugins/swift.html' },
+  { name: 'Visual Basic', url: 'https://redirect.sonarsource.com/plugins/vb.html' },
+  { name: 'PL/I', url: 'https://redirect.sonarsource.com/plugins/pli.html' }
+];
+
+const half = (languages.length + 1) / 2;
+
+export default function AboutLanguages() {
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.languages')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.languages.text')}</p>
+        <ul className="about-page-languages">
+          {languages.slice(0, half).map((language, index) => (
+            <li key={index}>
+              <a href={language.url}>{language.name}</a>
+              <br />
+              {index + half < languages.length && (
+                <a href={languages[index + half].url}>{languages[index + half].name}</a>
+              )}
+            </li>
+          ))}
+        </ul>
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js
deleted file mode 100644 (file)
index 203a285..0000000
+++ /dev/null
@@ -1,36 +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 ReadMore from './ReadMore';
-import { translate } from '../../../helpers/l10n';
-
-const link = 'https://redirect.sonarsource.com/doc/fix-the-leak.html';
-
-export default function AboutLeakPeriod() {
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.fix_the_leak')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.fix_the_leak_on_new_code.text')}</p>
-        <ReadMore link={link} />
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.tsx
new file mode 100644 (file)
index 0000000..78c3aaa
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 * as React from 'react';
+import ReadMore from './ReadMore';
+import { translate } from '../../../helpers/l10n';
+
+const link = 'https://redirect.sonarsource.com/doc/fix-the-leak.html';
+
+export default function AboutLeakPeriod() {
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.fix_the_leak')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.fix_the_leak_on_new_code.text')}</p>
+        <ReadMore link={link} />
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js
deleted file mode 100644 (file)
index ded5a77..0000000
+++ /dev/null
@@ -1,49 +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 { Link } from 'react-router';
-import { formatMeasure } from '../../../helpers/measures';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {
-  count: number,
-  loading: boolean
-};
-*/
-
-export default function AboutProjects({ count, loading } /*: Props */) {
-  return (
-    <div className="about-page-projects">
-      {loading && <i className="spinner" />}
-      {!loading && (
-        <div>
-          <div>
-            <Link className="about-page-projects-link" to="/projects">
-              {formatMeasure(count, 'INT')}
-            </Link>
-          </div>
-          <div>{translate('about_page.projects_analyzed')}</div>
-        </div>
-      )}
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.tsx
new file mode 100644 (file)
index 0000000..81e8065
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 * as React from 'react';
+import { Link } from 'react-router';
+import { formatMeasure } from '../../../helpers/measures';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+  count: number;
+  loading: boolean;
+}
+
+export default function AboutProjects({ count, loading }: Props) {
+  return (
+    <div className="about-page-projects">
+      {loading ? (
+        <i className="spinner" />
+      ) : (
+        <div>
+          <div>
+            <Link className="about-page-projects-link" to="/projects">
+              {formatMeasure(count, 'INT')}
+            </Link>
+          </div>
+          <div>{translate('about_page.projects_analyzed')}</div>
+        </div>
+      )}
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js
deleted file mode 100644 (file)
index 2af9841..0000000
+++ /dev/null
@@ -1,36 +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 ReadMore from './ReadMore';
-import { translate } from '../../../helpers/l10n';
-
-const link = 'https://redirect.sonarsource.com/doc/quality-gates.html';
-
-export default function AboutQualityGates() {
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.quality_gates')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.quality_gates.text')}</p>
-        <ReadMore link={link} />
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.tsx
new file mode 100644 (file)
index 0000000..d89d581
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 * as React from 'react';
+import ReadMore from './ReadMore';
+import { translate } from '../../../helpers/l10n';
+
+const link = 'https://redirect.sonarsource.com/doc/quality-gates.html';
+
+export default function AboutQualityGates() {
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.quality_gates')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.quality_gates.text')}</p>
+        <ReadMore link={link} />
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js
deleted file mode 100644 (file)
index a1fa080..0000000
+++ /dev/null
@@ -1,66 +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 { translate } from '../../../helpers/l10n';
-import BugIcon from '../../../components/icons-components/BugIcon';
-import VulnerabilityIcon from '../../../components/icons-components/VulnerabilityIcon';
-import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
-
-export default function AboutQualityModel() {
-  return (
-    <div className="boxed-group about-quality-model">
-      <h2>{translate('about_page.quality_model')}</h2>
-
-      <div className="boxed-group-inner clearfix">
-        <div className="flex-columns">
-          <div className="flex-column flex-column-third">
-            <div className="pull-left little-spacer-right">
-              <BugIcon />
-            </div>
-            <p className="about-page-text overflow-hidden">
-              <strong>{translate('issue.type.BUG.plural')}</strong>{' '}
-              {translate('about_page.quality_model.bugs')}
-            </p>
-          </div>
-
-          <div className="flex-column flex-column-third">
-            <div className="pull-left little-spacer-right">
-              <VulnerabilityIcon />
-            </div>
-            <p className="about-page-text overflow-hidden">
-              <strong>{translate('issue.type.VULNERABILITY.plural')}</strong>{' '}
-              {translate('about_page.quality_model.vulnerabilities')}
-            </p>
-          </div>
-
-          <div className="flex-column flex-column-third">
-            <div className="pull-left little-spacer-right">
-              <CodeSmellIcon />
-            </div>
-            <p className="about-page-text overflow-hidden">
-              <strong>{translate('issue.type.CODE_SMELL.plural')}</strong>{' '}
-              {translate('about_page.quality_model.code_smells')}
-            </p>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.tsx
new file mode 100644 (file)
index 0000000..322ae44
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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 * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+import BugIcon from '../../../components/icons-components/BugIcon';
+import VulnerabilityIcon from '../../../components/icons-components/VulnerabilityIcon';
+import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
+
+export default function AboutQualityModel() {
+  return (
+    <div className="boxed-group about-quality-model">
+      <h2>{translate('about_page.quality_model')}</h2>
+
+      <div className="boxed-group-inner clearfix">
+        <div className="flex-columns">
+          <div className="flex-column flex-column-third">
+            <div className="pull-left little-spacer-right">
+              <BugIcon />
+            </div>
+            <p className="about-page-text overflow-hidden">
+              <strong>{translate('issue.type.BUG.plural')}</strong>{' '}
+              {translate('about_page.quality_model.bugs')}
+            </p>
+          </div>
+
+          <div className="flex-column flex-column-third">
+            <div className="pull-left little-spacer-right">
+              <VulnerabilityIcon />
+            </div>
+            <p className="about-page-text overflow-hidden">
+              <strong>{translate('issue.type.VULNERABILITY.plural')}</strong>{' '}
+              {translate('about_page.quality_model.vulnerabilities')}
+            </p>
+          </div>
+
+          <div className="flex-column flex-column-third">
+            <div className="pull-left little-spacer-right">
+              <CodeSmellIcon />
+            </div>
+            <p className="about-page-text overflow-hidden">
+              <strong>{translate('issue.type.CODE_SMELL.plural')}</strong>{' '}
+              {translate('about_page.quality_model.code_smells')}
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js
deleted file mode 100644 (file)
index 42ad663..0000000
+++ /dev/null
@@ -1,70 +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 { translate } from '../../../helpers/l10n';
-
-const scanners = [
-  {
-    key: 'sonarqube',
-    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner.html'
-  },
-  {
-    key: 'msbuild',
-    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html'
-  },
-  {
-    key: 'maven',
-    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-maven.html'
-  },
-  {
-    key: 'gradle',
-    link: 'https://redirect.sonarsource.com/doc/gradle.html'
-  },
-  {
-    key: 'jenkins',
-    link: 'https://redirect.sonarsource.com/plugins/jenkins.html'
-  },
-  {
-    key: 'ant',
-    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-ant.html'
-  }
-];
-
-export default function AboutScanners() {
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.scanners')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.scanners.text')}</p>
-        <div className="about-page-analyzers">
-          {scanners.map(scanner => (
-            <a className="about-page-analyzer-box" href={scanner.link} key={scanner.key}>
-              <img
-                alt={translate('about_page.scanners', scanner.key)}
-                height={60}
-                src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`}
-              />
-            </a>
-          ))}
-        </div>
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.tsx
new file mode 100644 (file)
index 0000000..b6f500b
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+import { getBaseUrl } from '../../../helpers/urls';
+
+const scanners = [
+  {
+    key: 'sonarqube',
+    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner.html'
+  },
+  {
+    key: 'msbuild',
+    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html'
+  },
+  {
+    key: 'maven',
+    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-maven.html'
+  },
+  {
+    key: 'gradle',
+    link: 'https://redirect.sonarsource.com/doc/gradle.html'
+  },
+  {
+    key: 'jenkins',
+    link: 'https://redirect.sonarsource.com/plugins/jenkins.html'
+  },
+  {
+    key: 'ant',
+    link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-ant.html'
+  }
+];
+
+export default function AboutScanners() {
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.scanners')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.scanners.text')}</p>
+        <div className="about-page-analyzers">
+          {scanners.map(scanner => (
+            <a className="about-page-analyzer-box" href={scanner.link} key={scanner.key}>
+              <img
+                alt={translate('about_page.scanners', scanner.key)}
+                height={60}
+                src={`${getBaseUrl()}/images/scanner-logos/${scanner.key}.svg`}
+              />
+            </a>
+          ))}
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js
deleted file mode 100644 (file)
index b4624dc..0000000
+++ /dev/null
@@ -1,92 +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 { Link } from 'react-router';
-import ReadMore from './ReadMore';
-import TagsIcon from '../../../components/icons-components/TagsIcon';
-import { translate } from '../../../helpers/l10n';
-import { getRulesUrl } from '../../../helpers/urls';
-
-const link = 'https://redirect.sonarsource.com/doc/rules.html';
-
-const owaspTags =
-  'owasp-a1,owasp-a2,owasp-a3,owasp-a4,owasp-a5,owasp-a6,owasp-a7,owasp-a8,owasp-a9,owasp-a10';
-const sans25Tags = 'sans-top25-porous,sans-top25-risky,sans-top25-insecure';
-
-/*::
-type Props = {
-  appState: {
-    defaultOrganization: string,
-    organizationsEnabled: boolean
-  }
-};
-*/
-
-export default function AboutStandards(props /*: Props */) {
-  const organization = props.appState.organizationsEnabled
-    ? props.appState.defaultOrganization
-    : undefined;
-
-  return (
-    <div className="boxed-group">
-      <h2>{translate('about_page.standards')}</h2>
-      <div className="boxed-group-inner">
-        <p className="about-page-text">{translate('about_page.standards.text')}</p>
-
-        <div className="spacer-top">
-          <ul className="list-inline">
-            <li>
-              <Link className="link-with-icon" to={getRulesUrl({ tags: 'misra' }, organization)}>
-                <TagsIcon />
-                <span className="little-spacer-left">MISRA</span>
-              </Link>
-            </li>
-            <li>
-              <Link className="link-with-icon" to={getRulesUrl({ tags: 'cert' }, organization)}>
-                <TagsIcon />
-                <span className="little-spacer-left">CERT</span>
-              </Link>
-            </li>
-            <li>
-              <Link className="link-with-icon" to={getRulesUrl({ tags: 'cwe' }, organization)}>
-                <TagsIcon />
-                <span className="little-spacer-left">CWE</span>
-              </Link>
-            </li>
-            <li>
-              <Link className="link-with-icon" to={getRulesUrl({ tags: owaspTags }, organization)}>
-                <TagsIcon />
-                <span className="little-spacer-left">OWASP Top 10</span>
-              </Link>
-            </li>
-            <li>
-              <Link className="link-with-icon" to={getRulesUrl({ tags: sans25Tags }, organization)}>
-                <TagsIcon />
-                <span className="little-spacer-left">SANS Top 25</span>
-              </Link>
-            </li>
-          </ul>
-        </div>
-
-        <ReadMore link={link} />
-      </div>
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutStandards.tsx b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.tsx
new file mode 100644 (file)
index 0000000..07d5818
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 * as React from 'react';
+import { Link } from 'react-router';
+import ReadMore from './ReadMore';
+import TagsIcon from '../../../components/icons-components/TagsIcon';
+import { translate } from '../../../helpers/l10n';
+import { getRulesUrl } from '../../../helpers/urls';
+import { AppState } from '../../../app/types';
+
+const link = 'https://redirect.sonarsource.com/doc/rules.html';
+
+const owaspTags =
+  'owasp-a1,owasp-a2,owasp-a3,owasp-a4,owasp-a5,owasp-a6,owasp-a7,owasp-a8,owasp-a9,owasp-a10';
+const sans25Tags = 'sans-top25-porous,sans-top25-risky,sans-top25-insecure';
+
+interface Props {
+  appState: Pick<AppState, 'defaultOrganization' | 'organizationsEnabled'>;
+}
+
+export default function AboutStandards({ appState }: Props) {
+  const organization = appState.organizationsEnabled ? appState.defaultOrganization : undefined;
+
+  return (
+    <div className="boxed-group">
+      <h2>{translate('about_page.standards')}</h2>
+      <div className="boxed-group-inner">
+        <p className="about-page-text">{translate('about_page.standards.text')}</p>
+
+        <div className="spacer-top">
+          <ul className="list-inline">
+            <li>
+              <Link className="link-with-icon" to={getRulesUrl({ tags: 'misra' }, organization)}>
+                <TagsIcon />
+                <span className="little-spacer-left">MISRA</span>
+              </Link>
+            </li>
+            <li>
+              <Link className="link-with-icon" to={getRulesUrl({ tags: 'cert' }, organization)}>
+                <TagsIcon />
+                <span className="little-spacer-left">CERT</span>
+              </Link>
+            </li>
+            <li>
+              <Link className="link-with-icon" to={getRulesUrl({ tags: 'cwe' }, organization)}>
+                <TagsIcon />
+                <span className="little-spacer-left">CWE</span>
+              </Link>
+            </li>
+            <li>
+              <Link className="link-with-icon" to={getRulesUrl({ tags: owaspTags }, organization)}>
+                <TagsIcon />
+                <span className="little-spacer-left">OWASP Top 10</span>
+              </Link>
+            </li>
+            <li>
+              <Link className="link-with-icon" to={getRulesUrl({ tags: sans25Tags }, organization)}>
+                <TagsIcon />
+                <span className="little-spacer-left">SANS Top 25</span>
+              </Link>
+            </li>
+          </ul>
+        </div>
+
+        <ReadMore link={link} />
+      </div>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js
deleted file mode 100644 (file)
index b658477..0000000
+++ /dev/null
@@ -1,111 +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 { Link } from 'react-router';
-import { formatMeasure } from '../../../helpers/measures';
-import { translate } from '../../../helpers/l10n';
-import { getIssuesUrl } from '../../../helpers/urls';
-import BugIcon from '../../../components/icons-components/BugIcon';
-import VulnerabilityIcon from '../../../components/icons-components/VulnerabilityIcon';
-import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
-import { IssueType } from '../../../app/types';
-
-/*::
-type Props = {
-  bugs: ?number,
-  codeSmells: ?number,
-  loading: boolean,
-  vulnerabilities: ?number
-};
-*/
-
-export default function EntryIssueTypes(
-  { bugs, codeSmells, loading, vulnerabilities } /*: Props */
-) {
-  return (
-    <div className="about-page-projects">
-      {loading && <i className="spinner" />}
-      {!loading && (
-        <table className="about-page-issue-types">
-          <tbody>
-            <tr>
-              <td className="about-page-issue-type-number">
-                <Link
-                  className="about-page-issue-type-link"
-                  to={getIssuesUrl({
-                    resolved: 'false',
-                    types: IssueType.Bug,
-                    s: 'CREATION_DATE'
-                  })}>
-                  {formatMeasure(bugs, 'SHORT_INT')}
-                </Link>
-              </td>
-              <td>
-                <span className="little-spacer-right">
-                  <BugIcon />
-                </span>
-                {translate('issue.type.BUG.plural')}
-              </td>
-            </tr>
-            <tr>
-              <td className="about-page-issue-type-number">
-                <Link
-                  className="about-page-issue-type-link"
-                  to={getIssuesUrl({
-                    resolved: 'false',
-                    types: IssueType.Vulnerability,
-                    s: 'CREATION_DATE'
-                  })}>
-                  {formatMeasure(vulnerabilities, 'SHORT_INT')}
-                </Link>
-              </td>
-              <td>
-                <span className="little-spacer-right">
-                  <VulnerabilityIcon />
-                </span>
-                {translate('issue.type.VULNERABILITY.plural')}
-              </td>
-            </tr>
-            <tr>
-              <td className="about-page-issue-type-number">
-                <Link
-                  className="about-page-issue-type-link"
-                  to={getIssuesUrl({
-                    resolved: 'false',
-                    types: IssueType.CodeSmell,
-                    s: 'CREATION_DATE'
-                  })}>
-                  {formatMeasure(codeSmells, 'SHORT_INT')}
-                </Link>
-              </td>
-              <td>
-                <span className="little-spacer-right">
-                  <CodeSmellIcon />
-                </span>
-                {translate('issue.type.CODE_SMELL.plural')}
-              </td>
-            </tr>
-          </tbody>
-        </table>
-      )}
-    </div>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.tsx b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.tsx
new file mode 100644 (file)
index 0000000..5361e0e
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 * as React from 'react';
+import { Link } from 'react-router';
+import { formatMeasure } from '../../../helpers/measures';
+import { translate } from '../../../helpers/l10n';
+import { getIssuesUrl } from '../../../helpers/urls';
+import BugIcon from '../../../components/icons-components/BugIcon';
+import VulnerabilityIcon from '../../../components/icons-components/VulnerabilityIcon';
+import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
+import { IssueType } from '../../../app/types';
+
+interface Props {
+  bugs?: number;
+  codeSmells?: number;
+  loading: boolean;
+  vulnerabilities?: number;
+}
+
+export default function EntryIssueTypes({ bugs, codeSmells, loading, vulnerabilities }: Props) {
+  return (
+    <div className="about-page-projects">
+      {loading ? (
+        <i className="spinner" />
+      ) : (
+        <table className="about-page-issue-types">
+          <tbody>
+            <tr>
+              <td className="about-page-issue-type-number">
+                <Link
+                  className="about-page-issue-type-link"
+                  to={getIssuesUrl({
+                    resolved: 'false',
+                    types: IssueType.Bug,
+                    s: 'CREATION_DATE'
+                  })}>
+                  {formatMeasure(bugs, 'SHORT_INT')}
+                </Link>
+              </td>
+              <td>
+                <span className="little-spacer-right">
+                  <BugIcon />
+                </span>
+                {translate('issue.type.BUG.plural')}
+              </td>
+            </tr>
+            <tr>
+              <td className="about-page-issue-type-number">
+                <Link
+                  className="about-page-issue-type-link"
+                  to={getIssuesUrl({
+                    resolved: 'false',
+                    types: IssueType.Vulnerability,
+                    s: 'CREATION_DATE'
+                  })}>
+                  {formatMeasure(vulnerabilities, 'SHORT_INT')}
+                </Link>
+              </td>
+              <td>
+                <span className="little-spacer-right">
+                  <VulnerabilityIcon />
+                </span>
+                {translate('issue.type.VULNERABILITY.plural')}
+              </td>
+            </tr>
+            <tr>
+              <td className="about-page-issue-type-number">
+                <Link
+                  className="about-page-issue-type-link"
+                  to={getIssuesUrl({
+                    resolved: 'false',
+                    types: IssueType.CodeSmell,
+                    s: 'CREATION_DATE'
+                  })}>
+                  {formatMeasure(codeSmells, 'SHORT_INT')}
+                </Link>
+              </td>
+              <td>
+                <span className="little-spacer-right">
+                  <CodeSmellIcon />
+                </span>
+                {translate('issue.type.CODE_SMELL.plural')}
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      )}
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/ReadMore.js b/server/sonar-web/src/main/js/apps/about/components/ReadMore.js
deleted file mode 100644 (file)
index 1024c44..0000000
+++ /dev/null
@@ -1,38 +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 PropTypes from 'prop-types';
-import { translate } from '../../../helpers/l10n';
-
-export default class ReadMore extends React.PureComponent {
-  static propTypes = {
-    link: PropTypes.string.isRequired
-  };
-
-  render() {
-    return (
-      <div className="big-spacer-top">
-        <a className="about-page-link-more" href={this.props.link} target="_blank">
-          <span>{translate('about_page.read_more')}</span>
-        </a>
-      </div>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/ReadMore.tsx b/server/sonar-web/src/main/js/apps/about/components/ReadMore.tsx
new file mode 100644 (file)
index 0000000..2abbff2
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+  link: string;
+}
+
+export default function ReadMore({ link }: Props) {
+  return (
+    <div className="big-spacer-top">
+      <a className="about-page-link-more" href={link} rel="noopener noreferrer" target="_blank">
+        <span>{translate('about_page.read_more')}</span>
+      </a>
+    </div>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/store/values/actions.js b/server/sonar-web/src/main/js/apps/settings/store/values/actions.js
deleted file mode 100644 (file)
index 0da9d1b..0000000
+++ /dev/null
@@ -1,34 +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 type { SettingValue } from '../../types'; */
-
-export const RECEIVE_VALUES /*: string */ = 'RECEIVE_VALUES';
-
-/**
- * Receive settings action creator
- * @param {Array} settings
- * @returns {Object}
- */
-export const receiveValues = (settings /*: SettingValue[] */, componentKey /*: ?string */) => ({
-  type: RECEIVE_VALUES,
-  settings,
-  componentKey
-});
diff --git a/server/sonar-web/src/main/js/apps/settings/store/values/actions.ts b/server/sonar-web/src/main/js/apps/settings/store/values/actions.ts
new file mode 100644 (file)
index 0000000..a7d6f8f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+interface SettingValue {
+  key: string;
+  value?: string;
+}
+
+export const RECEIVE_VALUES = 'RECEIVE_VALUES';
+
+export function receiveValues(settings: SettingValue[], componentKey?: string) {
+  return { type: RECEIVE_VALUES, settings, componentKey };
+}