aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2017-08-18 18:53:44 +0200
committerGitHub <noreply@github.com>2017-08-18 18:53:44 +0200
commit7983068e4d2a45531ba0942688e659adf9ee61a2 (patch)
treec481c4ef137cf8b1f4ac69d2917b51317d8c4dad /server/sonar-web/src/main/js/apps
parentf98b26b3f33e0eb2788ca93a4b115585c527c737 (diff)
downloadsonarqube-7983068e4d2a45531ba0942688e659adf9ee61a2.tar.gz
sonarqube-7983068e4d2a45531ba0942688e659adf9ee61a2.zip
translate all routes files to ts (#2378)
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/about/routes.ts (renamed from server/sonar-web/src/main/js/apps/about/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js94
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx94
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/Projects.js67
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/Projects.tsx65
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx (renamed from server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js)34
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/propTypes.js34
-rw-r--r--server/sonar-web/src/main/js/apps/account/projects/types.ts32
-rw-r--r--server/sonar-web/src/main/js/apps/account/routes.ts (renamed from server/sonar-web/src/main/js/apps/account/routes.js)16
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/routes.ts (renamed from server/sonar-web/src/main/js/apps/background-tasks/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/code/routes.ts (renamed from server/sonar-web/src/main/js/apps/code/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/routes.ts (renamed from server/sonar-web/src/main/js/apps/coding-rules/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/routes.ts (renamed from server/sonar-web/src/main/js/apps/component-measures/routes.js)8
-rw-r--r--server/sonar-web/src/main/js/apps/component/components/App.tsx (renamed from server/sonar-web/src/main/js/apps/component/components/App.js)21
-rw-r--r--server/sonar-web/src/main/js/apps/component/routes.ts (renamed from server/sonar-web/src/main/js/apps/component/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/custom-measures/routes.ts (renamed from server/sonar-web/src/main/js/apps/custom-measures/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/groups/routes.ts (renamed from server/sonar-web/src/main/js/apps/groups/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/routes.ts (renamed from server/sonar-web/src/main/js/apps/issues/routes.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx (renamed from server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx (renamed from server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/maintenance/routes.tsx (renamed from server/sonar-web/src/main/js/apps/maintenance/routes.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx (renamed from server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/metrics/routes.ts (renamed from server/sonar-web/src/main/js/apps/metrics/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/ApplicationQualityGate-test.js.snap2
-rw-r--r--server/sonar-web/src/main/js/apps/overview/routes.ts (renamed from server/sonar-web/src/main/js/apps/overview/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/permission-templates/routes.ts (renamed from server/sonar-web/src/main/js/apps/permission-templates/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/routes.ts (renamed from server/sonar-web/src/main/js/apps/permissions/routes.js)6
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/routes.ts (renamed from server/sonar-web/src/main/js/apps/projectActivity/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/projects-admin/routes.ts (renamed from server/sonar-web/src/main/js/apps/projects-admin/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/App.tsx (renamed from server/sonar-web/src/main/js/apps/projects/components/App.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/projects/routes.ts (renamed from server/sonar-web/src/main/js/apps/projects/routes.js)9
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/routes.ts (renamed from server/sonar-web/src/main/js/apps/quality-gates/routes.js)8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.js.snap)12
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts (renamed from server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js)7
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js122
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx109
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js)112
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js)17
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js)29
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js)41
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js)43
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js)28
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js)20
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js)70
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js)17
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js)27
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js)40
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js)5
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/App.js)42
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js)8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.js)25
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.js)50
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.js)41
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js)64
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js)35
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js)37
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js)41
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js)39
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.js)48
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js)25
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.js)61
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.js)38
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js)55
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js)27
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js)25
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js)100
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js93
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx82
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js)53
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js)62
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.js)13
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.js)25
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.js)23
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.js)21
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.js)29
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.js)3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.js.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.js.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.js.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.js.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap (renamed from server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.js.snap)0
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.js)82
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js)37
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js96
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx86
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js)44
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js80
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx73
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js)53
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js)45
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js)54
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js)19
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js)38
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx (renamed from server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.js)54
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/propTypes.js76
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/routes.ts (renamed from server/sonar-web/src/main/js/apps/quality-profiles/routes.js)14
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/types.ts53
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/utils.ts (renamed from server/sonar-web/src/main/js/apps/quality-profiles/utils.js)50
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js49
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.tsx50
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/routes.ts (renamed from server/sonar-web/src/main/js/apps/sessions/routes.js)8
-rw-r--r--server/sonar-web/src/main/js/apps/settings/routes.ts (renamed from server/sonar-web/src/main/js/apps/settings/routes.js)10
-rw-r--r--server/sonar-web/src/main/js/apps/system/routes.js28
-rw-r--r--server/sonar-web/src/main/js/apps/system/routes.ts30
-rw-r--r--server/sonar-web/src/main/js/apps/update-center/routes.ts (renamed from server/sonar-web/src/main/js/apps/update-center/routes.js)12
-rw-r--r--server/sonar-web/src/main/js/apps/users/routes.ts (renamed from server/sonar-web/src/main/js/apps/users/routes.js)4
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/routes.ts (renamed from server/sonar-web/src/main/js/apps/web-api/routes.js)10
115 files changed, 1688 insertions, 1906 deletions
diff --git a/server/sonar-web/src/main/js/apps/about/routes.js b/server/sonar-web/src/main/js/apps/about/routes.ts
index 0748dad497d..6da3a2d64ba 100644
--- a/server/sonar-web/src/main/js/apps/about/routes.js
+++ b/server/sonar-web/src/main/js/apps/about/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/AboutApp').then(i => callback(null, { component: i.default }));
}
}
diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js
deleted file mode 100644
index 13826f80dc8..00000000000
--- a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 moment from 'moment';
-import { sortBy } from 'lodash';
-import { Link } from 'react-router';
-import Level from '../../../components/ui/Level';
-import { projectType } from './propTypes';
-import { translateWithParameters, translate } from '../../../helpers/l10n';
-
-export default class ProjectCard extends React.PureComponent {
- static propTypes = {
- project: projectType.isRequired
- };
-
- render() {
- const { project } = this.props;
- const isAnalyzed = project.lastAnalysisDate != null;
- const analysisMoment = isAnalyzed && moment(project.lastAnalysisDate);
- const links = sortBy(project.links, 'type');
-
- return (
- <div className="account-project-card clearfix">
- <aside className="account-project-side">
- {isAnalyzed
- ? <div className="account-project-analysis" title={analysisMoment.format('LLL')}>
- {translateWithParameters(
- 'my_account.projects.analyzed_x',
- analysisMoment.fromNow()
- )}
- </div>
- : <div className="account-project-analysis">
- {translate('my_account.projects.never_analyzed')}
- </div>}
-
- {project.qualityGate != null &&
- <div className="account-project-quality-gate">
- <Level level={project.qualityGate} />
- </div>}
- </aside>
-
- <h3 className="account-project-name">
- <Link to={{ pathname: '/dashboard', query: { id: project.key } }}>
- {project.name}
- </Link>
- </h3>
-
- {links.length > 0 &&
- <div className="account-project-links">
- <ul className="list-inline">
- {links.map(link =>
- <li key={link.type}>
- <a
- className="link-with-icon"
- href={link.href}
- title={link.name}
- target="_blank"
- rel="nofollow">
- <i className={`icon-color-link icon-${link.type}`} />
- </a>
- </li>
- )}
- </ul>
- </div>}
-
- <div className="account-project-key">
- {project.key}
- </div>
-
- {!!project.description &&
- <div className="account-project-description">
- {project.description}
- </div>}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx
new file mode 100644
index 00000000000..93a3a787715
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 * as moment from 'moment';
+import { sortBy } from 'lodash';
+import { Link } from 'react-router';
+import { IProject } from './types';
+import Level from '../../../components/ui/Level';
+import { translateWithParameters, translate } from '../../../helpers/l10n';
+
+interface Props {
+ project: IProject;
+}
+
+export default function ProjectCard(props: Props) {
+ const { project } = props;
+ const isAnalyzed = project.lastAnalysisDate != null;
+ const analysisMoment = isAnalyzed && moment(project.lastAnalysisDate);
+ const links = sortBy(project.links, 'type');
+
+ return (
+ <div className="account-project-card clearfix">
+ <aside className="account-project-side">
+ {isAnalyzed
+ ? <div
+ className="account-project-analysis"
+ title={analysisMoment ? analysisMoment.format('LLL') : undefined}>
+ {translateWithParameters(
+ 'my_account.projects.analyzed_x',
+ analysisMoment ? analysisMoment.fromNow() : undefined
+ )}
+ </div>
+ : <div className="account-project-analysis">
+ {translate('my_account.projects.never_analyzed')}
+ </div>}
+
+ {project.qualityGate != null &&
+ <div className="account-project-quality-gate">
+ <Level level={project.qualityGate} />
+ </div>}
+ </aside>
+
+ <h3 className="account-project-name">
+ <Link to={{ pathname: '/dashboard', query: { id: project.key } }}>
+ {project.name}
+ </Link>
+ </h3>
+
+ {links.length > 0 &&
+ <div className="account-project-links">
+ <ul className="list-inline">
+ {links.map(link =>
+ <li key={link.type}>
+ <a
+ className="link-with-icon"
+ href={link.href}
+ title={link.name}
+ target="_blank"
+ rel="nofollow">
+ <i className={`icon-color-link icon-${link.type}`} />
+ </a>
+ </li>
+ )}
+ </ul>
+ </div>}
+
+ <div className="account-project-key">
+ {project.key}
+ </div>
+
+ {!!project.description &&
+ <div className="account-project-description">
+ {project.description}
+ </div>}
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/account/projects/Projects.js b/server/sonar-web/src/main/js/apps/account/projects/Projects.js
deleted file mode 100644
index 89c151f73d5..00000000000
--- a/server/sonar-web/src/main/js/apps/account/projects/Projects.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 ProjectCard from './ProjectCard';
-import ListFooter from '../../../components/controls/ListFooter';
-import { projectsListType } from './propTypes';
-import { translate } from '../../../helpers/l10n';
-
-export default class Projects extends React.PureComponent {
- static propTypes = {
- projects: projectsListType.isRequired,
- total: PropTypes.number.isRequired,
- loading: PropTypes.bool.isRequired,
- loadMore: PropTypes.func.isRequired
- };
-
- render() {
- const { projects } = this.props;
-
- return (
- <div id="account-projects">
- {projects.length === 0
- ? <div className="js-no-results">
- {translate('my_account.projects.no_results')}
- </div>
- : <p>
- {translate('my_account.projects.description')}
- </p>}
-
- {projects.length > 0 &&
- <ul className="account-projects-list">
- {projects.map(project =>
- <li key={project.key}>
- <ProjectCard project={project} />
- </li>
- )}
- </ul>}
-
- {projects.length > 0 &&
- <ListFooter
- count={projects.length}
- total={this.props.total}
- ready={!this.props.loading}
- loadMore={this.props.loadMore}
- />}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/account/projects/Projects.tsx b/server/sonar-web/src/main/js/apps/account/projects/Projects.tsx
new file mode 100644
index 00000000000..e3681c3465d
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/account/projects/Projects.tsx
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 ProjectCard from './ProjectCard';
+import { IProject } from './types';
+import ListFooter from '../../../components/controls/ListFooter';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ loading: boolean;
+ loadMore: () => void;
+ projects: IProject[];
+ search: (query: string) => void;
+ total?: number;
+}
+
+export default function Projects(props: Props) {
+ const { projects } = props;
+
+ return (
+ <div id="account-projects">
+ {projects.length === 0
+ ? <div className="js-no-results">
+ {translate('my_account.projects.no_results')}
+ </div>
+ : <p>
+ {translate('my_account.projects.description')}
+ </p>}
+
+ {projects.length > 0 &&
+ <ul className="account-projects-list">
+ {projects.map(project =>
+ <li key={project.key}>
+ <ProjectCard project={project} />
+ </li>
+ )}
+ </ul>}
+
+ {projects.length > 0 &&
+ <ListFooter
+ count={projects.length}
+ total={props.total || 0}
+ ready={!props.loading}
+ loadMore={props.loadMore}
+ />}
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx
index 69aea617c93..b822768884d 100644
--- a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js
+++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx
@@ -17,24 +17,28 @@
* 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 * as React from 'react';
import Helmet from 'react-helmet';
import Projects from './Projects';
import { getMyProjects } from '../../../api/components';
import { translate } from '../../../helpers/l10n';
-export default class ProjectsContainer extends React.PureComponent {
- state = {
+interface State {
+ loading: boolean;
+ page: number;
+ projects?: any[];
+ query: string;
+ total?: number;
+}
+
+export default class ProjectsContainer extends React.PureComponent<{}, State> {
+ mounted: boolean;
+ state: State = {
loading: true,
page: 1,
query: ''
};
- componentWillMount() {
- this.loadMore = this.loadMore.bind(this);
- this.search = this.search.bind(this);
- }
-
componentDidMount() {
this.mounted = true;
this.loadProjects();
@@ -46,15 +50,15 @@ export default class ProjectsContainer extends React.PureComponent {
loadProjects(page = this.state.page, query = this.state.query) {
this.setState({ loading: true });
- const data = { ps: 100 };
+ const data: { [p: string]: any } = { ps: 100 };
if (page > 1) {
data.p = page;
}
if (query) {
data.q = query;
}
- return getMyProjects(data).then(r => {
- const projects = page > 1 ? [...this.state.projects, ...r.projects] : r.projects;
+ return getMyProjects(data).then((r: any) => {
+ const projects = page > 1 ? [...(this.state.projects || []), ...r.projects] : r.projects;
this.setState({
projects,
query,
@@ -65,13 +69,9 @@ export default class ProjectsContainer extends React.PureComponent {
});
}
- loadMore() {
- return this.loadProjects(this.state.page + 1);
- }
+ loadMore = () => this.loadProjects(this.state.page + 1);
- search(query) {
- return this.loadProjects(1, query);
- }
+ search = (query: string) => this.loadProjects(1, query);
render() {
const helmet = <Helmet title={translate('my_account.projects')} />;
diff --git a/server/sonar-web/src/main/js/apps/account/projects/propTypes.js b/server/sonar-web/src/main/js/apps/account/projects/propTypes.js
deleted file mode 100644
index cae87b48906..00000000000
--- a/server/sonar-web/src/main/js/apps/account/projects/propTypes.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 PropTypes from 'prop-types';
-
-const { shape, string, array, arrayOf } = PropTypes;
-
-export const projectType = shape({
- id: string.isRequired,
- key: string.isRequired,
- name: string.isRequired,
- lastAnalysisDate: string,
- description: string,
- links: array.isRequired,
- qualityGate: string
-});
-
-export const projectsListType = arrayOf(projectType);
diff --git a/server/sonar-web/src/main/js/apps/account/projects/types.ts b/server/sonar-web/src/main/js/apps/account/projects/types.ts
new file mode 100644
index 00000000000..76feb045c64
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/account/projects/types.ts
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.
+ */
+export interface IProject {
+ id: string;
+ key: string;
+ name: string;
+ lastAnalysisDate: string;
+ description: string;
+ links: Array<{
+ href: string;
+ name: string;
+ type: string;
+ }>;
+ qualityGate: string;
+}
diff --git a/server/sonar-web/src/main/js/apps/account/routes.js b/server/sonar-web/src/main/js/apps/account/routes.ts
index 2b92bf00f6b..90e66149504 100644
--- a/server/sonar-web/src/main/js/apps/account/routes.js
+++ b/server/sonar-web/src/main/js/apps/account/routes.ts
@@ -17,44 +17,46 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps, RouteComponent } from 'react-router';
+
const routes = [
{
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/Account').then(i => callback(null, i.default));
},
childRoutes: [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./profile/Profile').then(i => callback(null, { component: i.default }));
}
},
{
path: 'security',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/Security').then(i => callback(null, i.default));
}
},
{
path: 'projects',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./projects/ProjectsContainer').then(i => callback(null, i.default));
}
},
{
path: 'notifications',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./notifications/Notifications').then(i => callback(null, i.default));
}
},
{
path: 'organizations',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./organizations/UserOrganizations').then(i => callback(null, i.default));
},
childRoutes: [
{
path: 'create',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./organizations/CreateOrganizationForm').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/routes.js b/server/sonar-web/src/main/js/apps/background-tasks/routes.ts
index 3f46e626d9e..88e0a5e53bc 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/routes.js
+++ b/server/sonar-web/src/main/js/apps/background-tasks/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/BackgroundTasksApp').then(i => callback(null, { component: i.default }));
}
}
diff --git a/server/sonar-web/src/main/js/apps/code/routes.js b/server/sonar-web/src/main/js/apps/code/routes.ts
index 4de41657b76..fcffeff191c 100644
--- a/server/sonar-web/src/main/js/apps/code/routes.js
+++ b/server/sonar-web/src/main/js/apps/code/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/App').then(i => callback(null, { component: i.default }));
}
}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/routes.js b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts
index af91a4eab6d..798ee29934a 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/routes.js
+++ b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts
@@ -17,10 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent } from 'react-router';
+
const routes = [
{
indexRoute: {
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/CodingRulesAppContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.js b/server/sonar-web/src/main/js/apps/component-measures/routes.ts
index c0abc9f57d8..9f3813c87e2 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/routes.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/routes.ts
@@ -17,15 +17,17 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps, RedirectFunction } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/AppContainer').then(i => callback(null, { component: i.default }));
}
},
{
path: 'domain/:domainName',
- onEnter(nextState, replace) {
+ onEnter(nextState: RouterState, replace: RedirectFunction) {
replace({
pathname: '/component_measures',
query: {
@@ -37,7 +39,7 @@ const routes = [
},
{
path: 'metric/:metricKey(/:view)',
- onEnter(nextState, replace) {
+ onEnter(nextState: RouterState, replace: RedirectFunction) {
if (nextState.params.view === 'history') {
replace({
pathname: '/project/activity',
diff --git a/server/sonar-web/src/main/js/apps/component/components/App.js b/server/sonar-web/src/main/js/apps/component/components/App.tsx
index e8c1c9f2128..a1fb59f825c 100644
--- a/server/sonar-web/src/main/js/apps/component/components/App.js
+++ b/server/sonar-web/src/main/js/apps/component/components/App.tsx
@@ -17,20 +17,19 @@
* 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 * as React from 'react';
import SourceViewer from '../../../components/SourceViewer/SourceViewer';
-export default class App extends React.PureComponent {
- /*:: props: {
- location: {
- query: {
- id: string,
- line?: string
- }
- }
+interface Props {
+ location: {
+ query: {
+ id: string;
+ line?: string;
+ };
};
-*/
+}
+
+export default class App extends React.PureComponent<Props> {
scrollToLine = () => {
const { line } = this.props.location.query;
if (line) {
diff --git a/server/sonar-web/src/main/js/apps/component/routes.js b/server/sonar-web/src/main/js/apps/component/routes.ts
index 9943b1d8380..c5105eeca4e 100644
--- a/server/sonar-web/src/main/js/apps/component/routes.js
+++ b/server/sonar-web/src/main/js/apps/component/routes.ts
@@ -17,10 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent } from 'react-router';
+
const routes = [
{
indexRoute: {
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/App').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.js b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts
index e3aee2038cd..ad092ba1d48 100644
--- a/server/sonar-web/src/main/js/apps/custom-measures/routes.js
+++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/CustomMeasuresAppContainer').then(i =>
callback(null, { component: i.default })
);
diff --git a/server/sonar-web/src/main/js/apps/groups/routes.js b/server/sonar-web/src/main/js/apps/groups/routes.ts
index 8829f80c94b..80ee5984d39 100644
--- a/server/sonar-web/src/main/js/apps/groups/routes.js
+++ b/server/sonar-web/src/main/js/apps/groups/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
Promise.all([
import('./components/GroupsAppContainer').then(i => i.default),
import('../organizations/forSingleOrganization').then(i => i.default)
diff --git a/server/sonar-web/src/main/js/apps/issues/routes.js b/server/sonar-web/src/main/js/apps/issues/routes.ts
index ffcdcb7a090..e915d90da0a 100644
--- a/server/sonar-web/src/main/js/apps/issues/routes.js
+++ b/server/sonar-web/src/main/js/apps/issues/routes.ts
@@ -17,11 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
import { onEnter } from './redirects';
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/AppContainer').then(i =>
callback(null, { component: i.default, onEnter })
);
diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx
index bf151b827ac..923d805efd7 100644
--- a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx
@@ -17,7 +17,7 @@
* 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 * as React from 'react';
import init from '../init';
export default class MaintenanceAppContainer extends React.PureComponent {
diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx
index c28492700ce..398ebb69fd6 100644
--- a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx
@@ -17,7 +17,7 @@
* 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 * as React from 'react';
import init from '../init';
export default class SetupAppContainer extends React.PureComponent {
diff --git a/server/sonar-web/src/main/js/apps/maintenance/routes.js b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx
index e6b19e9a5a3..df6cd941cd5 100644
--- a/server/sonar-web/src/main/js/apps/maintenance/routes.js
+++ b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx
@@ -17,7 +17,7 @@
* 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 * as React from 'react';
import { IndexRoute } from 'react-router';
import MaintenanceAppContainer from './components/MaintenanceAppContainer';
import SetupAppContainer from './components/SetupAppContainer';
diff --git a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx
index f5f031e9839..0bf49c749d5 100644
--- a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx
@@ -17,7 +17,7 @@
* 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 * as React from 'react';
import Helmet from 'react-helmet';
import init from '../init';
import { translate } from '../../../helpers/l10n';
diff --git a/server/sonar-web/src/main/js/apps/metrics/routes.js b/server/sonar-web/src/main/js/apps/metrics/routes.ts
index 637dba72da9..c52951ea17b 100644
--- a/server/sonar-web/src/main/js/apps/metrics/routes.js
+++ b/server/sonar-web/src/main/js/apps/metrics/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/MetricsAppContainer').then(i =>
callback(null, { component: i.default })
);
diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/ApplicationQualityGate-test.js.snap b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/ApplicationQualityGate-test.js.snap
index 247c1251986..326b9ecefb1 100644
--- a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/ApplicationQualityGate-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/ApplicationQualityGate-test.js.snap
@@ -27,8 +27,6 @@ exports[`renders 2`] = `
overview.quality_gate
<Level
level="ERROR"
- muted={false}
- small={false}
/>
</h2>
<div
diff --git a/server/sonar-web/src/main/js/apps/overview/routes.js b/server/sonar-web/src/main/js/apps/overview/routes.ts
index 02a7323043e..21e41c6b087 100644
--- a/server/sonar-web/src/main/js/apps/overview/routes.js
+++ b/server/sonar-web/src/main/js/apps/overview/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/AppContainer').then(i => callback(null, { component: i.default }));
}
}
diff --git a/server/sonar-web/src/main/js/apps/permission-templates/routes.js b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts
index ce1b2679e4a..f00dc431c31 100644
--- a/server/sonar-web/src/main/js/apps/permission-templates/routes.js
+++ b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
Promise.all([
import('./components/AppContainer').then(i => i.default),
import('../organizations/forSingleOrganization').then(i => i.default)
diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.js b/server/sonar-web/src/main/js/apps/permissions/routes.ts
index 631a26985b1..85a62be0dd2 100644
--- a/server/sonar-web/src/main/js/apps/permissions/routes.js
+++ b/server/sonar-web/src/main/js/apps/permissions/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
export const globalPermissionsRoutes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
Promise.all([
import('./global/components/App').then(i => i.default),
import('../organizations/forSingleOrganization').then(i => i.default)
@@ -32,7 +34,7 @@ export const globalPermissionsRoutes = [
export const projectPermissionsRoutes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./project/components/AppContainer').then(i =>
callback(null, { component: i.default })
);
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.js b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts
index 11233a7368b..47d7bda3dae 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/routes.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/ProjectActivityAppContainer').then(i =>
callback(null, { component: i.default })
);
diff --git a/server/sonar-web/src/main/js/apps/projects-admin/routes.js b/server/sonar-web/src/main/js/apps/projects-admin/routes.ts
index d17958371b6..447c6ae73dd 100644
--- a/server/sonar-web/src/main/js/apps/projects-admin/routes.js
+++ b/server/sonar-web/src/main/js/apps/projects-admin/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
Promise.all([
import('./AppContainer').then(i => i.default),
import('../organizations/forSingleOrganization').then(i => i.default)
diff --git a/server/sonar-web/src/main/js/apps/projects/components/App.js b/server/sonar-web/src/main/js/apps/projects/components/App.tsx
index 83b097ed170..471331fb0b9 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/App.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/App.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
export default class App extends React.PureComponent {
componentDidMount() {
diff --git a/server/sonar-web/src/main/js/apps/projects/routes.js b/server/sonar-web/src/main/js/apps/projects/routes.ts
index 1c3c76cc3d4..c6f3df309f5 100644
--- a/server/sonar-web/src/main/js/apps/projects/routes.js
+++ b/server/sonar-web/src/main/js/apps/projects/routes.ts
@@ -17,16 +17,17 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps, RouteComponent, RedirectFunction } from 'react-router';
import { saveAll } from '../../helpers/storage';
const routes = [
{
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/App').then(i => callback(null, i.default));
},
childRoutes: [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/DefaultPageSelector').then(i =>
callback(null, { component: i.default })
);
@@ -34,14 +35,14 @@ const routes = [
},
{
path: 'all',
- onEnter(_, replace) {
+ onEnter(_: RouterState, replace: RedirectFunction) {
saveAll();
replace('/projects');
}
},
{
path: 'favorite',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/FavoriteProjectsContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.js b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts
index 8664f1f39bb..f1d203bc354 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/routes.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts
@@ -17,20 +17,22 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps, RouteComponent } from 'react-router';
+
const routes = [
{
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./containers/QualityGatesAppContainer').then(i => callback(null, i.default));
},
childRoutes: [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/Intro').then(i => callback(null, { component: i.default }));
}
},
{
path: 'show/:id',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./containers/DetailsContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap
index 63a0a9ee7e0..a833c80f2e3 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap
@@ -109,6 +109,18 @@ Array [
Object {
"childrenCount": 0,
"depth": 1,
+ "key": "foo",
+ "name": "foo",
+ "parentKey": "bar",
+ },
+]
+`;
+
+exports[`#sortProfiles sorts partial set of inherited profiles 2`] = `
+Array [
+ Object {
+ "childrenCount": 0,
+ "depth": 1,
"key": "profile1",
"name": "profile1",
"parentKey": "x",
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts
index 57157f7de3a..433702eab06 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts
@@ -18,9 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { sortProfiles } from '../utils';
+import { IProfile } from '../types';
-function createProfile(key, parentKey) {
- return { name: key, key, parentKey };
+function createProfile(key: string, parentKey?: string) {
+ return { name: key, key, parentKey } as IProfile;
}
describe('#sortProfiles', () => {
@@ -54,7 +55,7 @@ describe('#sortProfiles', () => {
it('sorts partial set of inherited profiles', () => {
const foo = createProfile('foo', 'bar');
- expect(sortProfiles([foo]), ['foo']);
+ expect(sortProfiles([foo])).toMatchSnapshot();
const profile1 = createProfile('profile1', 'x');
const profile2 = createProfile('profile2');
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js
deleted file mode 100644
index 7eeb76ee8f8..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 moment from 'moment';
-import ChangesList from './ChangesList';
-import { translate } from '../../../helpers/l10n';
-import { getRulesUrl } from '../../../helpers/urls';
-
-/*::
-type Props = {
- events: Array<{
- action: string,
- authorName: string,
- date: string,
- params?: {},
- ruleKey: string,
- ruleName: string
- }>,
- organization: ?string
-};
-*/
-
-export default class Changelog extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- let isEvenRow = false;
-
- const rows = this.props.events.map((event, index) => {
- const prev = index > 0 ? this.props.events[index - 1] : null;
- const isSameDate = prev != null && moment(prev.date).diff(event.date, 'seconds') < 10;
- const isBulkChange =
- prev != null &&
- isSameDate &&
- prev.authorName === event.authorName &&
- prev.action === event.action;
-
- if (!isBulkChange) {
- isEvenRow = !isEvenRow;
- }
-
- const className = 'js-profile-changelog-event ' + (isEvenRow ? 'even' : 'odd');
-
- return (
- <tr key={index} className={className}>
- <td className="thin nowrap">
- {!isBulkChange && moment(event.date).format('LLL')}
- </td>
-
- <td className="thin nowrap">
- {!isBulkChange &&
- (event.authorName
- ? <span>
- {event.authorName}
- </span>
- : <span className="note">System</span>)}
- </td>
-
- <td className="thin nowrap">
- {!isBulkChange && translate('quality_profiles.changelog', event.action)}
- </td>
-
- <td style={{ lineHeight: '1.5' }}>
- <Link to={getRulesUrl({ rule_key: event.ruleKey }, this.props.organization)}>
- {event.ruleName}
- </Link>
- </td>
-
- <td className="thin nowrap">
- <ChangesList changes={event.params} />
- </td>
- </tr>
- );
- });
-
- return (
- <table className="data zebra-hover">
- <thead>
- <tr>
- <th className="thin nowrap">
- {translate('date')} <i className="icon-sort-desc" />
- </th>
- <th className="thin nowrap">
- {translate('user')}
- </th>
- <th className="thin nowrap">
- {translate('action')}
- </th>
- <th>
- {translate('rule')}
- </th>
- <th className="thin nowrap">
- {translate('parameters')}
- </th>
- </tr>
- </thead>
- <tbody>
- {rows}
- </tbody>
- </table>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx
new file mode 100644
index 00000000000..6c152925cca
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.tsx
@@ -0,0 +1,109 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 * as moment from 'moment';
+import ChangesList from './ChangesList';
+import { translate } from '../../../helpers/l10n';
+import { getRulesUrl } from '../../../helpers/urls';
+import { IProfileChangelogEvent } from '../types';
+
+interface Props {
+ events: IProfileChangelogEvent[];
+ organization: string | null;
+}
+
+export default function Changelog(props: Props) {
+ let isEvenRow = false;
+
+ const rows = props.events.map((event, index) => {
+ const prev = index > 0 ? props.events[index - 1] : null;
+ const isSameDate = prev != null && moment(prev.date).diff(event.date, 'seconds') < 10;
+ const isBulkChange =
+ prev != null &&
+ isSameDate &&
+ prev.authorName === event.authorName &&
+ prev.action === event.action;
+
+ if (!isBulkChange) {
+ isEvenRow = !isEvenRow;
+ }
+
+ const className = 'js-profile-changelog-event ' + (isEvenRow ? 'even' : 'odd');
+
+ return (
+ <tr key={index} className={className}>
+ <td className="thin nowrap">
+ {!isBulkChange && moment(event.date).format('LLL')}
+ </td>
+
+ <td className="thin nowrap">
+ {!isBulkChange &&
+ (event.authorName
+ ? <span>
+ {event.authorName}
+ </span>
+ : <span className="note">System</span>)}
+ </td>
+
+ <td className="thin nowrap">
+ {!isBulkChange && translate('quality_profiles.changelog', event.action)}
+ </td>
+
+ <td style={{ lineHeight: '1.5' }}>
+ <Link to={getRulesUrl({ rule_key: event.ruleKey }, props.organization)}>
+ {event.ruleName}
+ </Link>
+ </td>
+
+ <td className="thin nowrap">
+ {event.params && <ChangesList changes={event.params} />}
+ </td>
+ </tr>
+ );
+ });
+
+ return (
+ <table className="data zebra-hover">
+ <thead>
+ <tr>
+ <th className="thin nowrap">
+ {translate('date')} <i className="icon-sort-desc" />
+ </th>
+ <th className="thin nowrap">
+ {translate('user')}
+ </th>
+ <th className="thin nowrap">
+ {translate('action')}
+ </th>
+ <th>
+ {translate('rule')}
+ </th>
+ <th className="thin nowrap">
+ {translate('parameters')}
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {rows}
+ </tbody>
+ </table>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx
index 6bca8f58b0f..aa54dd0c89c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx
@@ -17,48 +17,42 @@
* 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 * as React from 'react';
+import * as PropTypes from 'prop-types';
import Changelog from './Changelog';
import ChangelogSearch from './ChangelogSearch';
import ChangelogEmpty from './ChangelogEmpty';
import { getProfileChangelog } from '../../../api/quality-profiles';
import { translate } from '../../../helpers/l10n';
import { getProfileChangelogPath } from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile, IProfileChangelogEvent } from '../types';
-/*::
-type Props = {
+interface Props {
location: {
query: {
- since?: string,
- to?: string
- }
- },
- organization: ?string,
- profile: Profile
-};
-*/
-
-/*::
-type State = {
- events?: Array<*>,
- loading: boolean,
- page?: number,
- total?: number
-};
-*/
-
-export default class ChangelogContainer extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
+ since?: string;
+ to?: string;
+ };
+ };
+ organization: string | null;
+ profile: IProfile;
+}
+
+interface State {
+ events?: IProfileChangelogEvent[];
+ loading: boolean;
+ page?: number;
+ total?: number;
+}
+
+export default class ChangelogContainer extends React.PureComponent<Props, State> {
+ mounted: boolean;
static contextTypes = {
router: PropTypes.object
};
- state /*: State */ = {
+ state: State = {
loading: true
};
@@ -67,7 +61,7 @@ export default class ChangelogContainer extends React.PureComponent {
this.loadChangelog();
}
- componentDidUpdate(prevProps /*: Props */) {
+ componentDidUpdate(prevProps: Props) {
if (prevProps.location !== this.props.location) {
this.loadChangelog();
}
@@ -80,7 +74,7 @@ export default class ChangelogContainer extends React.PureComponent {
loadChangelog() {
this.setState({ loading: true });
const { query } = this.props.location;
- const data /*: Object */ = { profileKey: this.props.profile.key };
+ const data: any = { profileKey: this.props.profile.key };
if (query.since) {
data.since = query.since;
}
@@ -88,7 +82,7 @@ export default class ChangelogContainer extends React.PureComponent {
data.to = query.to;
}
- getProfileChangelog(data).then(r => {
+ getProfileChangelog(data).then((r: any) => {
if (this.mounted) {
this.setState({
events: r.events,
@@ -100,36 +94,38 @@ export default class ChangelogContainer extends React.PureComponent {
});
}
- loadMore(e /*: SyntheticInputEvent */) {
- e.preventDefault();
- e.target.blur();
+ loadMore(event: React.SyntheticEvent<HTMLElement>) {
+ event.preventDefault();
+ event.currentTarget.blur();
+
+ if (this.state.page != null) {
+ this.setState({ loading: true });
+ const { query } = this.props.location;
+ const data: any = {
+ profileKey: this.props.profile.key,
+ p: this.state.page + 1
+ };
+ if (query.since) {
+ data.since = query.since;
+ }
+ if (query.to) {
+ data.to = query.to;
+ }
- this.setState({ loading: true });
- const { query } = this.props.location;
- const data /*: Object */ = {
- profileKey: this.props.profile.key,
- p: this.state.page + 1
- };
- if (query.since) {
- data.since = query.since;
- }
- if (query.to) {
- data.to = query.to;
+ getProfileChangelog(data).then((r: any) => {
+ if (this.mounted && this.state.events) {
+ this.setState({
+ events: [...this.state.events, ...r.events],
+ total: r.total,
+ page: r.p,
+ loading: false
+ });
+ }
+ });
}
-
- getProfileChangelog(data).then(r => {
- if (this.mounted && this.state.events) {
- this.setState({
- events: [...this.state.events, ...r.events],
- total: r.total,
- page: r.p,
- loading: false
- });
- }
- });
}
- handleFromDateChange = (fromDate /*: string | void */) => {
+ handleFromDateChange = (fromDate?: string) => {
const path = getProfileChangelogPath(
this.props.profile.name,
this.props.profile.language,
@@ -142,7 +138,7 @@ export default class ChangelogContainer extends React.PureComponent {
this.context.router.push(path);
};
- handleToDateChange = (toDate /*: string | void */) => {
+ handleToDateChange = (toDate?: string) => {
const path = getProfileChangelogPath(
this.props.profile.name,
this.props.profile.language,
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx
index 96db0d8c8eb..b8a9fbaa35e 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx
@@ -17,16 +17,13 @@
* 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 * as React from 'react';
import { translate } from '../../../helpers/l10n';
-export default class ChangelogEmpty extends React.PureComponent {
- render() {
- return (
- <div className="big-spacer-top">
- {translate('no_results')}
- </div>
- );
- }
+export default function ChangelogEmpty() {
+ return (
+ <div className="big-spacer-top">
+ {translate('no_results')}
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
index c0abdb0155a..e59479fccf3 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
@@ -17,27 +17,22 @@
* 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 * as React from 'react';
import DateInput from '../../../components/controls/DateInput';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- fromDate?: string,
- toDate?: string,
- onFromDateChange: () => void,
- onReset: () => void,
- onToDateChange: () => void
-};
-*/
-
-export default class ChangelogSearch extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ fromDate?: string;
+ toDate?: string;
+ onFromDateChange: () => void;
+ onReset: () => void;
+ onToDateChange: () => void;
+}
- handleResetClick(e /*: SyntheticInputEvent */) {
- e.preventDefault();
- e.target.blur();
+export default class ChangelogSearch extends React.PureComponent<Props> {
+ handleResetClick(event: React.SyntheticEvent<HTMLElement>) {
+ event.preventDefault();
+ event.currentTarget.blur();
this.props.onReset();
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx
index c910ebb54ab..c800e44e918 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx
@@ -17,33 +17,24 @@
* 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 * as React from 'react';
import SeverityChange from './SeverityChange';
import ParameterChange from './ParameterChange';
-/*::
-type Props = {
- changes: { [string]: ?string }
-};
-*/
-
-export default class ChangesList extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- const { changes } = this.props;
+interface Props {
+ changes: { [change: string]: string | null };
+}
- return (
- <ul>
- {Object.keys(changes).map(key =>
- <li key={key}>
- {key === 'severity'
- ? <SeverityChange severity={changes[key]} />
- : <ParameterChange name={key} value={changes[key]} />}
- </li>
- )}
- </ul>
- );
- }
+export default function ChangesList({ changes }: Props) {
+ return (
+ <ul>
+ {Object.keys(changes).map(key =>
+ <li key={key}>
+ {key === 'severity'
+ ? <SeverityChange severity={changes[key]} />
+ : <ParameterChange name={key} value={changes[key]} />}
+ </li>
+ )}
+ </ul>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx
index 9ee9d2bd80f..d62d11d7c25 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx
@@ -17,38 +17,29 @@
* 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 * as React from 'react';
import { translateWithParameters } from '../../../helpers/l10n';
-/*::
-type Props = {
- name: string,
- value: ?string
-};
-*/
-
-export default class ParameterChange extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- const { name, value } = this.props;
-
- if (value == null) {
- return (
- <div style={{ whiteSpace: 'normal' }}>
- {translateWithParameters(
- 'quality_profiles.changelog.parameter_reset_to_default_value',
- name
- )}
- </div>
- );
- }
+interface Props {
+ name: string;
+ value: string | null;
+}
+export default function ParameterChange({ name, value }: Props) {
+ if (value == null) {
return (
<div style={{ whiteSpace: 'normal' }}>
- {translateWithParameters('quality_profiles.parameter_set_to', name, value)}
+ {translateWithParameters(
+ 'quality_profiles.changelog.parameter_reset_to_default_value',
+ name
+ )}
</div>
);
}
+
+ return (
+ <div style={{ whiteSpace: 'normal' }}>
+ {translateWithParameters('quality_profiles.parameter_set_to', name, value)}
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx
index 546c46610c2..3c744e731a9 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx
@@ -17,26 +17,18 @@
* 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 * as React from 'react';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- severity: ?string
-};
-*/
-
-export default class SeverityChange extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ severity: string | null;
+}
- render() {
- return (
- <div>
- {translate('quality_profiles.severity_set_to')}{' '}
- <SeverityHelper severity={this.props.severity} />
- </div>
- );
- }
+export default function SeverityChange({ severity }: Props) {
+ return (
+ <div>
+ {translate('quality_profiles.severity_set_to')} <SeverityHelper severity={severity} />
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.tsx
index 32774553ba1..ed8fb6b6106 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.tsx
@@ -18,11 +18,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import Changelog from '../Changelog';
import ChangesList from '../ChangesList';
+import { IProfileChangelogEvent } from '../../types';
-function createEvent(overrides) {
+function createEvent(overrides?: { [p: string]: any }): IProfileChangelogEvent {
return {
date: '2016-01-01',
authorName: 'John',
@@ -30,50 +31,51 @@ function createEvent(overrides) {
ruleKey: 'squid1234',
ruleName: 'Do not do this',
params: {},
+ organization: null,
...overrides
};
}
it('should render events', () => {
const events = [createEvent(), createEvent()];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.find('tbody').find('tr').length).toBe(2);
});
it('should render event date', () => {
const events = [createEvent()];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.text()).toContain('2016');
});
it('should render author', () => {
const events = [createEvent()];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.text()).toContain('John');
});
it('should render system author', () => {
const events = [createEvent({ authorName: undefined })];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.text()).toContain('System');
});
it('should render action', () => {
const events = [createEvent()];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.text()).toContain('ACTIVATED');
});
it('should render rule', () => {
const events = [createEvent()];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
expect(changelog.find('Link').prop('to')).toContain('rule_key=squid1234');
});
it('should render ChangesList', () => {
const params = { severity: 'BLOCKER' };
const events = [createEvent({ params })];
- const changelog = shallow(<Changelog events={events} />);
+ const changelog = shallow(<Changelog events={events} organization={null} />);
const changesList = changelog.find(ChangesList);
expect(changesList.length).toBe(1);
expect(changesList.prop('changes')).toBe(params);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx
index be461db98d4..78dd87a4b9f 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import ChangelogSearch from '../ChangelogSearch';
import DateInput from '../../../../components/controls/DateInput';
import { click } from '../../../../helpers/testUtils';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx
index 7ccb56ee199..82ddc9af0a0 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import ChangesList from '../ChangesList';
import SeverityChange from '../SeverityChange';
import ParameterChange from '../ParameterChange';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx
index 25032b3e07a..de80150b085 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx
@@ -18,11 +18,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import ParameterChange from '../ParameterChange';
it('should render different messages', () => {
- const first = shallow(<ParameterChange name="foo" />);
+ const first = shallow(<ParameterChange name="foo" value={null} />);
const second = shallow(<ParameterChange name="foo" value="bar" />);
expect(first.text()).not.toBe(second.text());
});
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx
index 8597dd0ab8c..bc5f6553420 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import SeverityChange from '../SeverityChange';
import SeverityHelper from '../../../../components/shared/SeverityHelper';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx
index 718d80dcc3d..003fd55a6d3 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx
@@ -17,45 +17,45 @@
* 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 * as React from 'react';
+import * as PropTypes from 'prop-types';
import ComparisonForm from './ComparisonForm';
import ComparisonResults from './ComparisonResults';
import { compareProfiles } from '../../../api/quality-profiles';
import { getProfileComparePath } from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- location: { query: { withKey?: string } },
- organization: ?string,
- profile: Profile,
- profiles: Array<Profile>
-};
-*/
-
-/*::
-type State = {
- loading: boolean,
- left?: { name: string },
- right?: { name: string },
- inLeft?: Array<*>,
- inRight?: Array<*>,
- modified?: Array<*>
-};
-*/
-
-export default class ComparisonContainer extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- /*:: state: State; */
+import { IProfile } from '../types';
+
+interface Props {
+ location: { query: { withKey?: string } };
+ organization: string | null;
+ profile: IProfile;
+ profiles: IProfile[];
+}
+
+type Params = { [p: string]: string };
+
+interface State {
+ loading: boolean;
+ left?: { name: string };
+ right?: { name: string };
+ inLeft?: Array<{ key: string; name: string; severity: string }>;
+ inRight?: Array<{ key: string; name: string; severity: string }>;
+ modified?: Array<{
+ key: string;
+ name: string;
+ left: { params: Params; severity: string };
+ right: { params: Params; severity: string };
+ }>;
+}
+
+export default class ComparisonContainer extends React.PureComponent<Props, State> {
+ mounted: boolean;
static contextTypes = {
router: PropTypes.object
};
- constructor(props /*: Props */) {
+ constructor(props: Props) {
super(props);
this.state = { loading: false };
}
@@ -65,7 +65,7 @@ export default class ComparisonContainer extends React.PureComponent {
this.loadResults();
}
- componentDidUpdate(prevProps /*: Props */) {
+ componentDidUpdate(prevProps: Props) {
if (prevProps.profile !== this.props.profile || prevProps.location !== this.props.location) {
this.loadResults();
}
@@ -83,7 +83,7 @@ export default class ComparisonContainer extends React.PureComponent {
}
this.setState({ loading: true });
- compareProfiles(this.props.profile.key, withKey).then(r => {
+ compareProfiles(this.props.profile.key, withKey).then((r: any) => {
if (this.mounted) {
this.setState({
left: r.left,
@@ -97,7 +97,7 @@ export default class ComparisonContainer extends React.PureComponent {
});
}
- handleCompare = (withKey /*: string */) => {
+ handleCompare = (withKey: string) => {
const path = getProfileComparePath(
this.props.profile.name,
this.props.profile.language,
@@ -126,6 +126,10 @@ export default class ComparisonContainer extends React.PureComponent {
</header>
{left != null &&
+ inLeft != null &&
+ right != null &&
+ inRight != null &&
+ modified != null &&
<ComparisonResults
left={left}
right={right}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx
index b3a19a37f5c..a6a2c390289 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx
@@ -17,16 +17,13 @@
* 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 * as React from 'react';
import { translate } from '../../../helpers/l10n';
-export default class ComparisonEmpty extends React.PureComponent {
- render() {
- return (
- <div className="big-spacer-top">
- {translate('quality_profile.empty_comparison')}
- </div>
- );
- }
+export default function ComparisonEmpty() {
+ return (
+ <div className="big-spacer-top">
+ {translate('quality_profile.empty_comparison')}
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx
index c0a0086f006..11c4fb25639 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx
@@ -17,25 +17,20 @@
* 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 Select from 'react-select';
+import * as React from 'react';
+import * as Select from 'react-select';
import { translate } from '../../../helpers/l10n';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- profile: Profile,
- profiles: Array<Profile>,
- onCompare: string => void,
- withKey: string
-};
-*/
-
-export default class ComparisonForm extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ profile: IProfile;
+ profiles: IProfile[];
+ onCompare: (rule: string) => void;
+ withKey?: string;
+}
- handleChange(option /*: { value: string } */) {
+export default class ComparisonForm extends React.PureComponent<Props> {
+ handleChange(option: { value: string }) {
this.props.onCompare(option.value);
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx
index b13c88ecace..f29c2ec1c2b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx
@@ -17,33 +17,31 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import ComparisonEmpty from './ComparisonEmpty';
import SeverityIcon from '../../../components/shared/SeverityIcon';
import { translateWithParameters } from '../../../helpers/l10n';
import { getRulesUrl } from '../../../helpers/urls';
-/*::
-type Params = { [string]: string };
-*/
+type Params = { [p: string]: string };
-/*::
-type Props = {
- left: { name: string },
- right: { name: string },
- inLeft: Array<*>,
- inRight: Array<*>,
- modified: Array<*>,
- organization: ?string
-};
-*/
-
-export default class ComparisonResults extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ left: { name: string };
+ right: { name: string };
+ inLeft: Array<{ key: string; name: string; severity: string }>;
+ inRight: Array<{ key: string; name: string; severity: string }>;
+ modified: Array<{
+ key: string;
+ name: string;
+ left: { params: Params; severity: string };
+ right: { params: Params; severity: string };
+ }>;
+ organization: string | null;
+}
- renderRule(rule /*: { key: string, name: string } */, severity /*: string */) {
+export default class ComparisonResults extends React.PureComponent<Props> {
+ renderRule(rule: { key: string; name: string }, severity: string) {
return (
<div>
<SeverityIcon severity={severity} />{' '}
@@ -52,7 +50,7 @@ export default class ComparisonResults extends React.PureComponent {
);
}
- renderParameters(params /*: Params */) {
+ renderParameters(params: Params) {
if (!params) {
return null;
}
@@ -135,7 +133,7 @@ export default class ComparisonResults extends React.PureComponent {
}
const header = (
<tr key="modified-header">
- <td colSpan="2" className="text-center">
+ <td colSpan={2} className="text-center">
<h6>
{translateWithParameters(
'quality_profiles.x_rules_have_different_configuration',
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx
index b972451e628..55edbd993fe 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx
@@ -18,8 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
-import Select from 'react-select';
+import * as React from 'react';
import ComparisonForm from '../ComparisonForm';
import { createFakeProfile } from '../../utils';
@@ -38,7 +37,7 @@ it('should render Select with right options', () => {
profiles={profiles}
onCompare={() => true}
/>
- ).find(Select);
+ ).find('Select');
expect(output.length).toBe(1);
expect(output.prop('value')).toBe('another');
expect(output.prop('options')).toEqual([{ value: 'another', label: 'another name' }]);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx
index d346aa2f480..c3200b06612 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import { Link } from 'react-router';
import ComparisonResults from '../ComparisonResults';
import ComparisonEmpty from '../ComparisonEmpty';
@@ -32,6 +32,7 @@ it('should render ComparisonEmpty', () => {
inLeft={[]}
inRight={[]}
modified={[]}
+ organization={null}
/>
);
expect(output.is(ComparisonEmpty)).toBe(true);
@@ -65,6 +66,7 @@ it('should compare', () => {
inLeft={inLeft}
inRight={inRight}
modified={modified}
+ organization={null}
/>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx
index b0f80ee623b..44013b73e70 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx
@@ -17,37 +17,31 @@
* 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 * as React from 'react';
import { searchQualityProfiles, getExporters } from '../../../api/quality-profiles';
import { sortProfiles } from '../utils';
import { translate } from '../../../helpers/l10n';
import OrganizationHelmet from '../../../components/common/OrganizationHelmet';
-/*:: import type { Exporter } from '../propTypes'; */
import '../styles.css';
+import { IExporter, IProfile } from '../types';
-/*::
-type Props = {
- children: React.Element<*>,
- currentUser: { permissions: { global: Array<string> } },
- languages: Array<*>,
- onRequestFail: Object => void,
- organization: { name: string, canAdmin?: boolean, key: string } | null
-};
-*/
+interface Props {
+ children: React.ReactElement<any>;
+ currentUser: { permissions: { global: Array<string> } };
+ languages: Array<{}>;
+ onRequestFail: (reasong: any) => void;
+ organization: { name: string; canAdmin?: boolean; key: string } | null;
+}
-/*::
-type State = {
- loading: boolean,
- exporters?: Array<Exporter>,
- profiles?: Array<*>
-};
-*/
+interface State {
+ loading: boolean;
+ exporters?: IExporter[];
+ profiles?: IProfile[];
+}
-export default class App extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { loading: true };
+export default class App extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: true };
componentWillMount() {
const html = document.querySelector('html');
@@ -90,7 +84,7 @@ export default class App extends React.PureComponent {
}
updateProfiles = () => {
- return this.fetchProfiles().then(profiles => {
+ return this.fetchProfiles().then((profiles: any) => {
if (this.mounted) {
this.setState({ profiles: sortProfiles(profiles) });
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx
index a9809ffe0dc..9eb3af6d784 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx
@@ -22,7 +22,7 @@ import App from './App';
import { getLanguages, getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer';
import { onFail } from '../../../store/rootActions';
-const mapStateToProps = (state, ownProps) => ({
+const mapStateToProps = (state: any, ownProps: any) => ({
currentUser: getCurrentUser(state),
languages: getLanguages(state),
organization: ownProps.params.organizationKey
@@ -30,8 +30,8 @@ const mapStateToProps = (state, ownProps) => ({
: null
});
-const mapDispatchToProps = dispatch => ({
- onRequestFail: error => onFail(dispatch)(error)
+const mapDispatchToProps = (dispatch: any) => ({
+ onRequestFail: (error: any) => onFail(dispatch)(error)
});
-export default connect(mapStateToProps, mapDispatchToProps)(App);
+export default connect(mapStateToProps, mapDispatchToProps)(App as any);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx
index fa2e1635620..7a70614d3e5 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx
@@ -17,22 +17,19 @@
* 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 classNames from 'classnames';
+import * as React from 'react';
+import * as classNames from 'classnames';
import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {|
- className?: string,
- tooltip?: boolean
-|};
-*/
+interface Props {
+ className?: string;
+ tooltip?: boolean;
+}
-export default function BuiltInBadge(props /*: Props */) {
+export default function BuiltInBadge({ className, tooltip = true }: Props) {
const badge = (
- <div className={classNames('outline-badge', props.className)}>
+ <div className={classNames('outline-badge', className)}>
{translate('quality_profiles.built_in')}
</div>
);
@@ -44,13 +41,9 @@ export default function BuiltInBadge(props /*: Props */) {
</span>
);
- return props.tooltip
+ return tooltip
? <Tooltip overlay={overlay}>
{badge}
</Tooltip>
: badge;
}
-
-BuiltInBadge.defaultProps = {
- tooltip: true
-};
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx
index 4ad268e4982..4d24898081d 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx
@@ -17,33 +17,27 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-/*:: import type { Profile } from '../propTypes'; */
import { copyProfile } from '../../../api/quality-profiles';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { IProfile } from '../types';
-/*::
-type Props = {
- onClose: () => void,
- onCopy: string => void,
- onRequestFail: Object => void,
- profile: Profile
-};
-*/
+interface Props {
+ onClose: () => void;
+ onCopy: (name: string) => void;
+ onRequestFail: (reasong: any) => void;
+ profile: IProfile;
+}
-/*::
-type State = {
- loading: boolean,
- name: ?string
-};
-*/
+interface State {
+ loading: boolean;
+ name: string | null;
+}
-export default class CopyProfileForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { loading: false, name: null };
+export default class CopyProfileForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false, name: null };
componentDidMount() {
this.mounted = true;
@@ -53,16 +47,16 @@ export default class CopyProfileForm extends React.PureComponent {
this.mounted = false;
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => {
+ handleNameChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
this.setState({ name: event.currentTarget.value });
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
const { name } = this.state;
@@ -70,8 +64,8 @@ export default class CopyProfileForm extends React.PureComponent {
if (name != null) {
this.setState({ loading: true });
copyProfile(this.props.profile.key, name).then(
- profile => this.props.onCopy(profile.name),
- error => {
+ (profile: any) => this.props.onCopy(profile.name),
+ (error: any) => {
if (this.mounted) {
this.setState({ loading: false });
}
@@ -113,11 +107,11 @@ export default class CopyProfileForm extends React.PureComponent {
<input
autoFocus={true}
id="copy-profile-name"
- maxLength="100"
+ maxLength={100}
name="name"
onChange={this.handleNameChange}
required={true}
- size="50"
+ size={50}
type="text"
value={this.state.name != null ? this.state.name : profile.name}
/>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx
index 975ca0a32db..5a7b22719db 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx
@@ -17,32 +17,27 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-/*:: import type { Profile } from '../propTypes'; */
import { deleteProfile } from '../../../api/quality-profiles';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { IProfile } from '../types';
-/*::
-type Props = {
- onClose: () => void,
- onDelete: () => void,
- onRequestFail: Object => void,
- profile: Profile
-};
-*/
+interface Props {
+ onClose: () => void;
+ onDelete: () => void;
+ onRequestFail: (reason: any) => void;
+ profile: IProfile;
+}
-/*::
-type State = {
- loading: boolean
-};
-*/
+interface State {
+ loading: boolean;
+ name: string | null;
+}
-export default class DeleteProfileForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { loading: false, name: null };
+export default class DeleteProfileForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false, name: null };
componentDidMount() {
this.mounted = true;
@@ -52,15 +47,15 @@ export default class DeleteProfileForm extends React.PureComponent {
this.mounted = false;
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
this.setState({ loading: true });
- deleteProfile(this.props.profile.key).then(this.props.onDelete, error => {
+ deleteProfile(this.props.profile.key).then(this.props.onDelete, (error: any) => {
if (this.mounted) {
this.setState({ loading: false });
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx
index 8a2b2f805f0..6d1ad5c0120 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx
@@ -17,9 +17,8 @@
* 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 * as React from 'react';
+import * as PropTypes from 'prop-types';
import { Link } from 'react-router';
import RenameProfileForm from './RenameProfileForm';
import CopyProfileForm from './CopyProfileForm';
@@ -28,31 +27,24 @@ import { translate } from '../../../helpers/l10n';
import { getRulesUrl } from '../../../helpers/urls';
import { setDefaultProfile } from '../../../api/quality-profiles';
import { getProfilePath, getProfileComparePath, getProfilesPath } from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- canAdmin: boolean,
- fromList: boolean,
- onRequestFail: Object => void,
- organization: ?string,
- profile: Profile,
- updateProfiles: () => Promise<*>
-};
-*/
-
-/*::
-type State = {
- copyFormOpen: boolean,
- deleteFormOpen: boolean,
- renameFormOpen: boolean
-};
-*/
-
-export default class ProfileActions extends React.PureComponent {
- /*:: props: Props; */
- /*:: state: State; */
+import { IProfile } from '../types';
+
+interface Props {
+ canAdmin: boolean;
+ fromList?: boolean;
+ onRequestFail: (reasong: any) => void;
+ organization: string | null;
+ profile: IProfile;
+ updateProfiles: () => Promise<void>;
+}
+
+interface State {
+ copyFormOpen: boolean;
+ deleteFormOpen: boolean;
+ renameFormOpen: boolean;
+}
+export default class ProfileActions extends React.PureComponent<Props, State> {
static defaultProps = {
fromList: false
};
@@ -61,7 +53,7 @@ export default class ProfileActions extends React.PureComponent {
router: PropTypes.object
};
- constructor(props /*: Props */) {
+ constructor(props: Props) {
super(props);
this.state = {
copyFormOpen: false,
@@ -70,12 +62,12 @@ export default class ProfileActions extends React.PureComponent {
};
}
- handleRenameClick = (event /*: Event */) => {
+ handleRenameClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ renameFormOpen: true });
};
- handleProfileRename = (name /*: string */) => {
+ handleProfileRename = (name: string) => {
this.closeRenameForm();
this.props.updateProfiles().then(() => {
if (!this.props.fromList) {
@@ -90,12 +82,12 @@ export default class ProfileActions extends React.PureComponent {
this.setState({ renameFormOpen: false });
};
- handleCopyClick = (event /*: Event */) => {
+ handleCopyClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ copyFormOpen: true });
};
- handleProfileCopy = (name /*: string */) => {
+ handleProfileCopy = (name: string) => {
this.props.updateProfiles().then(() => {
this.context.router.push(
getProfilePath(name, this.props.profile.language, this.props.organization)
@@ -107,12 +99,12 @@ export default class ProfileActions extends React.PureComponent {
this.setState({ copyFormOpen: false });
};
- handleSetDefaultClick = (e /*: SyntheticInputEvent */) => {
+ handleSetDefaultClick = (e: React.SyntheticEvent<HTMLElement>) => {
e.preventDefault();
setDefaultProfile(this.props.profile.key).then(this.props.updateProfiles);
};
- handleDeleteClick = (event /*: Event */) => {
+ handleDeleteClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ deleteFormOpen: true });
};
@@ -131,7 +123,9 @@ export default class ProfileActions extends React.PureComponent {
// FIXME use org, name and lang
const backupUrl =
- window.baseUrl + '/api/qualityprofiles/backup?profileKey=' + encodeURIComponent(profile.key);
+ (window as any).baseUrl +
+ '/api/qualityprofiles/backup?profileKey=' +
+ encodeURIComponent(profile.key);
const activateMoreUrl = getRulesUrl(
{
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx
index f44f53c9e35..ee6d302acdd 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx
@@ -17,32 +17,27 @@
* 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 * as React from 'react';
import Helmet from 'react-helmet';
import ProfileNotFound from './ProfileNotFound';
import ProfileHeader from '../details/ProfileHeader';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- children: React.Element<*>,
+interface Props {
+ canAdmin: boolean;
+ children: React.ReactElement<any>;
location: {
- pathname: string,
- query: { key?: string, language: string, name: string }
- },
- onRequestFail: Object => void,
- organization: ?string,
- profiles: Array<Profile>,
- router: { replace: ({}) => void },
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class ProfileContainer extends React.PureComponent {
- /*:: props: Props; */
+ pathname: string;
+ query: { key?: string; language: string; name: string };
+ };
+ onRequestFail: (reasong: any) => void;
+ organization: string | null;
+ profiles: IProfile[];
+ router: { replace: ({}) => void };
+ updateProfiles: () => Promise<void>;
+}
+export default class ProfileContainer extends React.PureComponent<Props> {
componentDidMount() {
const { location, profiles, router } = this.props;
if (location.query.key) {
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx
index ae878a4ba6b..947b15e419c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx
@@ -17,35 +17,20 @@
* 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 moment from 'moment';
+import * as React from 'react';
+import * as moment from 'moment';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- date?: string
-};
-*/
-
-export default class ProfileDate extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- const { date } = this.props;
-
- if (!date) {
- return (
- <span>
- {translate('never')}
- </span>
- );
- }
+interface Props {
+ date?: string;
+}
- return (
- <span title={moment(date).format('LLL')} data-toggle="tooltip">
+export default function ProfileDate({ date }: Props) {
+ return date
+ ? <span title={moment(date).format('LLL')} data-toggle="tooltip">
{moment(date).fromNow()}
</span>
- );
- }
+ : <span>
+ {translate('never')}
+ </span>;
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx
index 2ff0534c108..8b69532ad74 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx
@@ -17,32 +17,25 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import { getProfilePath } from '../utils';
-/*::
-type Props = {
- children?: React.Element<*>,
- language: string,
- name: string,
- organization: ?string
-};
-*/
-
-export default class ProfileLink extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ className?: string;
+ children?: React.ReactElement<any> | string;
+ language: string;
+ name: string;
+ organization: string | null;
+}
- render() {
- const { name, language, organization, children, ...other } = this.props;
- return (
- <Link
- to={getProfilePath(name, language, organization)}
- activeClassName="link-no-underline"
- {...other}>
- {children}
- </Link>
- );
- }
+export default function ProfileLink({ name, language, organization, children, ...other }: Props) {
+ return (
+ <Link
+ to={getProfilePath(name, language, organization)}
+ activeClassName="link-no-underline"
+ {...other}>
+ {children}
+ </Link>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx
index 7dce1cc0ce1..a6fd496502c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx
@@ -17,34 +17,27 @@
* 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 * as React from 'react';
import { IndexLink } from 'react-router';
import { translate } from '../../../helpers/l10n';
import { getProfilesPath } from '../utils';
-/*::
-type Props = {
- organization: ?string
-};
-*/
-
-export default class ProfileNotFound extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ organization: string | null;
+}
- render() {
- return (
- <div className="quality-profile-not-found">
- <div className="note spacer-bottom">
- <IndexLink to={getProfilesPath(this.props.organization)} className="text-muted">
- {translate('quality_profiles.page')}
- </IndexLink>
- </div>
+export default function ProfileNotFound(props: Props) {
+ return (
+ <div className="quality-profile-not-found">
+ <div className="note spacer-bottom">
+ <IndexLink to={getProfilesPath(props.organization)} className="text-muted">
+ {translate('quality_profiles.page')}
+ </IndexLink>
+ </div>
- <div>
- {translate('quality_profiles.not_found')}
- </div>
+ <div>
+ {translate('quality_profiles.not_found')}
</div>
- );
- }
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx
index 37d63394d21..1d1491975ec 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx
@@ -17,33 +17,27 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-/*:: import type { Profile } from '../propTypes'; */
import { renameProfile } from '../../../api/quality-profiles';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { IProfile } from '../types';
-/*::
-type Props = {
- onClose: () => void,
- onRename: string => void,
- onRequestFail: Object => void,
- profile: Profile
-};
-*/
+interface Props {
+ onClose: () => void;
+ onRename: (name: string) => void;
+ onRequestFail: (reason: any) => void;
+ profile: IProfile;
+}
-/*::
-type State = {
- loading: boolean,
- name: ?string
-};
-*/
+interface State {
+ loading: boolean;
+ name: string | null;
+}
-export default class RenameProfileForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { loading: false, name: null };
+export default class RenameProfileForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false, name: null };
componentDidMount() {
this.mounted = true;
@@ -53,16 +47,16 @@ export default class RenameProfileForm extends React.PureComponent {
this.mounted = false;
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => {
+ handleNameChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
this.setState({ name: event.currentTarget.value });
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
const { name } = this.state;
@@ -71,7 +65,7 @@ export default class RenameProfileForm extends React.PureComponent {
this.setState({ loading: true });
renameProfile(this.props.profile.key, name).then(
() => this.props.onRename(name),
- error => {
+ (error: any) => {
if (this.mounted) {
this.setState({ loading: false });
}
@@ -113,11 +107,11 @@ export default class RenameProfileForm extends React.PureComponent {
<input
autoFocus={true}
id="rename-profile-name"
- maxLength="100"
+ maxLength={100}
name="name"
onChange={this.handleNameChange}
required={true}
- size="50"
+ size={50}
type="text"
value={this.state.name != null ? this.state.name : profile.name}
/>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx
index 08aa98c6b32..1c0efc638ab 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
-import React from 'react';
+import * as React from 'react';
import Helmet from 'react-helmet';
import ProfileContainer from '../ProfileContainer';
import ProfileNotFound from '../ProfileNotFound';
@@ -31,9 +31,12 @@ it('should render ProfileHeader', () => {
const updateProfiles = jest.fn();
const output = shallow(
<ProfileContainer
- location={{ query: { language: 'js', name: 'fake' } }}
- profiles={profiles}
canAdmin={false}
+ location={{ pathname: '', query: { language: 'js', name: 'fake' } }}
+ onRequestFail={jest.fn()}
+ organization={null}
+ profiles={profiles}
+ router={{} as any}
updateProfiles={updateProfiles}>
<div />
</ProfileContainer>
@@ -52,10 +55,13 @@ it('should render ProfileNotFound', () => {
];
const output = shallow(
<ProfileContainer
- location={{ query: { language: 'js', name: 'random' } }}
- profiles={profiles}
canAdmin={false}
- updateProfiles={() => true}>
+ location={{ pathname: '', query: { language: 'js', name: 'random' } }}
+ onRequestFail={jest.fn()}
+ organization={null}
+ profiles={profiles}
+ router={{} as any}
+ updateProfiles={jest.fn()}>
<div />
</ProfileContainer>
);
@@ -67,9 +73,12 @@ it('should render Helmet', () => {
const updateProfiles = jest.fn();
const output = shallow(
<ProfileContainer
- location={{ query: { language: 'js', name: 'First Profile' } }}
- profiles={profiles}
canAdmin={false}
+ location={{ pathname: '', query: { language: 'js', name: 'First Profile' } }}
+ onRequestFail={jest.fn()}
+ organization={null}
+ profiles={profiles}
+ router={{} as any}
updateProfiles={updateProfiles}>
<div />
</ProfileContainer>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
index f7d019e63d8..fd8292c7d97 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
@@ -17,36 +17,30 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-import Select from 'react-select';
+import * as Select from 'react-select';
import { sortBy } from 'lodash';
import { changeProfileParent } from '../../../api/quality-profiles';
import { translate } from '../../../helpers/l10n';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- onChange: () => void,
- onClose: () => void,
- onRequestFail: Object => void,
- profile: Profile,
- profiles: Array<Profile>
-};
-*/
+interface Props {
+ onChange: () => void;
+ onClose: () => void;
+ onRequestFail: (reasong: any) => void;
+ profile: IProfile;
+ profiles: IProfile[];
+}
-/*::
-type State = {
- loading: boolean,
- selected: ?string
-};
-*/
+interface State {
+ loading: boolean;
+ selected: string | null;
+}
-export default class ChangeParentForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
+export default class ChangeParentForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = {
loading: false,
selected: null
};
@@ -59,28 +53,30 @@ export default class ChangeParentForm extends React.PureComponent {
this.mounted = false;
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleSelectChange = (option /*: { value: string } */) => {
+ handleSelectChange = (option: { value: string }) => {
this.setState({ selected: option.value });
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
const parent = this.state.selected;
if (parent != null) {
this.setState({ loading: true });
- changeProfileParent(this.props.profile.key, parent).then(this.props.onChange).catch(error => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- this.props.onRequestFail(error);
- });
+ changeProfileParent(this.props.profile.key, parent)
+ .then(this.props.onChange)
+ .catch((error: any) => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ this.props.onRequestFail(error);
+ });
}
};
@@ -122,7 +118,6 @@ export default class ChangeParentForm extends React.PureComponent {
</label>
<Select
clearable={false}
- id="change-profile-parent"
name="parentKey"
onChange={this.handleSelectChange}
options={options}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx
index a3277635118..19085883c03 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx
@@ -17,27 +17,23 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-import escapeHtml from 'escape-html';
-/*:: import type { Profile } from '../propTypes'; */
+import * as escapeHtml from 'escape-html';
import SelectList from '../../../components/SelectList';
import { translate } from '../../../helpers/l10n';
+import { IProfile } from '../types';
-/*::
-type Props = {
- onClose: () => void,
- organization: ?string,
- profile: Profile
-};
-*/
+interface Props {
+ onClose: () => void;
+ organization: string | null;
+ profile: IProfile;
+}
-export default class ChangeProjectsForm extends React.PureComponent {
- /*:: container: HTMLElement; */
- /*:: props: Props; */
+export default class ChangeProjectsForm extends React.PureComponent<Props> {
+ container: HTMLElement;
- handleCloseClick = (event /*: Event */) => {
+ handleCloseClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
@@ -46,17 +42,17 @@ export default class ChangeProjectsForm extends React.PureComponent {
const { key } = this.props.profile;
const searchUrl =
- window.baseUrl + '/api/qualityprofiles/projects?key=' + encodeURIComponent(key);
+ (window as any).baseUrl + '/api/qualityprofiles/projects?key=' + encodeURIComponent(key);
- new SelectList({
+ new (SelectList as any)({
searchUrl,
el: this.container,
width: '100%',
readOnly: false,
focusSearch: false,
- dangerouslyUnescapedHtmlFormat: item => escapeHtml(item.name),
- selectUrl: window.baseUrl + '/api/qualityprofiles/add_project',
- deselectUrl: window.baseUrl + '/api/qualityprofiles/remove_project',
+ dangerouslyUnescapedHtmlFormat: (item: { name: string }) => escapeHtml(item.name),
+ selectUrl: (window as any).baseUrl + '/api/qualityprofiles/add_project',
+ deselectUrl: (window as any).baseUrl + '/api/qualityprofiles/remove_project',
extra: { profileKey: key },
selectParameter: 'projectUuid',
selectParameterValue: 'uuid',
@@ -91,7 +87,7 @@ export default class ChangeProjectsForm extends React.PureComponent {
</div>
<div className="modal-body">
- <div id="profile-projects" ref={node => (this.container = node)} />
+ <div id="profile-projects" ref={node => (this.container = node as HTMLElement)} />
</div>
<div className="modal-foot">
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx
index b157db49a68..a01130a889b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx
@@ -17,43 +17,36 @@
* 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 * as React from 'react';
import ProfileRules from './ProfileRules';
import ProfileProjects from './ProfileProjects';
import ProfileInheritance from './ProfileInheritance';
import ProfileExporters from './ProfileExporters';
-/*:: import type { Profile, Exporter } from '../propTypes'; */
+import { IExporter, IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- exporters: Array<Exporter>,
- onRequestFail: Object => void,
- organization: ?string,
- profile: Profile,
- profiles: Array<Profile>,
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class ProfileDetails extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ canAdmin: boolean;
+ exporters: IExporter[];
+ onRequestFail: (reasong: any) => void;
+ organization: string | null;
+ profile: IProfile;
+ profiles: IProfile[];
+ updateProfiles: () => Promise<void>;
+}
- render() {
- return (
- <div>
- <div className="quality-profile-grid">
- <div className="quality-profile-grid-left">
- <ProfileRules {...this.props} />
- <ProfileExporters {...this.props} />
- </div>
- <div className="quality-profile-grid-right">
- <ProfileInheritance {...this.props} />
- <ProfileProjects {...this.props} />
- </div>
+export default function ProfileDetails(props: Props) {
+ return (
+ <div>
+ <div className="quality-profile-grid">
+ <div className="quality-profile-grid-left">
+ <ProfileRules {...props} />
+ <ProfileExporters {...props} />
+ </div>
+ <div className="quality-profile-grid-right">
+ <ProfileInheritance {...props} />
+ <ProfileProjects {...props} />
</div>
</div>
- );
- }
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx
index 04f3c58df29..71913fae114 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx
@@ -17,28 +17,23 @@
* 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 { stringify } from 'querystring';
-import React from 'react';
+import * as React from 'react';
import { translate } from '../../../helpers/l10n';
-/*:: import type { Profile, Exporter } from '../propTypes'; */
+import { IProfile, IExporter } from '../types';
-/*::
-type Props = {
- exporters: Array<Exporter>,
- organization: ?string,
- profile: Profile
-};
-*/
-
-export default class ProfileExporters extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ exporters: IExporter[];
+ organization: string | null;
+ profile: IProfile;
+}
- getExportUrl(exporter /*: Exporter */) {
+export default class ProfileExporters extends React.PureComponent<Props> {
+ getExportUrl(exporter: IExporter) {
const { organization, profile } = this.props;
const path = '/api/qualityprofiles/export';
- const parameters /*: { [string]: string } */ = {
+ const parameters = {
exporterKey: exporter.key,
language: profile.language,
name: profile.name
@@ -46,7 +41,7 @@ export default class ProfileExporters extends React.PureComponent {
if (organization) {
Object.assign(parameters, { organization });
}
- return window.baseUrl + path + '?' + stringify(parameters);
+ return (window as any).baseUrl + path + '?' + stringify(parameters);
}
render() {
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx
index f5691c5ccea..ba0598251d6 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { Link, IndexLink } from 'react-router';
import ProfileLink from '../components/ProfileLink';
import ProfileActions from '../components/ProfileActions';
@@ -31,21 +30,17 @@ import {
getProfilesForLanguagePath,
getProfileChangelogPath
} from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- onRequestFail: Object => void,
- organization: ?string,
- profile: Profile,
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class ProfileHeader extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ canAdmin: boolean;
+ onRequestFail: (reasong: any) => void;
+ profile: IProfile;
+ organization: string | null;
+ updateProfiles: () => Promise<void>;
+}
+export default class ProfileHeader extends React.PureComponent<Props> {
renderUpdateDate() {
const { profile } = this.props;
let inner = (
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
index 9669bd0aa11..a7c6173deec 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
@@ -17,51 +17,44 @@
* 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 classNames from 'classnames';
+import * as React from 'react';
+import * as classNames from 'classnames';
import ProfileInheritanceBox from './ProfileInheritanceBox';
import ChangeParentForm from './ChangeParentForm';
import { translate } from '../../../helpers/l10n';
import { getProfileInheritance } from '../../../api/quality-profiles';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- canAdmin: boolean,
- onRequestFail: Object => void,
- organization: ?string,
- profile: Profile,
- profiles: Array<Profile>,
- updateProfiles: () => Promise<*>
-};
-*/
-
-/*::
-type ProfileInheritanceDetails = {
- activeRuleCount: number,
- isBuiltIn: boolean,
- key: string,
- language: string,
- name: string,
- overridingRuleCount?: number
-};
-*/
-
-/*::
-type State = {
- ancestors?: Array<ProfileInheritanceDetails>,
- children?: Array<ProfileInheritanceDetails>,
- formOpen: boolean,
- loading: boolean,
- profile?: ProfileInheritanceDetails
-};
-*/
-
-export default class ProfileInheritance extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
+import { IProfile } from '../types';
+
+interface Props {
+ canAdmin: boolean;
+ onRequestFail: (reason: any) => void;
+ organization: string | null;
+ profile: IProfile;
+ profiles: IProfile[];
+ updateProfiles: () => Promise<void>;
+}
+
+interface ProfileInheritanceDetails {
+ activeRuleCount: number;
+ isBuiltIn: boolean;
+ key: string;
+ language: string;
+ name: string;
+ overridingRuleCount?: number;
+}
+
+interface State {
+ ancestors?: Array<ProfileInheritanceDetails>;
+ children?: Array<ProfileInheritanceDetails>;
+ formOpen: boolean;
+ loading: boolean;
+ profile?: ProfileInheritanceDetails;
+}
+
+export default class ProfileInheritance extends React.PureComponent<Props, State> {
+ mounted: boolean;
+
+ state: State = {
formOpen: false,
loading: true
};
@@ -71,7 +64,7 @@ export default class ProfileInheritance extends React.PureComponent {
this.loadData();
}
- componentDidUpdate(prevProps /*: Props */) {
+ componentDidUpdate(prevProps: Props) {
if (prevProps.profile !== this.props.profile) {
this.loadData();
}
@@ -82,7 +75,7 @@ export default class ProfileInheritance extends React.PureComponent {
}
loadData() {
- getProfileInheritance(this.props.profile.key).then(r => {
+ getProfileInheritance(this.props.profile.key).then((r: any) => {
if (this.mounted) {
const { ancestors, children } = r;
this.setState({
@@ -95,7 +88,7 @@ export default class ProfileInheritance extends React.PureComponent {
});
}
- handleChangeParentClick = (event /*: Event */) => {
+ handleChangeParentClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ formOpen: true });
};
@@ -153,15 +146,16 @@ export default class ProfileInheritance extends React.PureComponent {
/>
)}
- <ProfileInheritanceBox
- className={currentClassName}
- depth={ancestors ? ancestors.length : 0}
- displayLink={false}
- extendsBuiltIn={extendsBuiltIn}
- language={profile.language}
- organization={this.props.organization}
- profile={this.state.profile}
- />
+ {this.state.profile != null &&
+ <ProfileInheritanceBox
+ className={currentClassName}
+ depth={ancestors ? ancestors.length : 0}
+ displayLink={false}
+ extendsBuiltIn={extendsBuiltIn}
+ language={profile.language}
+ organization={this.props.organization}
+ profile={this.state.profile}
+ />}
{this.state.children != null &&
this.state.children.map(child =>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js
deleted file mode 100644
index 1adf7c7322b..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 ProfileLink from '../components/ProfileLink';
-import BuiltInBadge from '../components/BuiltInBadge';
-import Tooltip from '../../../components/controls/Tooltip';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-
-/*::
-type Props = {|
- className?: string,
- depth: number,
- displayLink?: boolean,
- extendsBuiltIn?: boolean,
- language: string,
- organization: ?string,
- profile: {
- activeRuleCount: number,
- isBuiltIn: boolean,
- key: string,
- language: string,
- name: string,
- overridingRuleCount?: number
- }
-|};
-*/
-
-export default class ProfileInheritanceBox extends React.PureComponent {
- /*:: props: Props; */
-
- static defaultProps = {
- displayLink: true
- };
-
- render() {
- const { profile, className, extendsBuiltIn } = this.props;
- const offset = 25 * this.props.depth;
-
- return (
- <tr className={className}>
- <td>
- <div style={{ paddingLeft: offset }}>
- {this.props.displayLink
- ? <ProfileLink
- language={this.props.language}
- name={profile.name}
- organization={this.props.organization}>
- {profile.name}
- </ProfileLink>
- : profile.name}
- {profile.isBuiltIn && <BuiltInBadge className="spacer-left" />}
- {extendsBuiltIn &&
- <Tooltip overlay={translate('quality_profiles.extends_built_in')}>
- <i className="icon-help spacer-left" />
- </Tooltip>}
- </div>
- </td>
-
- <td>
- {translateWithParameters('quality_profile.x_active_rules', profile.activeRuleCount)}
- </td>
-
- <td>
- {profile.overridingRuleCount != null &&
- <p>
- {translateWithParameters(
- 'quality_profiles.x_overridden_rules',
- profile.overridingRuleCount
- )}
- </p>}
- </td>
- </tr>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx
new file mode 100644
index 00000000000..2455e39ae03
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 ProfileLink from '../components/ProfileLink';
+import BuiltInBadge from '../components/BuiltInBadge';
+import Tooltip from '../../../components/controls/Tooltip';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+
+interface Props {
+ className?: string;
+ depth: number;
+ displayLink?: boolean;
+ extendsBuiltIn?: boolean;
+ language: string;
+ organization: string | null;
+ profile: {
+ activeRuleCount: number;
+ isBuiltIn: boolean;
+ key: string;
+ language: string;
+ name: string;
+ overridingRuleCount?: number;
+ };
+}
+
+export default function ProfileInheritanceBox({ displayLink = true, ...props }: Props) {
+ const { profile, className, extendsBuiltIn } = props;
+ const offset = 25 * props.depth;
+
+ return (
+ <tr className={className}>
+ <td>
+ <div style={{ paddingLeft: offset }}>
+ {displayLink
+ ? <ProfileLink
+ language={props.language}
+ name={profile.name}
+ organization={props.organization}>
+ {profile.name}
+ </ProfileLink>
+ : profile.name}
+ {profile.isBuiltIn && <BuiltInBadge className="spacer-left" />}
+ {extendsBuiltIn &&
+ <Tooltip overlay={translate('quality_profiles.extends_built_in')}>
+ <i className="icon-help spacer-left" />
+ </Tooltip>}
+ </div>
+ </td>
+
+ <td>
+ {translateWithParameters('quality_profile.x_active_rules', profile.activeRuleCount)}
+ </td>
+
+ <td>
+ {profile.overridingRuleCount != null &&
+ <p>
+ {translateWithParameters(
+ 'quality_profiles.x_overridden_rules',
+ profile.overridingRuleCount
+ )}
+ </p>}
+ </td>
+ </tr>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx
index 984b7995b0f..92d30c277ba 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx
@@ -17,37 +17,32 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import ChangeProjectsForm from './ChangeProjectsForm';
import QualifierIcon from '../../../components/shared/QualifierIcon';
import { getProfileProjects } from '../../../api/quality-profiles';
import { translate } from '../../../helpers/l10n';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- canAdmin: boolean,
- organization: ?string,
- profile: Profile,
- updateProfiles: () => Promise<*>
-};
-*/
-
-/*::
-type State = {
- formOpen: boolean,
- loading: boolean,
- more?: boolean,
- projects: ?Array<*>
-};
-*/
-
-export default class ProfileProjects extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
+import { IProfile } from '../types';
+
+interface Props {
+ canAdmin: boolean;
+ organization: string | null;
+ profile: IProfile;
+ updateProfiles: () => Promise<void>;
+}
+
+interface State {
+ formOpen: boolean;
+ loading: boolean;
+ more?: boolean;
+ projects: Array<{ key: string; name: string; uuid: string }> | null;
+}
+
+export default class ProfileProjects extends React.PureComponent<Props, State> {
+ mounted: boolean;
+
+ state: State = {
formOpen: false,
loading: true,
projects: null
@@ -58,7 +53,7 @@ export default class ProfileProjects extends React.PureComponent {
this.loadProjects();
}
- componentDidUpdate(prevProps /*: Props */) {
+ componentDidUpdate(prevProps: Props) {
if (prevProps.profile !== this.props.profile) {
this.loadProjects();
}
@@ -74,7 +69,7 @@ export default class ProfileProjects extends React.PureComponent {
}
const data = { key: this.props.profile.key };
- getProfileProjects(data).then(r => {
+ getProfileProjects(data).then((r: any) => {
if (this.mounted) {
this.setState({
projects: r.results,
@@ -85,7 +80,7 @@ export default class ProfileProjects extends React.PureComponent {
});
}
- handleChangeClick = (event /*: Event */) => {
+ handleChangeClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ formOpen: true });
};
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx
index ceb3fbed7c1..2fc1879190c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import { keyBy } from 'lodash';
import ProfileRulesRowOfType from './ProfileRulesRowOfType';
@@ -29,33 +28,34 @@ import { searchRules, takeFacet } from '../../../api/rules';
import { getQualityProfiles } from '../../../api/quality-profiles';
import { getRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
const TYPES = ['BUG', 'VULNERABILITY', 'CODE_SMELL'];
-/*::
-type Props = {
- canAdmin: boolean,
- organization: ?string,
- profile: Profile
-};
-*/
-
-/*::
-type State = {
- activatedTotal: ?number,
- activatedByType?: { [string]: ?{ val: string, count: ?number } },
- allByType?: { [string]: ?{ val: string, count: ?number } },
- compareToSonarWay: ?{ profile: string, profileName: string, missingRuleCount: number },
- loading: boolean,
- total: ?number
-};
-*/
-
-export default class ProfileRules extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
+interface Props {
+ canAdmin: boolean;
+ organization: string | null;
+ profile: IProfile;
+}
+
+interface ByType {
+ val: string;
+ count: number | null;
+}
+
+interface State {
+ activatedTotal: number | null;
+ activatedByType: { [type: string]: ByType };
+ allByType: { [type: string]: ByType };
+ compareToSonarWay: { profile: string; profileName: string; missingRuleCount: number } | null;
+ loading: boolean;
+ total: number | null;
+}
+
+export default class ProfileRules extends React.PureComponent<Props, State> {
+ mounted: boolean;
+
+ state: State = {
activatedTotal: null,
activatedByType: keyBy(TYPES.map(t => ({ val: t, count: null })), 'val'),
allByType: keyBy(TYPES.map(t => ({ val: t, count: null })), 'val'),
@@ -69,7 +69,7 @@ export default class ProfileRules extends React.PureComponent {
this.loadRules();
}
- componentDidUpdate(prevProps /*: Props */) {
+ componentDidUpdate(prevProps: Props) {
if (prevProps.profile !== this.props.profile) {
this.loadRules();
}
@@ -117,8 +117,8 @@ export default class ProfileRules extends React.PureComponent {
const [allRules, activatedRules, showProfile] = responses;
this.setState({
activatedTotal: activatedRules.total,
- allByType: keyBy(takeFacet(allRules, 'types'), 'val'),
- activatedByType: keyBy(takeFacet(activatedRules, 'types'), 'val'),
+ allByType: keyBy<ByType>(takeFacet(allRules, 'types'), 'val'),
+ activatedByType: keyBy<ByType>(takeFacet(activatedRules, 'types'), 'val'),
compareToSonarWay: showProfile && showProfile.compareToSonarWay,
loading: false,
total: allRules.total
@@ -127,13 +127,13 @@ export default class ProfileRules extends React.PureComponent {
});
}
- getRulesCountForType(type /*: string */) /*: ?number */ {
+ getRulesCountForType(type: string) {
return this.state.activatedByType && this.state.activatedByType[type]
? this.state.activatedByType[type].count
: null;
}
- getRulesTotalForType(type /*: string */) /*: ?number */ {
+ getRulesTotalForType(type: string) {
return this.state.allByType && this.state.allByType[type]
? this.state.allByType[type].count
: null;
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx
index a74e0829787..3e69b0c86be 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx
@@ -17,18 +17,19 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import Tooltip from '../../../components/controls/Tooltip';
import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = { activeDeprecatedRules: number, organization: ?string, profile: string };
-*/
+interface Props {
+ activeDeprecatedRules: number;
+ organization: string | null;
+ profile: string;
+}
-export default function ProfileRulesDeprecatedWarning(props /*: Props */) {
+export default function ProfileRulesDeprecatedWarning(props: Props) {
const url = getDeprecatedActiveRulesUrl({ qprofile: props.profile }, props.organization);
return (
<div className="quality-profile-rules-deprecated clearfix">
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.tsx
index a899b495348..b13a5ed9797 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.tsx
@@ -17,25 +17,22 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
import { formatMeasure } from '../../../helpers/measures';
import { getRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- count: ?number,
- organization: ?string,
- qprofile: string,
- total: ?number,
- type: string
-};
-*/
+interface Props {
+ count: number | null;
+ organization: string | null;
+ qprofile: string;
+ total: number | null;
+ type: string;
+}
-export default function ProfileRulesRowOfType(props /*: Props */) {
+export default function ProfileRulesRowOfType(props: Props) {
const activeRulesUrl = getRulesUrl(
{ qprofile: props.qprofile, activation: 'true', types: props.type },
props.organization
@@ -60,14 +57,14 @@ export default function ProfileRulesRowOfType(props /*: Props */) {
<td className="thin nowrap text-right">
{props.count != null &&
<Link to={activeRulesUrl}>
- {formatMeasure(props.count, 'SHORT_INT')}
+ {formatMeasure(props.count, 'SHORT_INT', null)}
</Link>}
</td>
<td className="thin nowrap text-right">
{inactiveCount != null &&
(inactiveCount > 0
? <Link to={inactiveRulesUrl} className="small text-muted">
- {formatMeasure(inactiveCount, 'SHORT_INT')}
+ {formatMeasure(inactiveCount, 'SHORT_INT', null)}
</Link>
: <span className="note text-muted">0</span>)}
</td>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx
index 1cb16d7623c..4f97d20776b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx
@@ -17,23 +17,20 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import { formatMeasure } from '../../../helpers/measures';
import { getRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- count: ?number,
- organization: ?string,
- qprofile: string,
- total: ?number
-};
-*/
+interface Props {
+ count: number | null;
+ organization: string | null;
+ qprofile: string;
+ total: number | null;
+}
-export default function ProfileRulesRowTotal(props /*: Props */) {
+export default function ProfileRulesRowTotal(props: Props) {
const activeRulesUrl = getRulesUrl(
{ qprofile: props.qprofile, activation: 'true' },
props.organization
@@ -58,7 +55,7 @@ export default function ProfileRulesRowTotal(props /*: Props */) {
{props.count != null &&
<Link to={activeRulesUrl}>
<strong>
- {formatMeasure(props.count, 'SHORT_INT')}
+ {formatMeasure(props.count, 'SHORT_INT', null)}
</strong>
</Link>}
</td>
@@ -67,7 +64,7 @@ export default function ProfileRulesRowTotal(props /*: Props */) {
(inactiveCount > 0
? <Link to={inactiveRulesUrl} className="small text-muted">
<strong>
- {formatMeasure(inactiveCount, 'SHORT_INT')}
+ {formatMeasure(inactiveCount, 'SHORT_INT', null)}
</strong>
</Link>
: <span className="note text-muted">0</span>)}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx
index 1e4a4c27c46..cc7470d93ab 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx
@@ -17,24 +17,21 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import Tooltip from '../../../components/controls/Tooltip';
import { getRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- language: string,
- organization: ?string,
- profile: string,
- sonarway: string,
- sonarWayMissingRules: number
-};
-*/
+interface Props {
+ language: string;
+ organization: string | null;
+ profile: string;
+ sonarway: string;
+ sonarWayMissingRules: number;
+}
-export default function ProfileRulesSonarWayComparison(props /*: Props */) {
+export default function ProfileRulesSonarWayComparison(props: Props) {
const url = getRulesUrl(
{
qprofile: props.profile,
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx
index cd62b6a21d6..91e5ed96cfc 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx
@@ -17,7 +17,7 @@
* 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 * as React from 'react';
import { shallow } from 'enzyme';
import ProfileRules from '../ProfileRules';
import { doAsync } from '../../../../helpers/testUtils';
@@ -68,11 +68,9 @@ const apiResponseActive = {
};
// Mock api some api functions
-// eslint-disable-next-line
-apiRules.searchRules = data =>
+(apiRules as any).searchRules = (data: any) =>
Promise.resolve(data.activation === 'true' ? apiResponseActive : apiResponseAll);
-// eslint-disable-next-line
-apiQP.getQualityProfiles = () =>
+(apiQP as any).getQualityProfiles = () =>
Promise.resolve({
compareToSonarWay: {
profile: 'sonarway',
@@ -83,8 +81,9 @@ apiQP.getQualityProfiles = () =>
it('should render the quality profiles rules with sonarway comparison', () => {
const wrapper = shallow(<ProfileRules canAdmin={false} organization="foo" profile={PROFILE} />);
- wrapper.instance().mounted = true;
- wrapper.instance().loadRules();
+ const instance = wrapper.instance() as any;
+ instance.mounted = true;
+ instance.loadRules();
return doAsync(() => {
wrapper.update();
expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(1);
@@ -123,13 +122,13 @@ it('should not show a button to activate more rules on built in profiles', () =>
});
it('should not show sonarway comparison for built in profiles', () => {
- // eslint-disable-next-line
- apiQP.getQualityProfiles = jest.fn(() => Promise.resolve());
+ (apiQP as any).getQualityProfiles = jest.fn(() => Promise.resolve());
const wrapper = shallow(
<ProfileRules canAdmin={true} organization={null} profile={{ ...PROFILE, isBuiltIn: true }} />
);
- wrapper.instance().mounted = true;
- wrapper.instance().loadRules();
+ const instance = wrapper.instance() as any;
+ instance.mounted = true;
+ instance.loadRules();
return doAsync(() => {
wrapper.update();
expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(0);
@@ -138,8 +137,7 @@ it('should not show sonarway comparison for built in profiles', () => {
});
it('should not show sonarway comparison if there is no missing rules', () => {
- // eslint-disable-next-line
- apiQP.getQualityProfiles = jest.fn(() =>
+ (apiQP as any).getQualityProfiles = jest.fn(() =>
Promise.resolve({
compareToSonarWay: {
profile: 'sonarway',
@@ -149,8 +147,9 @@ it('should not show sonarway comparison if there is no missing rules', () => {
})
);
const wrapper = shallow(<ProfileRules canAdmin={true} organization={null} profile={PROFILE} />);
- wrapper.instance().mounted = true;
- wrapper.instance().loadRules();
+ const instance = wrapper.instance() as any;
+ instance.mounted = true;
+ instance.loadRules();
return doAsync(() => {
wrapper.update();
expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(1);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx
index 9a3387280e9..c306d6856c3 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { shallow } from 'enzyme';
import ProfileRulesDeprecatedWarning from '../ProfileRulesDeprecatedWarning';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx
index dea445e01bf..b8a3bc56505 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { shallow } from 'enzyme';
import ProfileRulesRowOfType from '../ProfileRulesRowOfType';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx
index 20f2d697d5f..3428f58ea6b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { shallow } from 'enzyme';
import ProfileRulesRowTotal from '../ProfileRulesRowTotal';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx
index ef992d630ba..50914b7a094 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { shallow } from 'enzyme';
import ProfileRulesSonarWayComparison from '../ProfileRulesSonarWayComparison';
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap
index 22be4264e2a..22be4264e2a 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap
index 54fa91cc49d..54fa91cc49d 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap
index 62866095c17..62866095c17 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap
index f8686659326..f8686659326 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.js.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap
index 481846b23ad..481846b23ad 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
index d95984ce033..8f6d589cff8 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
@@ -17,39 +17,33 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
-import Select from 'react-select';
+import * as Select from 'react-select';
import { sortBy } from 'lodash';
import { getImporters, createQualityProfile } from '../../../api/quality-profiles';
import { translate } from '../../../helpers/l10n';
-/*::
-type Props = {
- languages: Array<{ key: string, name: string }>,
- onClose: () => void,
- onCreate: Function,
- onRequestFail: Object => void,
- organization: ?string
-};
-*/
-
-/*::
-type State = {
- importers: Array<{ key: string, languages: Array<string>, name: string }>,
- language?: string,
- loading: boolean,
- name: string,
- preloading: boolean
-};
-*/
-
-export default class CreateProfileForm extends React.PureComponent {
+interface Props {
+ languages: Array<{ key: string; name: string }>;
+ onClose: () => void;
+ onCreate: Function;
+ onRequestFail: (reasong: any) => void;
+ organization: string | null;
+}
+
+interface State {
+ importers: Array<{ key: string; languages: Array<string>; name: string }>;
+ language?: string;
+ loading: boolean;
+ name: string;
+ preloading: boolean;
+}
+
+export default class CreateProfileForm extends React.PureComponent<Props, State> {
/*:: form: HTMLFormElement; */
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { importers: [], loading: false, name: '', preloading: true };
+ mounted: boolean;
+ state: State = { importers: [], loading: false, name: '', preloading: true };
componentDidMount() {
this.mounted = true;
@@ -61,39 +55,41 @@ export default class CreateProfileForm extends React.PureComponent {
}
fetchImporters() {
- getImporters().then(importers => {
- if (this.mounted) {
- this.setState({ importers, preloading: false });
+ getImporters().then(
+ (importers: Array<{ key: string; languages: Array<string>; name: string }>) => {
+ if (this.mounted) {
+ this.setState({ importers, preloading: false });
+ }
}
- });
+ );
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => {
+ handleNameChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
this.setState({ name: event.currentTarget.value });
};
- handleLanguageChange = (option /*: { value: string } */) => {
+ handleLanguageChange = (option: { value: string }) => {
this.setState({ language: option.value });
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
this.setState({ loading: true });
- const data = new FormData(this.form);
+ const data = new FormData(event.currentTarget);
if (this.props.organization) {
data.append('organization', this.props.organization);
}
createQualityProfile(data).then(
- response => this.props.onCreate(response.profile),
- error => {
+ (response: any) => this.props.onCreate(response.profile),
+ (error: any) => {
if (this.mounted) {
this.setState({ loading: false });
}
@@ -118,10 +114,7 @@ export default class CreateProfileForm extends React.PureComponent {
className="modal"
overlayClassName="modal-overlay"
onRequestClose={this.props.onClose}>
- <form
- id="create-profile-form"
- onSubmit={this.handleFormSubmit}
- ref={node => (this.form = node)}>
+ <form id="create-profile-form" onSubmit={this.handleFormSubmit}>
<div className="modal-head">
<h2>
{header}
@@ -141,11 +134,11 @@ export default class CreateProfileForm extends React.PureComponent {
<input
autoFocus={true}
id="create-profile-name"
- maxLength="100"
+ maxLength={100}
name="name"
onChange={this.handleNameChange}
required={true}
- size="50"
+ size={50}
type="text"
value={this.state.name}
/>
@@ -157,7 +150,6 @@ export default class CreateProfileForm extends React.PureComponent {
</label>
<Select
clearable={false}
- id="create-profile-language"
name="language"
onChange={this.handleLanguageChange}
options={languages.map(language => ({
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx
index 4be28f3dd04..f238580d1e2 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx
@@ -17,32 +17,23 @@
* 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 * as React from 'react';
import EvolutionDeprecated from './EvolutionDeprecated';
import EvolutionStagnant from './EvolutionStagnant';
import EvolutionRules from './EvolutionRules';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- organization: ?string,
- profiles: Array<Profile>
-};
-*/
-
-export default class Evolution extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- const { organization, profiles } = this.props;
+interface Props {
+ organization: string | null;
+ profiles: IProfile[];
+}
- return (
- <div className="quality-profiles-evolution">
- <EvolutionDeprecated organization={organization} profiles={profiles} />
- <EvolutionStagnant organization={organization} profiles={profiles} />
- <EvolutionRules organization={organization} />
- </div>
- );
- }
+export default function Evolution({ organization, profiles }: Props) {
+ return (
+ <div className="quality-profiles-evolution">
+ <EvolutionDeprecated organization={organization} profiles={profiles} />
+ <EvolutionStagnant organization={organization} profiles={profiles} />
+ <EvolutionRules organization={organization} />
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js
deleted file mode 100644
index a3eaef27bd2..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 { sortBy } from 'lodash';
-import ProfileLink from '../components/ProfileLink';
-import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls';
-import { translateWithParameters, translate } from '../../../helpers/l10n';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- organization: ?string,
- profiles: Array<Profile>
-};
-*/
-
-export default class EvolutionDeprecated extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- const profilesWithDeprecations = this.props.profiles.filter(
- profile => profile.activeDeprecatedRuleCount > 0
- );
-
- if (profilesWithDeprecations.length === 0) {
- return null;
- }
-
- const sortedProfiles = sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount);
-
- return (
- <div className="quality-profile-box quality-profiles-evolution-deprecated">
- <div className="spacer-bottom">
- <strong>
- {translate('quality_profiles.deprecated_rules')}
- </strong>
- </div>
- <div className="spacer-bottom">
- {translateWithParameters(
- 'quality_profiles.deprecated_rules_are_still_activated',
- profilesWithDeprecations.length
- )}
- </div>
- <ul>
- {sortedProfiles.map(profile =>
- <li key={profile.key} className="spacer-top">
- <div className="text-ellipsis">
- <ProfileLink
- className="link-no-underline"
- language={profile.language}
- name={profile.name}
- organization={this.props.organization}>
- {profile.name}
- </ProfileLink>
- </div>
- <div className="note">
- {profile.languageName}
- {', '}
- <Link
- to={getDeprecatedActiveRulesUrl(
- { qprofile: profile.key },
- this.props.organization
- )}
- className="text-muted">
- {translateWithParameters(
- 'quality_profile.x_rules',
- profile.activeDeprecatedRuleCount
- )}
- </Link>
- </div>
- </li>
- )}
- </ul>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx
new file mode 100644
index 00000000000..0f8da8a3e9a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.tsx
@@ -0,0 +1,86 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { sortBy } from 'lodash';
+import ProfileLink from '../components/ProfileLink';
+import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls';
+import { translateWithParameters, translate } from '../../../helpers/l10n';
+import { IProfile } from '../types';
+
+interface Props {
+ organization: string | null;
+ profiles: IProfile[];
+}
+
+export default function EvolutionDeprecated(props: Props) {
+ const profilesWithDeprecations = props.profiles.filter(
+ profile => profile.activeDeprecatedRuleCount > 0
+ );
+
+ if (profilesWithDeprecations.length === 0) {
+ return null;
+ }
+
+ const sortedProfiles = sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount);
+
+ return (
+ <div className="quality-profile-box quality-profiles-evolution-deprecated">
+ <div className="spacer-bottom">
+ <strong>
+ {translate('quality_profiles.deprecated_rules')}
+ </strong>
+ </div>
+ <div className="spacer-bottom">
+ {translateWithParameters(
+ 'quality_profiles.deprecated_rules_are_still_activated',
+ profilesWithDeprecations.length
+ )}
+ </div>
+ <ul>
+ {sortedProfiles.map(profile =>
+ <li key={profile.key} className="spacer-top">
+ <div className="text-ellipsis">
+ <ProfileLink
+ className="link-no-underline"
+ language={profile.language}
+ name={profile.name}
+ organization={props.organization}>
+ {profile.name}
+ </ProfileLink>
+ </div>
+ <div className="note">
+ {profile.languageName}
+ {', '}
+ <Link
+ to={getDeprecatedActiveRulesUrl({ qprofile: profile.key }, props.organization)}
+ className="text-muted">
+ {translateWithParameters(
+ 'quality_profile.x_rules',
+ profile.activeDeprecatedRuleCount
+ )}
+ </Link>
+ </div>
+ </li>
+ )}
+ </ul>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx
index 042c04a73b6..c9e3e1f46e1 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx
@@ -17,10 +17,9 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
-import moment from 'moment';
+import * as moment from 'moment';
import { sortBy } from 'lodash';
import { searchRules } from '../../../api/rules';
import { translateWithParameters, translate } from '../../../helpers/l10n';
@@ -31,24 +30,33 @@ const RULES_LIMIT = 10;
const PERIOD_START_MOMENT = moment().subtract(1, 'year');
-function parseRules(r) {
+function parseRules(r: any) {
const { rules, actives } = r;
- return rules.map(rule => {
+ return rules.map((rule: any) => {
const activations = actives[rule.key];
return { ...rule, activations: activations ? activations.length : 0 };
});
}
-/*::
-type Props = {
- organization: ?string
-};
-*/
+interface Props {
+ organization: string | null;
+}
+
+interface IRule {
+ activations: number;
+ key: string;
+ langName: string;
+ name: string;
+}
+
+interface State {
+ latestRules?: Array<IRule>;
+ latestRulesTotal?: number;
+}
-export default class EvolutionRules extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state = {};
+export default class EvolutionRules extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = {};
componentDidMount() {
this.mounted = true;
@@ -68,10 +76,10 @@ export default class EvolutionRules extends React.PureComponent {
f: 'name,langName,actives'
};
- searchRules(data).then(r => {
+ searchRules(data).then((r: any) => {
if (this.mounted) {
this.setState({
- latestRules: sortBy(parseRules(r), 'langName'),
+ latestRules: sortBy<IRule>(parseRules(r), 'langName'),
latestRulesTotal: r.total
});
}
@@ -79,7 +87,7 @@ export default class EvolutionRules extends React.PureComponent {
}
render() {
- if (!this.state.latestRulesTotal) {
+ if (!this.state.latestRulesTotal || !this.state.latestRules) {
return null;
}
@@ -125,7 +133,7 @@ export default class EvolutionRules extends React.PureComponent {
{this.state.latestRulesTotal > RULES_LIMIT &&
<div className="spacer-top">
<Link to={newRulesUrl} className="small">
- {translate('see_all')} {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT')}
+ {translate('see_all')} {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT', null)}
</Link>
</div>}
</div>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js
deleted file mode 100644
index 1eda4c0b8e3..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 moment from 'moment';
-import ProfileLink from '../components/ProfileLink';
-import { translate } from '../../../helpers/l10n';
-import { isStagnant } from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
-
-/*::
-type Props = {
- organization: ?string,
- profiles: Array<Profile>
-};
-*/
-
-export default class EvolutionStagnant extends React.PureComponent {
- /*:: props: Props; */
-
- render() {
- // TODO filter built-in out
-
- const outdated = this.props.profiles.filter(isStagnant);
-
- if (outdated.length === 0) {
- return null;
- }
-
- return (
- <div className="quality-profile-box quality-profiles-evolution-stagnant">
- <div className="spacer-bottom">
- <strong>
- {translate('quality_profiles.stagnant_profiles')}
- </strong>
- </div>
- <div className="spacer-bottom">
- {translate('quality_profiles.not_updated_more_than_year')}
- </div>
- <ul>
- {outdated.map(profile =>
- <li key={profile.key} className="spacer-top">
- <div className="text-ellipsis">
- <ProfileLink
- className="link-no-underline"
- language={profile.language}
- name={profile.name}
- organization={this.props.organization}>
- {profile.name}
- </ProfileLink>
- </div>
- <div className="note">
- {profile.languageName}
- {', '}
- updated on {moment(profile.rulesUpdatedAt).format('LL')}
- </div>
- </li>
- )}
- </ul>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx
new file mode 100644
index 00000000000..8b3fc2eae90
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.tsx
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 * as moment from 'moment';
+import ProfileLink from '../components/ProfileLink';
+import { translate } from '../../../helpers/l10n';
+import { isStagnant } from '../utils';
+import { IProfile } from '../types';
+
+interface Props {
+ organization: string | null;
+ profiles: IProfile[];
+}
+
+export default function EvolutionStagnan(props: Props) {
+ // TODO filter built-in out
+
+ const outdated = props.profiles.filter(isStagnant);
+
+ if (outdated.length === 0) {
+ return null;
+ }
+
+ return (
+ <div className="quality-profile-box quality-profiles-evolution-stagnant">
+ <div className="spacer-bottom">
+ <strong>
+ {translate('quality_profiles.stagnant_profiles')}
+ </strong>
+ </div>
+ <div className="spacer-bottom">
+ {translate('quality_profiles.not_updated_more_than_year')}
+ </div>
+ <ul>
+ {outdated.map(profile =>
+ <li key={profile.key} className="spacer-top">
+ <div className="text-ellipsis">
+ <ProfileLink
+ className="link-no-underline"
+ language={profile.language}
+ name={profile.name}
+ organization={props.organization}>
+ {profile.name}
+ </ProfileLink>
+ </div>
+ <div className="note">
+ {profile.languageName}
+ {', '}
+ updated on {moment(profile.rulesUpdatedAt).format('LL')}
+ </div>
+ </li>
+ )}
+ </ul>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx
index 95f63d8cd4c..cd3b21502a5 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx
@@ -17,42 +17,35 @@
* 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 * as React from 'react';
import PageHeader from './PageHeader';
import Evolution from './Evolution';
import ProfilesList from './ProfilesList';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- languages: Array<{ key: string, name: string }>,
- location: { query: { [string]: string } },
- onRequestFail: Object => void,
- organization?: string,
- profiles: Array<Profile>,
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class HomeContainer extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ canAdmin: boolean;
+ languages: Array<{ key: string; name: string }>;
+ location: { query: { [p: string]: string } };
+ onRequestFail: (reason: any) => void;
+ organization: string | null;
+ profiles: Array<IProfile>;
+ updateProfiles: () => Promise<void>;
+}
- render() {
- return (
- <div>
- <PageHeader {...this.props} />
+export default function HomeContainer(props: Props) {
+ return (
+ <div>
+ <PageHeader {...props} />
- <div className="page-with-sidebar">
- <div className="page-main">
- <ProfilesList {...this.props} />
- </div>
- <div className="page-sidebar">
- <Evolution {...this.props} />
- </div>
+ <div className="page-with-sidebar">
+ <div className="page-main">
+ <ProfilesList {...props} />
+ </div>
+ <div className="page-sidebar">
+ <Evolution {...props} />
</div>
</div>
- );
- }
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx
index 44ba30feeb7..0f3b2b9c19f 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx
@@ -17,51 +17,44 @@
* 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 * as React from 'react';
+import * as PropTypes from 'prop-types';
import CreateProfileForm from './CreateProfileForm';
import RestoreProfileForm from './RestoreProfileForm';
-/*:: import type { Profile } from '../propTypes'; */
import { getProfilePath } from '../utils';
import { translate } from '../../../helpers/l10n';
+import { IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- languages: Array<{ key: string, name: string }>,
- onRequestFail: Object => void,
- organization: ?string,
- updateProfiles: () => Promise<*>
-};
-*/
-
-/*::
-type State = {
- createFormOpen: boolean,
- restoreFormOpen: boolean
-};
-*/
+interface Props {
+ canAdmin: boolean;
+ languages: Array<{ key: string; name: string }>;
+ onRequestFail: (reason: any) => void;
+ organization: string | null;
+ updateProfiles: () => Promise<void>;
+}
-export default class PageHeader extends React.PureComponent {
- /*:: props: Props; */
+interface State {
+ createFormOpen: boolean;
+ restoreFormOpen: boolean;
+}
+export default class PageHeader extends React.PureComponent<Props, State> {
static contextTypes = {
router: PropTypes.object
};
- state /*: State */ = {
+ state = {
createFormOpen: false,
restoreFormOpen: false
};
- handleCreateClick = (event /*: Event & { currentTarget: HTMLButtonElement } */) => {
+ handleCreateClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
event.currentTarget.blur();
this.setState({ createFormOpen: true });
};
- handleCreate = (profile /*: Profile */) => {
+ handleCreate = (profile: IProfile) => {
this.props.updateProfiles().then(() => {
this.context.router.push(
getProfilePath(profile.name, profile.language, this.props.organization)
@@ -73,7 +66,7 @@ export default class PageHeader extends React.PureComponent {
this.setState({ createFormOpen: false });
};
- handleRestoreClick = (event /*: Event */) => {
+ handleRestoreClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.setState({ restoreFormOpen: true });
};
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx
index b912a9662a5..6f4c8f8c17b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx
@@ -17,31 +17,25 @@
* 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 * as React from 'react';
import { groupBy, pick, sortBy } from 'lodash';
import ProfilesListRow from './ProfilesListRow';
import ProfilesListHeader from './ProfilesListHeader';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
-/*::
-type Props = {
- canAdmin: boolean,
- languages: Array<{ key: string, name: string }>,
- location: { query: { [string]: string } },
- onRequestFail: Object => void,
- organization: ?string,
- profiles: Array<Profile>,
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class ProfilesList extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ canAdmin: boolean;
+ languages: Array<{ key: string; name: string }>;
+ location: { query: { [p: string]: string } };
+ onRequestFail: (reason: any) => void;
+ organization: string | null;
+ profiles: IProfile[];
+ updateProfiles: () => Promise<void>;
+}
- renderProfiles(profiles /*: Array<Profile> */) {
+export default class ProfilesList extends React.PureComponent<Props> {
+ renderProfiles(profiles: IProfile[]) {
return profiles.map(profile =>
<ProfilesListRow
canAdmin={this.props.canAdmin}
@@ -54,7 +48,7 @@ export default class ProfilesList extends React.PureComponent {
);
}
- renderHeader(languageKey /*: string */, profilesCount /*: number */) {
+ renderHeader(languageKey: string, profilesCount: number) {
const language = this.props.languages.find(l => l.key === languageKey);
if (!language) {
@@ -91,8 +85,14 @@ export default class ProfilesList extends React.PureComponent {
const { profiles, languages } = this.props;
const { language } = this.props.location.query;
- const profilesIndex = groupBy(profiles, profile => profile.language);
- const profilesToShow = language ? pick(profilesIndex, language) : profilesIndex;
+ const profilesIndex: { [language: string]: IProfile[] } = groupBy<IProfile>(
+ profiles,
+ profile => profile.language
+ );
+
+ const profilesToShow: { [language: string]: IProfile[] } = language
+ ? pick(profilesIndex, language)
+ : profilesIndex;
const languagesToShow = sortBy(Object.keys(profilesToShow));
@@ -115,12 +115,10 @@ export default class ProfilesList extends React.PureComponent {
{profilesToShow[languageKey] != null &&
this.renderHeader(languageKey, profilesToShow[languageKey].length)}
- <TooltipsContainer>
- <tbody>
- {profilesToShow[languageKey] != null &&
- this.renderProfiles(profilesToShow[languageKey])}
- </tbody>
- </TooltipsContainer>
+ <tbody>
+ {profilesToShow[languageKey] != null &&
+ this.renderProfiles(profilesToShow[languageKey])}
+ </tbody>
</table>
</div>
)}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx
index ab76d1a4df3..15b98d6a2d4 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx
@@ -17,23 +17,18 @@
* 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 * as React from 'react';
import { IndexLink } from 'react-router';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { getProfilesPath, getProfilesForLanguagePath } from '../utils';
-/*::
-type Props = {
- currentFilter?: string,
- languages: Array<{ key: string, name: string }>,
- organization: ?string
-};
-*/
-
-export default class ProfilesListHeader extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ currentFilter?: string;
+ languages: Array<{ key: string; name: string }>;
+ organization: string | null;
+}
+export default class ProfilesListHeader extends React.PureComponent<Props> {
renderFilterToggle() {
const { languages, currentFilter } = this.props;
const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
index f9d18056d2e..2d982c34db4 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
@@ -17,8 +17,7 @@
* 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 * as React from 'react';
import { Link } from 'react-router';
import ProfileLink from '../components/ProfileLink';
import ProfileDate from '../components/ProfileDate';
@@ -27,21 +26,18 @@ import BuiltInBadge from '../components/BuiltInBadge';
import { translate } from '../../../helpers/l10n';
import { getRulesUrl } from '../../../helpers/urls';
import { isStagnant } from '../utils';
-/*:: import type { Profile } from '../propTypes'; */
+import { IProfile } from '../types';
+import Tooltip from '../../../components/controls/Tooltip';
-/*::
-type Props = {
- canAdmin: boolean,
- onRequestFail: Object => void,
- organization: ?string,
- profile: Profile,
- updateProfiles: () => Promise<*>
-};
-*/
-
-export default class ProfilesListRow extends React.PureComponent {
- /*:: props: Props; */
+interface Props {
+ canAdmin: boolean;
+ onRequestFail: (reason: any) => void;
+ organization: string | null;
+ profile: IProfile;
+ updateProfiles: () => Promise<void>;
+}
+export default class ProfilesListRow extends React.PureComponent<Props> {
renderName() {
const { profile } = this.props;
const offset = 25 * (profile.depth - 1);
@@ -100,13 +96,11 @@ export default class ProfilesListRow extends React.PureComponent {
<div>
{profile.activeDeprecatedRuleCount > 0 &&
<span className="spacer-right">
- <Link
- to={deprecatedRulesUrl}
- className="badge badge-normal-size badge-danger-light"
- title={translate('quality_profiles.deprecated_rules')}
- data-toggle="tooltip">
- {profile.activeDeprecatedRuleCount}
- </Link>
+ <Tooltip overlay={translate('quality_profiles.deprecated_rules')}>
+ <Link to={deprecatedRulesUrl} className="badge badge-normal-size badge-danger-light">
+ {profile.activeDeprecatedRuleCount}
+ </Link>
+ </Tooltip>
</span>}
<Link to={activeRulesUrl}>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx
index 26411abb34c..5f12d61f662 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx
@@ -17,35 +17,28 @@
* 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 * as React from 'react';
import Modal from 'react-modal';
import { restoreQualityProfile } from '../../../api/quality-profiles';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-/*::
-type Props = {
- onClose: () => void,
- onRequestFail: Object => void,
- onRestore: Function,
- organization: ?string
-};
-*/
+interface Props {
+ onClose: () => void;
+ onRequestFail: (reason: any) => void;
+ onRestore: () => void;
+ organization: string | null;
+}
-/*::
-type State = {
- loading: boolean,
- profile?: { name: string },
- ruleFailures?: number,
- ruleSuccesses?: number
-};
-*/
+interface State {
+ loading: boolean;
+ profile?: { name: string };
+ ruleFailures?: number;
+ ruleSuccesses?: number;
+}
-export default class RestoreProfileForm extends React.PureComponent {
- /*:: form: HTMLFormElement; */
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = { loading: false };
+export default class RestoreProfileForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false };
componentDidMount() {
this.mounted = true;
@@ -55,23 +48,23 @@ export default class RestoreProfileForm extends React.PureComponent {
this.mounted = false;
}
- handleCancelClick = (event /*: Event */) => {
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
event.preventDefault();
this.props.onClose();
};
- handleFormSubmit = (event /*: Event */) => {
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
this.setState({ loading: true });
- const data = new FormData(this.form);
+ const data = new FormData(event.currentTarget);
if (this.props.organization) {
data.append('organization', this.props.organization);
}
restoreQualityProfile(data).then(
- response => {
+ (response: any) => {
if (this.mounted) {
this.setState({
loading: false,
@@ -82,7 +75,7 @@ export default class RestoreProfileForm extends React.PureComponent {
}
this.props.onRestore();
},
- error => {
+ (error: any) => {
if (this.mounted) {
this.setState({ loading: false });
}
@@ -103,10 +96,7 @@ export default class RestoreProfileForm extends React.PureComponent {
className="modal"
overlayClassName="modal-overlay"
onRequestClose={this.props.onClose}>
- <form
- id="restore-profile-form"
- onSubmit={this.handleFormSubmit}
- ref={node => (this.form = node)}>
+ <form id="restore-profile-form" onSubmit={this.handleFormSubmit}>
<div className="modal-head">
<h2>
{header}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/propTypes.js b/server/sonar-web/src/main/js/apps/quality-profiles/propTypes.js
deleted file mode 100644
index dbf1364fca2..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-profiles/propTypes.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 { shape, string, number, bool, arrayOf } from 'prop-types';
-
-/*::
-export type Profile = {
- key: string,
- name: string,
- isBuiltIn: boolean,
- isDefault: boolean,
- isInherited: boolean,
- language: string,
- languageName: string,
- activeRuleCount: number,
- activeDeprecatedRuleCount: number,
- projectCount?: number,
- parentKey?: string,
- parentName?: string,
- userUpdatedAt?: string,
- lastUsed?: string,
- rulesUpdatedAt: string,
- depth: number,
- childrenCount: number
-};
-*/
-
-/*::
-export type Exporter = {
- key: string,
- name: string,
- languages: Array<string>
-};
-*/
-
-export const ProfileType = shape({
- key: string.isRequired,
- name: string.isRequired,
- isDefault: bool.isRequired,
- isInherited: bool.isRequired,
- language: string.isRequired,
- languageName: string.isRequired,
- activeRuleCount: number.isRequired,
- activeDeprecatedRuleCount: number.isRequired,
- projectCount: number,
- parentKey: string,
- parentName: string,
- userUpdatedAt: string,
- lastUsed: string
-});
-
-export const ProfilesListType = arrayOf(ProfileType);
-
-const LanguageType = shape({
- key: string.isRequired,
- name: string.isRequired
-});
-
-export const LanguagesListType = arrayOf(LanguageType);
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts
index 1d7b96fe647..cac3704b319 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts
@@ -17,11 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { withRouter } from 'react-router';
+import { withRouter, RouterState, IndexRouteProps, RouteComponent } from 'react-router';
const routes = [
{
- getComponent(state, callback) {
+ getComponent(state: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/AppContainer').then(i => i.default).then(AppContainer => {
if (state.params.organizationKey) {
callback(null, AppContainer);
@@ -32,30 +32,30 @@ const routes = [
}
});
},
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./home/HomeContainer').then(i => callback(null, { component: i.default }));
},
childRoutes: [
{
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/ProfileContainer').then(i => callback(null, withRouter(i.default)));
},
childRoutes: [
{
path: 'show',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./details/ProfileDetails').then(i => callback(null, i.default));
}
},
{
path: 'changelog',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./changelog/ChangelogContainer').then(i => callback(null, i.default));
}
},
{
path: 'compare',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./compare/ComparisonContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/types.ts b/server/sonar-web/src/main/js/apps/quality-profiles/types.ts
new file mode 100644
index 00000000000..73e4384706d
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/types.ts
@@ -0,0 +1,53 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.
+ */
+export interface IProfile {
+ key: string;
+ name: string;
+ isBuiltIn: boolean;
+ isDefault: boolean;
+ isInherited: boolean;
+ language: string;
+ languageName: string;
+ activeRuleCount: number;
+ activeDeprecatedRuleCount: number;
+ projectCount?: number;
+ parentKey?: string;
+ parentName?: string;
+ userUpdatedAt?: string;
+ lastUsed?: string;
+ rulesUpdatedAt: string;
+ depth: number;
+ childrenCount: number;
+}
+
+export interface IExporter {
+ key: string;
+ name: string;
+ languages: string[];
+}
+
+export interface IProfileChangelogEvent {
+ action: string;
+ authorName: string;
+ date: string;
+ params?: { [change: string]: string | null };
+ ruleKey: string;
+ ruleName: string;
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js b/server/sonar-web/src/main/js/apps/quality-profiles/utils.ts
index 60ec46e6572..890f3879e63 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/utils.ts
@@ -17,22 +17,21 @@
* 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 { sortBy } from 'lodash';
-import moment from 'moment';
-/*:: import type { Profile } from './propTypes'; */
+import * as moment from 'moment';
+import { IProfile } from './types';
-export function sortProfiles(profiles /*: Array<Profile> */) {
- const result = [];
+export function sortProfiles(profiles: IProfile[]) {
+ const result: IProfile[] = [];
const sorted = sortBy(profiles, 'name');
- function retrieveChildren(parent) {
+ function retrieveChildren(parent: IProfile | null) {
return sorted.filter(
p => (parent == null && p.parentKey == null) || (parent != null && p.parentKey === parent.key)
);
}
- function putProfile(profile = null, depth = 1) {
+ function putProfile(profile: IProfile | null = null, depth: number = 1) {
const children = retrieveChildren(profile);
if (profile != null) {
@@ -51,7 +50,7 @@ export function sortProfiles(profiles /*: Array<Profile> */) {
return result;
}
-export function createFakeProfile(overrides /*: {} */) {
+export function createFakeProfile(overrides?: any) {
return {
key: 'key',
name: 'name',
@@ -66,37 +65,30 @@ export function createFakeProfile(overrides /*: {} */) {
};
}
-export function isStagnant(profile /*: Profile */) {
+export function isStagnant(profile: IProfile) {
return moment().diff(moment(profile.userUpdatedAt), 'years') >= 1;
}
-export const getProfilesPath = (organization /*: ?string */) =>
+export const getProfilesPath = (organization: string | null) =>
organization ? `/organizations/${organization}/quality_profiles` : '/profiles';
-export const getProfilesForLanguagePath = (
- language /*: string */,
- organization /*: ?string */
-) => ({
+export const getProfilesForLanguagePath = (language: string, organization: string | null) => ({
pathname: getProfilesPath(organization),
query: { language }
});
-export const getProfilePath = (
- name /*: string */,
- language /*: string */,
- organization /*: ?string */
-) => ({
+export const getProfilePath = (name: string, language: string, organization: string | null) => ({
pathname: getProfilesPath(organization) + '/show',
query: { name, language }
});
export const getProfileComparePath = (
- name /*: string */,
- language /*: string */,
- organization /*: ?string */,
- withKey /*: ?string */
+ name: string,
+ language: string,
+ organization: string | null,
+ withKey?: string
) => {
- const query /*: Object */ = { language, name };
+ const query = { language, name };
if (withKey) {
Object.assign(query, { withKey });
}
@@ -107,12 +99,12 @@ export const getProfileComparePath = (
};
export const getProfileChangelogPath = (
- name /*: string */,
- language /*: string */,
- organization /*: ?string */,
- filter /*: ?{ since?: string, to?: string } */
+ name: string,
+ language: string,
+ organization: string | null,
+ filter?: { since?: string; to?: string }
) => {
- const query /*: Object */ = { language, name };
+ const query = { language, name };
if (filter) {
if (filter.since) {
Object.assign(query, { since: filter.since });
diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js b/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js
deleted file mode 100644
index a8f98da3fd1..00000000000
--- a/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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';
-
-export default class Unauthorized extends React.PureComponent {
- static propTypes = {
- location: PropTypes.object.isRequired
- };
-
- render() {
- const { message } = this.props.location.query;
-
- return (
- <div className="text-center">
- <p id="unauthorized">
- {"You're not authorized to access this page. Please contact the administrator."}
- </p>
-
- {!!message &&
- <p className="spacer-top">
- Reason : {message}
- </p>}
-
- <div className="big-spacer-top">
- <a href={window.baseUrl + '/'}>Home</a>
- </div>
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.tsx b/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.tsx
new file mode 100644
index 00000000000..edfa3d62d26
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.tsx
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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';
+
+interface Props {
+ location: {
+ query: {
+ message: string;
+ };
+ };
+}
+
+export default function Unauthorized(props: Props) {
+ const { message } = props.location.query;
+
+ return (
+ <div className="text-center">
+ <p id="unauthorized">
+ {"You're not authorized to access this page. Please contact the administrator."}
+ </p>
+
+ {!!message &&
+ <p className="spacer-top">
+ Reason : {message}
+ </p>}
+
+ <div className="big-spacer-top">
+ <Link to="/">Home</Link>
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.js b/server/sonar-web/src/main/js/apps/sessions/routes.ts
index 32e367c391f..ce1a2e80c70 100644
--- a/server/sonar-web/src/main/js/apps/sessions/routes.js
+++ b/server/sonar-web/src/main/js/apps/sessions/routes.ts
@@ -17,22 +17,24 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent } from 'react-router';
+
const routes = [
{
path: 'new',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/LoginFormContainer').then(i => callback(null, i.default));
}
},
{
path: 'logout',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/Logout').then(i => callback(null, i.default));
}
},
{
path: 'unauthorized',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/Unauthorized').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/settings/routes.js b/server/sonar-web/src/main/js/apps/settings/routes.ts
index 9a408f19fe8..54afd122a3d 100644
--- a/server/sonar-web/src/main/js/apps/settings/routes.js
+++ b/server/sonar-web/src/main/js/apps/settings/routes.ts
@@ -17,27 +17,29 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/AppContainer').then(i => callback(null, { component: i.default }));
}
},
{
path: 'licenses',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./licenses/LicensesApp').then(i => callback(null, i.default));
}
},
{
path: 'encryption',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./encryption/EncryptionAppContainer').then(i => callback(null, i.default));
}
},
{
path: 'server_id',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./serverId/ServerIdAppContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/system/routes.js b/server/sonar-web/src/main/js/apps/system/routes.js
deleted file mode 100644
index 0ab080a46f4..00000000000
--- a/server/sonar-web/src/main/js/apps/system/routes.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.
- */
-const routes = [
- {
- getIndexRoute(_, callback) {
- import('./main').then(i => callback(null, { component: i.default }));
- }
- }
-];
-
-export default routes;
diff --git a/server/sonar-web/src/main/js/apps/system/routes.ts b/server/sonar-web/src/main/js/apps/system/routes.ts
new file mode 100644
index 00000000000..9f7f40c4cd2
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/system/routes.ts
@@ -0,0 +1,30 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 { RouterState, IndexRouteProps } from 'react-router';
+
+const routes = [
+ {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
+ import('./main').then(i => callback(null, { component: (i as any).default }));
+ }
+ }
+];
+
+export default routes;
diff --git a/server/sonar-web/src/main/js/apps/update-center/routes.js b/server/sonar-web/src/main/js/apps/update-center/routes.ts
index 81c884ae5d6..e41cfdc073a 100644
--- a/server/sonar-web/src/main/js/apps/update-center/routes.js
+++ b/server/sonar-web/src/main/js/apps/update-center/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/UpdateCenterAppContainer').then(i =>
callback(null, { component: i.default })
);
@@ -27,25 +29,25 @@ const routes = [
},
{
path: 'installed',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default));
}
},
{
path: 'updates',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default));
}
},
{
path: 'available',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default));
}
},
{
path: 'system',
- getComponent(_, callback) {
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default));
}
}
diff --git a/server/sonar-web/src/main/js/apps/users/routes.js b/server/sonar-web/src/main/js/apps/users/routes.ts
index b07c3c9c5c2..88751d8b803 100644
--- a/server/sonar-web/src/main/js/apps/users/routes.js
+++ b/server/sonar-web/src/main/js/apps/users/routes.ts
@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/UsersAppContainer').then(i => callback(null, { component: i.default }));
}
}
diff --git a/server/sonar-web/src/main/js/apps/web-api/routes.js b/server/sonar-web/src/main/js/apps/web-api/routes.ts
index 5993b47eea4..a76c3f27e93 100644
--- a/server/sonar-web/src/main/js/apps/web-api/routes.js
+++ b/server/sonar-web/src/main/js/apps/web-api/routes.ts
@@ -17,16 +17,18 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { RouterState, RouteComponent, IndexRouteProps } from 'react-router';
+
const routes = [
{
- getIndexRoute(_, callback) {
- import('./components/WebApiApp').then(i => callback(null, { component: i.default }));
+ getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
+ import('./components/WebApiApp').then(i => callback(null, { component: (i as any).default }));
}
},
{
path: '**',
- getComponent(_, callback) {
- import('./components/WebApiApp').then(i => callback(null, i.default));
+ getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) {
+ import('./components/WebApiApp').then(i => callback(null, (i as any).default));
}
}
];