From: Stas Vilchik Date: Fri, 18 Aug 2017 16:53:44 +0000 (+0200) Subject: translate all routes files to ts (#2378) X-Git-Tag: 6.6-RC1~569 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7983068e4d2a45531ba0942688e659adf9ee61a2;p=sonarqube.git translate all routes files to ts (#2378) --- diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json index ae03fe49562..e9019ccbe63 100644 --- a/server/sonar-web/package.json +++ b/server/sonar-web/package.json @@ -44,13 +44,18 @@ "devDependencies": { "@types/classnames": "2.2.0", "@types/enzyme": "2.8.6", + "@types/escape-html": "0.0.19", "@types/jest": "20.0.7", + "@types/jquery": "3.2.11", "@types/lodash": "4.14.73", "@types/prop-types": "15.5.1", "@types/react": "16.0.2", "@types/react-dom": "15.5.2", + "@types/react-helmet": "5.0.3", + "@types/react-modal": "2.2.0", "@types/react-redux": "5.0.3", "@types/react-router": "3.0.5", + "@types/react-select": "1.0.51", "autoprefixer": "7.1.1", "awesome-typescript-loader": "3.2.3", "babel-core": "^6.22.1", @@ -122,8 +127,16 @@ ], "jest": { "coverageDirectory": "/target/coverage", - "coveragePathIgnorePatterns": ["/node_modules", "/tests"], - "moduleFileExtensions": ["ts", "tsx", "js", "json"], + "coveragePathIgnorePatterns": [ + "/node_modules", + "/tests" + ], + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "json" + ], "moduleNameMapper": { "^.+\\.(hbs|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/config/jest/FileStub.js", "^.+\\.css$": "/config/jest/CSSStub.js" @@ -132,7 +145,9 @@ "/config/polyfills.js", "/config/jest/SetupTestEnvironment.js" ], - "snapshotSerializers": ["enzyme-to-json/serializer"], + "snapshotSerializers": [ + "enzyme-to-json/serializer" + ], "testPathIgnorePatterns": [ "/node_modules", "/src/main/webapp", diff --git a/server/sonar-web/src/main/js/apps/about/routes.js b/server/sonar-web/src/main/js/apps/about/routes.js deleted file mode 100644 index 0748dad497d..00000000000 --- a/server/sonar-web/src/main/js/apps/about/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('./components/AboutApp').then(i => callback(null, { component: i.default })); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/about/routes.ts b/server/sonar-web/src/main/js/apps/about/routes.ts new file mode 100644 index 00000000000..6da3a2d64ba --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/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('./components/AboutApp').then(i => callback(null, { component: i.default })); + } + } +]; + +export default routes; 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 ( -
- - -

- - {project.name} - -

- - {links.length > 0 && -
-
    - {links.map(link => -
  • - - - -
  • - )} -
-
} - -
- {project.key} -
- - {!!project.description && -
- {project.description} -
} -
- ); - } -} 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 ( +
+ + +

+ + {project.name} + +

+ + {links.length > 0 && +
+
    + {links.map(link => +
  • + + + +
  • + )} +
+
} + +
+ {project.key} +
+ + {!!project.description && +
+ {project.description} +
} +
+ ); +} 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 ( -
- {projects.length === 0 - ?
- {translate('my_account.projects.no_results')} -
- :

- {translate('my_account.projects.description')} -

} - - {projects.length > 0 && -
    - {projects.map(project => -
  • - -
  • - )} -
} - - {projects.length > 0 && - } -
- ); - } -} 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 ( +
+ {projects.length === 0 + ?
+ {translate('my_account.projects.no_results')} +
+ :

+ {translate('my_account.projects.description')} +

} + + {projects.length > 0 && +
    + {projects.map(project => +
  • + +
  • + )} +
} + + {projects.length > 0 && + } +
+ ); +} 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.js deleted file mode 100644 index 69aea617c93..00000000000 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js +++ /dev/null @@ -1,101 +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 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 = { - loading: true, - page: 1, - query: '' - }; - - componentWillMount() { - this.loadMore = this.loadMore.bind(this); - this.search = this.search.bind(this); - } - - componentDidMount() { - this.mounted = true; - this.loadProjects(); - } - - componentWillUnmount() { - this.mounted = false; - } - - loadProjects(page = this.state.page, query = this.state.query) { - this.setState({ loading: true }); - const data = { 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; - this.setState({ - projects, - query, - loading: false, - page: r.paging.pageIndex, - total: r.paging.total - }); - }); - } - - loadMore() { - return this.loadProjects(this.state.page + 1); - } - - search(query) { - return this.loadProjects(1, query); - } - - render() { - const helmet = ; - - if (this.state.projects == null) { - return ( -
- {helmet} - -
- ); - } - - return ( -
- {helmet} - -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx new file mode 100644 index 00000000000..b822768884d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx @@ -0,0 +1,101 @@ +/* + * 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 Helmet from 'react-helmet'; +import Projects from './Projects'; +import { getMyProjects } from '../../../api/components'; +import { translate } from '../../../helpers/l10n'; + +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: '' + }; + + componentDidMount() { + this.mounted = true; + this.loadProjects(); + } + + componentWillUnmount() { + this.mounted = false; + } + + loadProjects(page = this.state.page, query = this.state.query) { + this.setState({ loading: true }); + const data: { [p: string]: any } = { ps: 100 }; + if (page > 1) { + data.p = page; + } + if (query) { + data.q = query; + } + return getMyProjects(data).then((r: any) => { + const projects = page > 1 ? [...(this.state.projects || []), ...r.projects] : r.projects; + this.setState({ + projects, + query, + loading: false, + page: r.paging.pageIndex, + total: r.paging.total + }); + }); + } + + loadMore = () => this.loadProjects(this.state.page + 1); + + search = (query: string) => this.loadProjects(1, query); + + render() { + const helmet = ; + + if (this.state.projects == null) { + return ( +
+ {helmet} + +
+ ); + } + + return ( +
+ {helmet} + +
+ ); + } +} 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.js deleted file mode 100644 index 2b92bf00f6b..00000000000 --- a/server/sonar-web/src/main/js/apps/account/routes.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. - */ -const routes = [ - { - getComponent(_, callback) { - import('./components/Account').then(i => callback(null, i.default)); - }, - childRoutes: [ - { - getIndexRoute(_, callback) { - import('./profile/Profile').then(i => callback(null, { component: i.default })); - } - }, - { - path: 'security', - getComponent(_, callback) { - import('./components/Security').then(i => callback(null, i.default)); - } - }, - { - path: 'projects', - getComponent(_, callback) { - import('./projects/ProjectsContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'notifications', - getComponent(_, callback) { - import('./notifications/Notifications').then(i => callback(null, i.default)); - } - }, - { - path: 'organizations', - getComponent(_, callback) { - import('./organizations/UserOrganizations').then(i => callback(null, i.default)); - }, - childRoutes: [ - { - path: 'create', - getComponent(_, callback) { - import('./organizations/CreateOrganizationForm').then(i => callback(null, i.default)); - } - } - ] - } - ] - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/account/routes.ts b/server/sonar-web/src/main/js/apps/account/routes.ts new file mode 100644 index 00000000000..90e66149504 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/routes.ts @@ -0,0 +1,69 @@ +/* + * 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, RouteComponent } from 'react-router'; + +const routes = [ + { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/Account').then(i => callback(null, i.default)); + }, + childRoutes: [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./profile/Profile').then(i => callback(null, { component: i.default })); + } + }, + { + path: 'security', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/Security').then(i => callback(null, i.default)); + } + }, + { + path: 'projects', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./projects/ProjectsContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'notifications', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./notifications/Notifications').then(i => callback(null, i.default)); + } + }, + { + path: 'organizations', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./organizations/UserOrganizations').then(i => callback(null, i.default)); + }, + childRoutes: [ + { + path: 'create', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./organizations/CreateOrganizationForm').then(i => callback(null, i.default)); + } + } + ] + } + ] + } +]; + +export default routes; 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.js deleted file mode 100644 index 3f46e626d9e..00000000000 --- a/server/sonar-web/src/main/js/apps/background-tasks/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('./components/BackgroundTasksApp').then(i => callback(null, { component: i.default })); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/routes.ts b/server/sonar-web/src/main/js/apps/background-tasks/routes.ts new file mode 100644 index 00000000000..88e0a5e53bc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/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('./components/BackgroundTasksApp').then(i => callback(null, { component: i.default })); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/code/routes.js b/server/sonar-web/src/main/js/apps/code/routes.js deleted file mode 100644 index 4de41657b76..00000000000 --- a/server/sonar-web/src/main/js/apps/code/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('./components/App').then(i => callback(null, { component: i.default })); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/code/routes.ts b/server/sonar-web/src/main/js/apps/code/routes.ts new file mode 100644 index 00000000000..fcffeff191c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/code/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('./components/App').then(i => callback(null, { component: i.default })); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index af91a4eab6d..00000000000 --- a/server/sonar-web/src/main/js/apps/coding-rules/routes.js +++ /dev/null @@ -1,30 +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 = [ - { - indexRoute: { - getComponent(_, callback) { - import('./components/CodingRulesAppContainer').then(i => callback(null, i.default)); - } - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/routes.ts b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts new file mode 100644 index 00000000000..798ee29934a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/coding-rules/routes.ts @@ -0,0 +1,32 @@ +/* + * 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, RouteComponent } from 'react-router'; + +const routes = [ + { + indexRoute: { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/CodingRulesAppContainer').then(i => callback(null, i.default)); + } + } + } +]; + +export default routes; 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.js deleted file mode 100644 index c0abc9f57d8..00000000000 --- a/server/sonar-web/src/main/js/apps/component-measures/routes.js +++ /dev/null @@ -1,64 +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('./components/AppContainer').then(i => callback(null, { component: i.default })); - } - }, - { - path: 'domain/:domainName', - onEnter(nextState, replace) { - replace({ - pathname: '/component_measures', - query: { - ...nextState.location.query, - metric: nextState.params.domainName - } - }); - } - }, - { - path: 'metric/:metricKey(/:view)', - onEnter(nextState, replace) { - if (nextState.params.view === 'history') { - replace({ - pathname: '/project/activity', - query: { - id: nextState.location.query.id, - graph: 'custom', - custom_metrics: nextState.params.metricKey - } - }); - } else { - replace({ - pathname: '/component_measures', - query: { - ...nextState.location.query, - metric: nextState.params.metricKey, - view: nextState.params.view - } - }); - } - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.ts b/server/sonar-web/src/main/js/apps/component-measures/routes.ts new file mode 100644 index 00000000000..9f3813c87e2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/component-measures/routes.ts @@ -0,0 +1,66 @@ +/* + * 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, RedirectFunction } from 'react-router'; + +const routes = [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/AppContainer').then(i => callback(null, { component: i.default })); + } + }, + { + path: 'domain/:domainName', + onEnter(nextState: RouterState, replace: RedirectFunction) { + replace({ + pathname: '/component_measures', + query: { + ...nextState.location.query, + metric: nextState.params.domainName + } + }); + } + }, + { + path: 'metric/:metricKey(/:view)', + onEnter(nextState: RouterState, replace: RedirectFunction) { + if (nextState.params.view === 'history') { + replace({ + pathname: '/project/activity', + query: { + id: nextState.location.query.id, + graph: 'custom', + custom_metrics: nextState.params.metricKey + } + }); + } else { + replace({ + pathname: '/component_measures', + query: { + ...nextState.location.query, + metric: nextState.params.metricKey, + view: nextState.params.view + } + }); + } + } + } +]; + +export default routes; 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.js deleted file mode 100644 index e8c1c9f2128..00000000000 --- a/server/sonar-web/src/main/js/apps/component/components/App.js +++ /dev/null @@ -1,63 +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 SourceViewer from '../../../components/SourceViewer/SourceViewer'; - -export default class App extends React.PureComponent { - /*:: props: { - location: { - query: { - id: string, - line?: string - } - } - }; -*/ - scrollToLine = () => { - const { line } = this.props.location.query; - if (line) { - const row = document.querySelector(`.source-line[data-line-number="${line}"]`); - if (row) { - const rect = row.getBoundingClientRect(); - const topOffset = window.innerHeight / 2 - 60; - const goal = rect.top - topOffset; - window.scrollTo(0, goal); - } - } - }; - - render() { - const { id, line } = this.props.location.query; - - const finalLine = line != null ? Number(line) : null; - - return ( -
- -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/component/components/App.tsx b/server/sonar-web/src/main/js/apps/component/components/App.tsx new file mode 100644 index 00000000000..a1fb59f825c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/component/components/App.tsx @@ -0,0 +1,62 @@ +/* + * 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 SourceViewer from '../../../components/SourceViewer/SourceViewer'; + +interface Props { + location: { + query: { + id: string; + line?: string; + }; + }; +} + +export default class App extends React.PureComponent { + scrollToLine = () => { + const { line } = this.props.location.query; + if (line) { + const row = document.querySelector(`.source-line[data-line-number="${line}"]`); + if (row) { + const rect = row.getBoundingClientRect(); + const topOffset = window.innerHeight / 2 - 60; + const goal = rect.top - topOffset; + window.scrollTo(0, goal); + } + } + }; + + render() { + const { id, line } = this.props.location.query; + + const finalLine = line != null ? Number(line) : null; + + return ( +
+ +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/component/routes.js b/server/sonar-web/src/main/js/apps/component/routes.js deleted file mode 100644 index 9943b1d8380..00000000000 --- a/server/sonar-web/src/main/js/apps/component/routes.js +++ /dev/null @@ -1,30 +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 = [ - { - indexRoute: { - getComponent(_, callback) { - import('./components/App').then(i => callback(null, i.default)); - } - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/component/routes.ts b/server/sonar-web/src/main/js/apps/component/routes.ts new file mode 100644 index 00000000000..c5105eeca4e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/component/routes.ts @@ -0,0 +1,32 @@ +/* + * 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, RouteComponent } from 'react-router'; + +const routes = [ + { + indexRoute: { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/App').then(i => callback(null, i.default)); + } + } + } +]; + +export default routes; 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.js deleted file mode 100644 index e3aee2038cd..00000000000 --- a/server/sonar-web/src/main/js/apps/custom-measures/routes.js +++ /dev/null @@ -1,30 +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('./components/CustomMeasuresAppContainer').then(i => - callback(null, { component: i.default }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.ts b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts new file mode 100644 index 00000000000..ad092ba1d48 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts @@ -0,0 +1,32 @@ +/* + * 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('./components/CustomMeasuresAppContainer').then(i => + callback(null, { component: i.default }) + ); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/groups/routes.js b/server/sonar-web/src/main/js/apps/groups/routes.js deleted file mode 100644 index 8829f80c94b..00000000000 --- a/server/sonar-web/src/main/js/apps/groups/routes.js +++ /dev/null @@ -1,33 +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) { - Promise.all([ - import('./components/GroupsAppContainer').then(i => i.default), - import('../organizations/forSingleOrganization').then(i => i.default) - ]).then(([GroupsAppContainer, forSingleOrganization]) => - callback(null, { component: forSingleOrganization(GroupsAppContainer) }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/groups/routes.ts b/server/sonar-web/src/main/js/apps/groups/routes.ts new file mode 100644 index 00000000000..80ee5984d39 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/groups/routes.ts @@ -0,0 +1,35 @@ +/* + * 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) { + Promise.all([ + import('./components/GroupsAppContainer').then(i => i.default), + import('../organizations/forSingleOrganization').then(i => i.default) + ]).then(([GroupsAppContainer, forSingleOrganization]) => + callback(null, { component: forSingleOrganization(GroupsAppContainer) }) + ); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/issues/routes.js b/server/sonar-web/src/main/js/apps/issues/routes.js deleted file mode 100644 index ffcdcb7a090..00000000000 --- a/server/sonar-web/src/main/js/apps/issues/routes.js +++ /dev/null @@ -1,32 +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 { onEnter } from './redirects'; - -const routes = [ - { - getIndexRoute(_, callback) { - import('./components/AppContainer').then(i => - callback(null, { component: i.default, onEnter }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/issues/routes.ts b/server/sonar-web/src/main/js/apps/issues/routes.ts new file mode 100644 index 00000000000..e915d90da0a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/issues/routes.ts @@ -0,0 +1,33 @@ +/* + * 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'; +import { onEnter } from './redirects'; + +const routes = [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/AppContainer').then(i => + callback(null, { component: i.default, onEnter }) + ); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index bf151b827ac..00000000000 --- a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js +++ /dev/null @@ -1,31 +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 init from '../init'; - -export default class MaintenanceAppContainer extends React.PureComponent { - componentDidMount() { - init(this.refs.container, false); - } - - render() { - return
; - } -} diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx new file mode 100644 index 00000000000..923d805efd7 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.tsx @@ -0,0 +1,31 @@ +/* + * 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 init from '../init'; + +export default class MaintenanceAppContainer extends React.PureComponent { + componentDidMount() { + init(this.refs.container, false); + } + + render() { + return
; + } +} 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.js deleted file mode 100644 index c28492700ce..00000000000 --- a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js +++ /dev/null @@ -1,31 +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 init from '../init'; - -export default class SetupAppContainer extends React.PureComponent { - componentDidMount() { - init(this.refs.container, true); - } - - render() { - return
; - } -} diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx new file mode 100644 index 00000000000..398ebb69fd6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.tsx @@ -0,0 +1,31 @@ +/* + * 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 init from '../init'; + +export default class SetupAppContainer extends React.PureComponent { + componentDidMount() { + init(this.refs.container, true); + } + + render() { + return
; + } +} diff --git a/server/sonar-web/src/main/js/apps/maintenance/routes.js b/server/sonar-web/src/main/js/apps/maintenance/routes.js deleted file mode 100644 index e6b19e9a5a3..00000000000 --- a/server/sonar-web/src/main/js/apps/maintenance/routes.js +++ /dev/null @@ -1,27 +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 { IndexRoute } from 'react-router'; -import MaintenanceAppContainer from './components/MaintenanceAppContainer'; -import SetupAppContainer from './components/SetupAppContainer'; - -export const maintenanceRoutes = ; - -export const setupRoutes = ; diff --git a/server/sonar-web/src/main/js/apps/maintenance/routes.tsx b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx new file mode 100644 index 00000000000..df6cd941cd5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/maintenance/routes.tsx @@ -0,0 +1,27 @@ +/* + * 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 { IndexRoute } from 'react-router'; +import MaintenanceAppContainer from './components/MaintenanceAppContainer'; +import SetupAppContainer from './components/SetupAppContainer'; + +export const maintenanceRoutes = ; + +export const setupRoutes = ; 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.js deleted file mode 100644 index f5f031e9839..00000000000 --- a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js +++ /dev/null @@ -1,38 +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 Helmet from 'react-helmet'; -import init from '../init'; -import { translate } from '../../../helpers/l10n'; - -export default class MetricsAppContainer extends React.PureComponent { - componentDidMount() { - init(this.refs.container); - } - - render() { - return ( -
- -
-
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx new file mode 100644 index 00000000000..0bf49c749d5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.tsx @@ -0,0 +1,38 @@ +/* + * 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 Helmet from 'react-helmet'; +import init from '../init'; +import { translate } from '../../../helpers/l10n'; + +export default class MetricsAppContainer extends React.PureComponent { + componentDidMount() { + init(this.refs.container); + } + + render() { + return ( +
+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/metrics/routes.js b/server/sonar-web/src/main/js/apps/metrics/routes.js deleted file mode 100644 index 637dba72da9..00000000000 --- a/server/sonar-web/src/main/js/apps/metrics/routes.js +++ /dev/null @@ -1,30 +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('./components/MetricsAppContainer').then(i => - callback(null, { component: i.default }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/metrics/routes.ts b/server/sonar-web/src/main/js/apps/metrics/routes.ts new file mode 100644 index 00000000000..c52951ea17b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/metrics/routes.ts @@ -0,0 +1,32 @@ +/* + * 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('./components/MetricsAppContainer').then(i => + callback(null, { component: i.default }) + ); + } + } +]; + +export default routes; 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
callback(null, { component: i.default })); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/overview/routes.ts b/server/sonar-web/src/main/js/apps/overview/routes.ts new file mode 100644 index 00000000000..21e41c6b087 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/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('./components/AppContainer').then(i => callback(null, { component: i.default })); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index ce1b2679e4a..00000000000 --- a/server/sonar-web/src/main/js/apps/permission-templates/routes.js +++ /dev/null @@ -1,33 +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) { - Promise.all([ - import('./components/AppContainer').then(i => i.default), - import('../organizations/forSingleOrganization').then(i => i.default) - ]).then(([AppContainer, forSingleOrganization]) => - callback(null, { component: forSingleOrganization(AppContainer) }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/routes.ts b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts new file mode 100644 index 00000000000..f00dc431c31 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permission-templates/routes.ts @@ -0,0 +1,35 @@ +/* + * 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) { + Promise.all([ + import('./components/AppContainer').then(i => i.default), + import('../organizations/forSingleOrganization').then(i => i.default) + ]).then(([AppContainer, forSingleOrganization]) => + callback(null, { component: forSingleOrganization(AppContainer) }) + ); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.js b/server/sonar-web/src/main/js/apps/permissions/routes.js deleted file mode 100644 index 631a26985b1..00000000000 --- a/server/sonar-web/src/main/js/apps/permissions/routes.js +++ /dev/null @@ -1,41 +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. - */ -export const globalPermissionsRoutes = [ - { - getIndexRoute(_, callback) { - Promise.all([ - import('./global/components/App').then(i => i.default), - import('../organizations/forSingleOrganization').then(i => i.default) - ]).then(([App, forSingleOrganization]) => - callback(null, { component: forSingleOrganization(App) }) - ); - } - } -]; - -export const projectPermissionsRoutes = [ - { - getIndexRoute(_, callback) { - import('./project/components/AppContainer').then(i => - callback(null, { component: i.default }) - ); - } - } -]; diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.ts b/server/sonar-web/src/main/js/apps/permissions/routes.ts new file mode 100644 index 00000000000..85a62be0dd2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/permissions/routes.ts @@ -0,0 +1,43 @@ +/* + * 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'; + +export const globalPermissionsRoutes = [ + { + 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) + ]).then(([App, forSingleOrganization]) => + callback(null, { component: forSingleOrganization(App) }) + ); + } + } +]; + +export const projectPermissionsRoutes = [ + { + 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.js deleted file mode 100644 index 11233a7368b..00000000000 --- a/server/sonar-web/src/main/js/apps/projectActivity/routes.js +++ /dev/null @@ -1,30 +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('./components/ProjectActivityAppContainer').then(i => - callback(null, { component: i.default }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.ts b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts new file mode 100644 index 00000000000..47d7bda3dae --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts @@ -0,0 +1,32 @@ +/* + * 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('./components/ProjectActivityAppContainer').then(i => + callback(null, { component: i.default }) + ); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index d17958371b6..00000000000 --- a/server/sonar-web/src/main/js/apps/projects-admin/routes.js +++ /dev/null @@ -1,33 +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) { - Promise.all([ - import('./AppContainer').then(i => i.default), - import('../organizations/forSingleOrganization').then(i => i.default) - ]).then(([AppContainer, forSingleOrganization]) => - callback(null, { component: forSingleOrganization(AppContainer) }) - ); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/routes.ts b/server/sonar-web/src/main/js/apps/projects-admin/routes.ts new file mode 100644 index 00000000000..447c6ae73dd --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects-admin/routes.ts @@ -0,0 +1,35 @@ +/* + * 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) { + Promise.all([ + import('./AppContainer').then(i => i.default), + import('../organizations/forSingleOrganization').then(i => i.default) + ]).then(([AppContainer, forSingleOrganization]) => + callback(null, { component: forSingleOrganization(AppContainer) }) + ); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index 83b097ed170..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/components/App.js +++ /dev/null @@ -1,45 +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'; - -export default class App extends React.PureComponent { - componentDidMount() { - const elem = document.querySelector('html'); - if (elem) { - elem.classList.add('dashboard-page'); - } - } - - componentWillUnmount() { - const elem = document.querySelector('html'); - if (elem) { - elem.classList.remove('dashboard-page'); - } - } - - render() { - return ( -
- {this.props.children} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/projects/components/App.tsx b/server/sonar-web/src/main/js/apps/projects/components/App.tsx new file mode 100644 index 00000000000..471331fb0b9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/components/App.tsx @@ -0,0 +1,44 @@ +/* + * 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'; + +export default class App extends React.PureComponent { + componentDidMount() { + const elem = document.querySelector('html'); + if (elem) { + elem.classList.add('dashboard-page'); + } + } + + componentWillUnmount() { + const elem = document.querySelector('html'); + if (elem) { + elem.classList.remove('dashboard-page'); + } + } + + render() { + return ( +
+ {this.props.children} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/projects/routes.js b/server/sonar-web/src/main/js/apps/projects/routes.js deleted file mode 100644 index 1c3c76cc3d4..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/routes.js +++ /dev/null @@ -1,52 +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 { saveAll } from '../../helpers/storage'; - -const routes = [ - { - getComponent(_, callback) { - import('./components/App').then(i => callback(null, i.default)); - }, - childRoutes: [ - { - getIndexRoute(_, callback) { - import('./components/DefaultPageSelector').then(i => - callback(null, { component: i.default }) - ); - } - }, - { - path: 'all', - onEnter(_, replace) { - saveAll(); - replace('/projects'); - } - }, - { - path: 'favorite', - getComponent(_, callback) { - import('./components/FavoriteProjectsContainer').then(i => callback(null, i.default)); - } - } - ] - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/projects/routes.ts b/server/sonar-web/src/main/js/apps/projects/routes.ts new file mode 100644 index 00000000000..c6f3df309f5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/routes.ts @@ -0,0 +1,53 @@ +/* + * 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, RouteComponent, RedirectFunction } from 'react-router'; +import { saveAll } from '../../helpers/storage'; + +const routes = [ + { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/App').then(i => callback(null, i.default)); + }, + childRoutes: [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/DefaultPageSelector').then(i => + callback(null, { component: i.default }) + ); + } + }, + { + path: 'all', + onEnter(_: RouterState, replace: RedirectFunction) { + saveAll(); + replace('/projects'); + } + }, + { + path: 'favorite', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/FavoriteProjectsContainer').then(i => callback(null, i.default)); + } + } + ] + } +]; + +export default routes; 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.js deleted file mode 100644 index 8664f1f39bb..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/routes.js +++ /dev/null @@ -1,41 +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 = [ - { - getComponent(_, callback) { - import('./containers/QualityGatesAppContainer').then(i => callback(null, i.default)); - }, - childRoutes: [ - { - getIndexRoute(_, callback) { - import('./components/Intro').then(i => callback(null, { component: i.default })); - } - }, - { - path: 'show/:id', - getComponent(_, callback) { - import('./containers/DetailsContainer').then(i => callback(null, i.default)); - } - } - ] - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.ts b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts new file mode 100644 index 00000000000..f1d203bc354 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.ts @@ -0,0 +1,43 @@ +/* + * 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, RouteComponent } from 'react-router'; + +const routes = [ + { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./containers/QualityGatesAppContainer').then(i => callback(null, i.default)); + }, + childRoutes: [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/Intro').then(i => callback(null, { component: i.default })); + } + }, + { + path: 'show/:id', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./containers/DetailsContainer').then(i => callback(null, i.default)); + } + } + ] + } +]; + +export default routes; 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.js.snap deleted file mode 100644 index 63a0a9ee7e0..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.js.snap +++ /dev/null @@ -1,131 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`#sortProfiles should sort by name 1`] = ` -Array [ - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile1", - "name": "profile1", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile2", - "name": "profile2", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile3", - "name": "profile3", - "parentKey": undefined, - }, -] -`; - -exports[`#sortProfiles should sort single branch 1`] = ` -Array [ - Object { - "childrenCount": 1, - "depth": 1, - "key": "profile1", - "name": "profile1", - "parentKey": undefined, - }, - Object { - "childrenCount": 1, - "depth": 2, - "key": "profile3", - "name": "profile3", - "parentKey": "profile1", - }, - Object { - "childrenCount": 0, - "depth": 3, - "key": "profile2", - "name": "profile2", - "parentKey": "profile3", - }, -] -`; - -exports[`#sortProfiles should sort when no parents 1`] = ` -Array [ - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile1", - "name": "profile1", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile2", - "name": "profile2", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile3", - "name": "profile3", - "parentKey": undefined, - }, -] -`; - -exports[`#sortProfiles should sort with children 1`] = ` -Array [ - Object { - "childrenCount": 2, - "depth": 1, - "key": "parent", - "name": "parent", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 2, - "key": "child1", - "name": "child1", - "parentKey": "parent", - }, - Object { - "childrenCount": 0, - "depth": 2, - "key": "child2", - "name": "child2", - "parentKey": "parent", - }, -] -`; - -exports[`#sortProfiles sorts partial set of inherited profiles 1`] = ` -Array [ - Object { - "childrenCount": 0, - "depth": 1, - "key": "profile1", - "name": "profile1", - "parentKey": "x", - }, - Object { - "childrenCount": 1, - "depth": 1, - "key": "profile2", - "name": "profile2", - "parentKey": undefined, - }, - Object { - "childrenCount": 0, - "depth": 2, - "key": "profile3", - "name": "profile3", - "parentKey": "profile2", - }, -] -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap new file mode 100644 index 00000000000..a833c80f2e3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/__snapshots__/utils-test.ts.snap @@ -0,0 +1,143 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`#sortProfiles should sort by name 1`] = ` +Array [ + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile1", + "name": "profile1", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile2", + "name": "profile2", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile3", + "name": "profile3", + "parentKey": undefined, + }, +] +`; + +exports[`#sortProfiles should sort single branch 1`] = ` +Array [ + Object { + "childrenCount": 1, + "depth": 1, + "key": "profile1", + "name": "profile1", + "parentKey": undefined, + }, + Object { + "childrenCount": 1, + "depth": 2, + "key": "profile3", + "name": "profile3", + "parentKey": "profile1", + }, + Object { + "childrenCount": 0, + "depth": 3, + "key": "profile2", + "name": "profile2", + "parentKey": "profile3", + }, +] +`; + +exports[`#sortProfiles should sort when no parents 1`] = ` +Array [ + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile1", + "name": "profile1", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile2", + "name": "profile2", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 1, + "key": "profile3", + "name": "profile3", + "parentKey": undefined, + }, +] +`; + +exports[`#sortProfiles should sort with children 1`] = ` +Array [ + Object { + "childrenCount": 2, + "depth": 1, + "key": "parent", + "name": "parent", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 2, + "key": "child1", + "name": "child1", + "parentKey": "parent", + }, + Object { + "childrenCount": 0, + "depth": 2, + "key": "child2", + "name": "child2", + "parentKey": "parent", + }, +] +`; + +exports[`#sortProfiles sorts partial set of inherited profiles 1`] = ` +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", + }, + Object { + "childrenCount": 1, + "depth": 1, + "key": "profile2", + "name": "profile2", + "parentKey": undefined, + }, + Object { + "childrenCount": 0, + "depth": 2, + "key": "profile3", + "name": "profile3", + "parentKey": "profile2", + }, +] +`; 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.js deleted file mode 100644 index 57157f7de3a..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js +++ /dev/null @@ -1,64 +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 { sortProfiles } from '../utils'; - -function createProfile(key, parentKey) { - return { name: key, key, parentKey }; -} - -describe('#sortProfiles', () => { - it('should sort when no parents', () => { - const profile1 = createProfile('profile1'); - const profile2 = createProfile('profile2'); - const profile3 = createProfile('profile3'); - expect(sortProfiles([profile1, profile2, profile3])).toMatchSnapshot(); - }); - - it('should sort by name', () => { - const profile1 = createProfile('profile1'); - const profile2 = createProfile('profile2'); - const profile3 = createProfile('profile3'); - expect(sortProfiles([profile3, profile1, profile2])).toMatchSnapshot(); - }); - - it('should sort with children', () => { - const child1 = createProfile('child1', 'parent'); - const child2 = createProfile('child2', 'parent'); - const parent = createProfile('parent'); - expect(sortProfiles([child1, child2, parent])).toMatchSnapshot(); - }); - - it('should sort single branch', () => { - const profile1 = createProfile('profile1'); - const profile2 = createProfile('profile2', 'profile3'); - const profile3 = createProfile('profile3', 'profile1'); - expect(sortProfiles([profile3, profile2, profile1])).toMatchSnapshot(); - }); - - it('sorts partial set of inherited profiles', () => { - const foo = createProfile('foo', 'bar'); - expect(sortProfiles([foo]), ['foo']); - - const profile1 = createProfile('profile1', 'x'); - const profile2 = createProfile('profile2'); - const profile3 = createProfile('profile3', 'profile2'); - expect(sortProfiles([profile1, profile2, profile3])).toMatchSnapshot(); - }); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts new file mode 100644 index 00000000000..433702eab06 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.ts @@ -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 { sortProfiles } from '../utils'; +import { IProfile } from '../types'; + +function createProfile(key: string, parentKey?: string) { + return { name: key, key, parentKey } as IProfile; +} + +describe('#sortProfiles', () => { + it('should sort when no parents', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2'); + const profile3 = createProfile('profile3'); + expect(sortProfiles([profile1, profile2, profile3])).toMatchSnapshot(); + }); + + it('should sort by name', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2'); + const profile3 = createProfile('profile3'); + expect(sortProfiles([profile3, profile1, profile2])).toMatchSnapshot(); + }); + + it('should sort with children', () => { + const child1 = createProfile('child1', 'parent'); + const child2 = createProfile('child2', 'parent'); + const parent = createProfile('parent'); + expect(sortProfiles([child1, child2, parent])).toMatchSnapshot(); + }); + + it('should sort single branch', () => { + const profile1 = createProfile('profile1'); + const profile2 = createProfile('profile2', 'profile3'); + const profile3 = createProfile('profile3', 'profile1'); + expect(sortProfiles([profile3, profile2, profile1])).toMatchSnapshot(); + }); + + it('sorts partial set of inherited profiles', () => { + const foo = createProfile('foo', 'bar'); + expect(sortProfiles([foo])).toMatchSnapshot(); + + const profile1 = createProfile('profile1', 'x'); + const profile2 = createProfile('profile2'); + const profile3 = createProfile('profile3', 'profile2'); + expect(sortProfiles([profile1, profile2, profile3])).toMatchSnapshot(); + }); +}); 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 ( - - - {!isBulkChange && moment(event.date).format('LLL')} - - - - {!isBulkChange && - (event.authorName - ? - {event.authorName} - - : System)} - - - - {!isBulkChange && translate('quality_profiles.changelog', event.action)} - - - - - {event.ruleName} - - - - - - - - ); - }); - - return ( - - - - - - - - - - - - {rows} - -
- {translate('date')} - - {translate('user')} - - {translate('action')} - - {translate('rule')} - - {translate('parameters')} -
- ); - } -} 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 ( + + + {!isBulkChange && moment(event.date).format('LLL')} + + + + {!isBulkChange && + (event.authorName + ? + {event.authorName} + + : System)} + + + + {!isBulkChange && translate('quality_profiles.changelog', event.action)} + + + + + {event.ruleName} + + + + + {event.params && } + + + ); + }); + + return ( + + + + + + + + + + + + {rows} + +
+ {translate('date')} + + {translate('user')} + + {translate('action')} + + {translate('rule')} + + {translate('parameters')} +
+ ); +} 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.js deleted file mode 100644 index 6bca8f58b0f..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js +++ /dev/null @@ -1,204 +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'; -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'; */ - -/*:: -type 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; */ - - static contextTypes = { - router: PropTypes.object - }; - - state /*: State */ = { - loading: true - }; - - componentDidMount() { - this.mounted = true; - this.loadChangelog(); - } - - componentDidUpdate(prevProps /*: Props */) { - if (prevProps.location !== this.props.location) { - this.loadChangelog(); - } - } - - componentWillUnmount() { - this.mounted = false; - } - - loadChangelog() { - this.setState({ loading: true }); - const { query } = this.props.location; - const data /*: Object */ = { profileKey: this.props.profile.key }; - if (query.since) { - data.since = query.since; - } - if (query.to) { - data.to = query.to; - } - - getProfileChangelog(data).then(r => { - if (this.mounted) { - this.setState({ - events: r.events, - total: r.total, - page: r.p, - loading: false - }); - } - }); - } - - loadMore(e /*: SyntheticInputEvent */) { - e.preventDefault(); - e.target.blur(); - - 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 => { - 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 */) => { - const path = getProfileChangelogPath( - this.props.profile.name, - this.props.profile.language, - this.props.organization, - { - since: fromDate, - to: this.props.location.query.to - } - ); - this.context.router.push(path); - }; - - handleToDateChange = (toDate /*: string | void */) => { - const path = getProfileChangelogPath( - this.props.profile.name, - this.props.profile.language, - this.props.organization, - { - since: this.props.location.query.since, - to: toDate - } - ); - this.context.router.push(path); - }; - - handleReset = () => { - const path = getProfileChangelogPath( - this.props.profile.name, - this.props.profile.language, - this.props.organization - ); - this.context.router.push(path); - }; - - render() { - const { query } = this.props.location; - - const shouldDisplayFooter = - this.state.events != null && - this.state.total != null && - this.state.events.length < this.state.total; - - return ( -
-
- - - {this.state.loading && } -
- - {this.state.events != null && this.state.events.length === 0 && } - - {this.state.events != null && - this.state.events.length > 0 && - } - - {shouldDisplayFooter && - } -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx new file mode 100644 index 00000000000..aa54dd0c89c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.tsx @@ -0,0 +1,200 @@ +/* + * 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 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 { IProfile, IProfileChangelogEvent } from '../types'; + +interface Props { + location: { + query: { + 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 { + mounted: boolean; + + static contextTypes = { + router: PropTypes.object + }; + + state: State = { + loading: true + }; + + componentDidMount() { + this.mounted = true; + this.loadChangelog(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.location !== this.props.location) { + this.loadChangelog(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + loadChangelog() { + this.setState({ loading: true }); + const { query } = this.props.location; + const data: any = { profileKey: this.props.profile.key }; + if (query.since) { + data.since = query.since; + } + if (query.to) { + data.to = query.to; + } + + getProfileChangelog(data).then((r: any) => { + if (this.mounted) { + this.setState({ + events: r.events, + total: r.total, + page: r.p, + loading: false + }); + } + }); + } + + loadMore(event: React.SyntheticEvent) { + 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; + } + + 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 + }); + } + }); + } + } + + handleFromDateChange = (fromDate?: string) => { + const path = getProfileChangelogPath( + this.props.profile.name, + this.props.profile.language, + this.props.organization, + { + since: fromDate, + to: this.props.location.query.to + } + ); + this.context.router.push(path); + }; + + handleToDateChange = (toDate?: string) => { + const path = getProfileChangelogPath( + this.props.profile.name, + this.props.profile.language, + this.props.organization, + { + since: this.props.location.query.since, + to: toDate + } + ); + this.context.router.push(path); + }; + + handleReset = () => { + const path = getProfileChangelogPath( + this.props.profile.name, + this.props.profile.language, + this.props.organization + ); + this.context.router.push(path); + }; + + render() { + const { query } = this.props.location; + + const shouldDisplayFooter = + this.state.events != null && + this.state.total != null && + this.state.events.length < this.state.total; + + return ( +
+
+ + + {this.state.loading && } +
+ + {this.state.events != null && this.state.events.length === 0 && } + + {this.state.events != null && + this.state.events.length > 0 && + } + + {shouldDisplayFooter && + } +
+ ); + } +} 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.js deleted file mode 100644 index 96db0d8c8eb..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js +++ /dev/null @@ -1,32 +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 { translate } from '../../../helpers/l10n'; - -export default class ChangelogEmpty extends React.PureComponent { - render() { - return ( -
- {translate('no_results')} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx new file mode 100644 index 00000000000..b8a9fbaa35e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.tsx @@ -0,0 +1,29 @@ +/* + * 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 { translate } from '../../../helpers/l10n'; + +export default function ChangelogEmpty() { + return ( +
+ {translate('no_results')} +
+ ); +} 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.js deleted file mode 100644 index c0abdb0155a..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js +++ /dev/null @@ -1,66 +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 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; */ - - handleResetClick(e /*: SyntheticInputEvent */) { - e.preventDefault(); - e.target.blur(); - this.props.onReset(); - } - - render() { - return ( -
- - {' — '} - - -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx new file mode 100644 index 00000000000..e59479fccf3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx @@ -0,0 +1,61 @@ +/* + * 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 DateInput from '../../../components/controls/DateInput'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + fromDate?: string; + toDate?: string; + onFromDateChange: () => void; + onReset: () => void; + onToDateChange: () => void; +} + +export default class ChangelogSearch extends React.PureComponent { + handleResetClick(event: React.SyntheticEvent) { + event.preventDefault(); + event.currentTarget.blur(); + this.props.onReset(); + } + + render() { + return ( +
+ + {' — '} + + +
+ ); + } +} 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.js deleted file mode 100644 index c910ebb54ab..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.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 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; - - return ( -
    - {Object.keys(changes).map(key => -
  • - {key === 'severity' - ? - : } -
  • - )} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx new file mode 100644 index 00000000000..c800e44e918 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.tsx @@ -0,0 +1,40 @@ +/* + * 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 SeverityChange from './SeverityChange'; +import ParameterChange from './ParameterChange'; + +interface Props { + changes: { [change: string]: string | null }; +} + +export default function ChangesList({ changes }: Props) { + return ( +
    + {Object.keys(changes).map(key => +
  • + {key === 'severity' + ? + : } +
  • + )} +
+ ); +} 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.js deleted file mode 100644 index 9ee9d2bd80f..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js +++ /dev/null @@ -1,54 +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 { 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 ( -
- {translateWithParameters( - 'quality_profiles.changelog.parameter_reset_to_default_value', - name - )} -
- ); - } - - return ( -
- {translateWithParameters('quality_profiles.parameter_set_to', name, value)} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx new file mode 100644 index 00000000000..d62d11d7c25 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.tsx @@ -0,0 +1,45 @@ +/* + * 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 { translateWithParameters } from '../../../helpers/l10n'; + +interface Props { + name: string; + value: string | null; +} + +export default function ParameterChange({ name, value }: Props) { + if (value == null) { + return ( +
+ {translateWithParameters( + 'quality_profiles.changelog.parameter_reset_to_default_value', + name + )} +
+ ); + } + + return ( +
+ {translateWithParameters('quality_profiles.parameter_set_to', name, value)} +
+ ); +} 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.js deleted file mode 100644 index 546c46610c2..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js +++ /dev/null @@ -1,42 +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 SeverityHelper from '../../../components/shared/SeverityHelper'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = { - severity: ?string -}; -*/ - -export default class SeverityChange extends React.PureComponent { - /*:: props: Props; */ - - render() { - return ( -
- {translate('quality_profiles.severity_set_to')}{' '} - -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx new file mode 100644 index 00000000000..3c744e731a9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.tsx @@ -0,0 +1,34 @@ +/* + * 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 SeverityHelper from '../../../components/shared/SeverityHelper'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + severity: string | null; +} + +export default function SeverityChange({ severity }: Props) { + return ( +
+ {translate('quality_profiles.severity_set_to')} +
+ ); +} 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.js deleted file mode 100644 index 32774553ba1..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.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. - */ -import { shallow } from 'enzyme'; -import React from 'react'; -import Changelog from '../Changelog'; -import ChangesList from '../ChangesList'; - -function createEvent(overrides) { - return { - date: '2016-01-01', - authorName: 'John', - action: 'ACTIVATED', - ruleKey: 'squid1234', - ruleName: 'Do not do this', - params: {}, - ...overrides - }; -} - -it('should render events', () => { - const events = [createEvent(), createEvent()]; - const changelog = shallow(); - expect(changelog.find('tbody').find('tr').length).toBe(2); -}); - -it('should render event date', () => { - const events = [createEvent()]; - const changelog = shallow(); - expect(changelog.text()).toContain('2016'); -}); - -it('should render author', () => { - const events = [createEvent()]; - const changelog = shallow(); - expect(changelog.text()).toContain('John'); -}); - -it('should render system author', () => { - const events = [createEvent({ authorName: undefined })]; - const changelog = shallow(); - expect(changelog.text()).toContain('System'); -}); - -it('should render action', () => { - const events = [createEvent()]; - const changelog = shallow(); - expect(changelog.text()).toContain('ACTIVATED'); -}); - -it('should render rule', () => { - const events = [createEvent()]; - const changelog = shallow(); - 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(); - 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__/Changelog-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.tsx new file mode 100644 index 00000000000..ed8fb6b6106 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.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 { shallow } from 'enzyme'; +import * as React from 'react'; +import Changelog from '../Changelog'; +import ChangesList from '../ChangesList'; +import { IProfileChangelogEvent } from '../../types'; + +function createEvent(overrides?: { [p: string]: any }): IProfileChangelogEvent { + return { + date: '2016-01-01', + authorName: 'John', + action: 'ACTIVATED', + ruleKey: 'squid1234', + ruleName: 'Do not do this', + params: {}, + organization: null, + ...overrides + }; +} + +it('should render events', () => { + const events = [createEvent(), createEvent()]; + const changelog = shallow(); + expect(changelog.find('tbody').find('tr').length).toBe(2); +}); + +it('should render event date', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).toContain('2016'); +}); + +it('should render author', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).toContain('John'); +}); + +it('should render system author', () => { + const events = [createEvent({ authorName: undefined })]; + const changelog = shallow(); + expect(changelog.text()).toContain('System'); +}); + +it('should render action', () => { + const events = [createEvent()]; + const changelog = shallow(); + expect(changelog.text()).toContain('ACTIVATED'); +}); + +it('should render rule', () => { + const events = [createEvent()]; + const changelog = shallow(); + 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(); + 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.js deleted file mode 100644 index be461db98d4..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js +++ /dev/null @@ -1,60 +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 { shallow } from 'enzyme'; -import React from 'react'; -import ChangelogSearch from '../ChangelogSearch'; -import DateInput from '../../../../components/controls/DateInput'; -import { click } from '../../../../helpers/testUtils'; - -it('should render DateInput', () => { - const onFromDateChange = jest.fn(); - const onToDateChange = jest.fn(); - const output = shallow( - - ); - const dateInputs = output.find(DateInput); - expect(dateInputs.length).toBe(2); - expect(dateInputs.at(0).prop('value')).toBe('2016-01-01'); - expect(dateInputs.at(0).prop('onChange')).toBe(onFromDateChange); - expect(dateInputs.at(1).prop('value')).toBe('2016-05-05'); - expect(dateInputs.at(1).prop('onChange')).toBe(onToDateChange); -}); - -it('should reset', () => { - const onReset = jest.fn(); - const output = shallow( - - ); - expect(onReset).not.toBeCalled(); - click(output.find('button')); - expect(onReset).toBeCalled(); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx new file mode 100644 index 00000000000..78dd87a4b9f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.tsx @@ -0,0 +1,60 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import ChangelogSearch from '../ChangelogSearch'; +import DateInput from '../../../../components/controls/DateInput'; +import { click } from '../../../../helpers/testUtils'; + +it('should render DateInput', () => { + const onFromDateChange = jest.fn(); + const onToDateChange = jest.fn(); + const output = shallow( + + ); + const dateInputs = output.find(DateInput); + expect(dateInputs.length).toBe(2); + expect(dateInputs.at(0).prop('value')).toBe('2016-01-01'); + expect(dateInputs.at(0).prop('onChange')).toBe(onFromDateChange); + expect(dateInputs.at(1).prop('value')).toBe('2016-05-05'); + expect(dateInputs.at(1).prop('onChange')).toBe(onToDateChange); +}); + +it('should reset', () => { + const onReset = jest.fn(); + const output = shallow( + + ); + expect(onReset).not.toBeCalled(); + click(output.find('button')); + expect(onReset).toBeCalled(); +}); 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.js deleted file mode 100644 index 7ccb56ee199..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js +++ /dev/null @@ -1,45 +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 { shallow } from 'enzyme'; -import React from 'react'; -import ChangesList from '../ChangesList'; -import SeverityChange from '../SeverityChange'; -import ParameterChange from '../ParameterChange'; - -it('should render changes', () => { - const changes = { severity: 'BLOCKER', foo: 'bar' }; - const output = shallow(); - expect(output.find('li').length).toBe(2); -}); - -it('should render severity change', () => { - const changes = { severity: 'BLOCKER' }; - const output = shallow().find(SeverityChange); - expect(output.length).toBe(1); - expect(output.prop('severity')).toBe('BLOCKER'); -}); - -it('should render parameter change', () => { - const changes = { foo: 'bar' }; - const output = shallow().find(ParameterChange); - expect(output.length).toBe(1); - expect(output.prop('name')).toBe('foo'); - expect(output.prop('value')).toBe('bar'); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx new file mode 100644 index 00000000000..82ddc9af0a0 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.tsx @@ -0,0 +1,45 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import ChangesList from '../ChangesList'; +import SeverityChange from '../SeverityChange'; +import ParameterChange from '../ParameterChange'; + +it('should render changes', () => { + const changes = { severity: 'BLOCKER', foo: 'bar' }; + const output = shallow(); + expect(output.find('li').length).toBe(2); +}); + +it('should render severity change', () => { + const changes = { severity: 'BLOCKER' }; + const output = shallow().find(SeverityChange); + expect(output.length).toBe(1); + expect(output.prop('severity')).toBe('BLOCKER'); +}); + +it('should render parameter change', () => { + const changes = { foo: 'bar' }; + const output = shallow().find(ParameterChange); + expect(output.length).toBe(1); + expect(output.prop('name')).toBe('foo'); + expect(output.prop('value')).toBe('bar'); +}); 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.js deleted file mode 100644 index 25032b3e07a..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.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. - */ -import { shallow } from 'enzyme'; -import React from 'react'; -import ParameterChange from '../ParameterChange'; - -it('should render different messages', () => { - const first = shallow(); - const second = shallow(); - expect(first.text()).not.toBe(second.text()); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx new file mode 100644 index 00000000000..de80150b085 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.tsx @@ -0,0 +1,28 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import ParameterChange from '../ParameterChange'; + +it('should render different messages', () => { + const first = shallow(); + const second = shallow(); + 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.js deleted file mode 100644 index 8597dd0ab8c..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js +++ /dev/null @@ -1,29 +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 { shallow } from 'enzyme'; -import React from 'react'; -import SeverityChange from '../SeverityChange'; -import SeverityHelper from '../../../../components/shared/SeverityHelper'; - -it('should render SeverityHelper', () => { - const output = shallow().find(SeverityHelper); - expect(output.length).toBe(1); - expect(output.prop('severity')).toBe('BLOCKER'); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx new file mode 100644 index 00000000000..bc5f6553420 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.tsx @@ -0,0 +1,29 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import SeverityChange from '../SeverityChange'; +import SeverityHelper from '../../../../components/shared/SeverityHelper'; + +it('should render SeverityHelper', () => { + const output = shallow().find(SeverityHelper); + expect(output.length).toBe(1); + expect(output.prop('severity')).toBe('BLOCKER'); +}); 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.js deleted file mode 100644 index 718d80dcc3d..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js +++ /dev/null @@ -1,140 +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'; -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 -}; -*/ - -/*:: -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; */ - - static contextTypes = { - router: PropTypes.object - }; - - constructor(props /*: Props */) { - super(props); - this.state = { loading: false }; - } - - componentDidMount() { - this.mounted = true; - this.loadResults(); - } - - componentDidUpdate(prevProps /*: Props */) { - if (prevProps.profile !== this.props.profile || prevProps.location !== this.props.location) { - this.loadResults(); - } - } - - componentWillUnmount() { - this.mounted = false; - } - - loadResults() { - const { withKey } = this.props.location.query; - if (!withKey) { - this.setState({ left: undefined, loading: false }); - return; - } - - this.setState({ loading: true }); - compareProfiles(this.props.profile.key, withKey).then(r => { - if (this.mounted) { - this.setState({ - left: r.left, - right: r.right, - inLeft: r.inLeft, - inRight: r.inRight, - modified: r.modified, - loading: false - }); - } - }); - } - - handleCompare = (withKey /*: string */) => { - const path = getProfileComparePath( - this.props.profile.name, - this.props.profile.language, - this.props.organization, - withKey - ); - this.context.router.push(path); - }; - - render() { - const { profile, profiles, location } = this.props; - const { withKey } = location.query; - const { left, right, inLeft, inRight, modified } = this.state; - - return ( -
-
- - - {this.state.loading && } -
- - {left != null && - } -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx new file mode 100644 index 00000000000..003fd55a6d3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx @@ -0,0 +1,144 @@ +/* + * 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 PropTypes from 'prop-types'; +import ComparisonForm from './ComparisonForm'; +import ComparisonResults from './ComparisonResults'; +import { compareProfiles } from '../../../api/quality-profiles'; +import { getProfileComparePath } from '../utils'; +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 { + mounted: boolean; + + static contextTypes = { + router: PropTypes.object + }; + + constructor(props: Props) { + super(props); + this.state = { loading: false }; + } + + componentDidMount() { + this.mounted = true; + this.loadResults(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.profile !== this.props.profile || prevProps.location !== this.props.location) { + this.loadResults(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + loadResults() { + const { withKey } = this.props.location.query; + if (!withKey) { + this.setState({ left: undefined, loading: false }); + return; + } + + this.setState({ loading: true }); + compareProfiles(this.props.profile.key, withKey).then((r: any) => { + if (this.mounted) { + this.setState({ + left: r.left, + right: r.right, + inLeft: r.inLeft, + inRight: r.inRight, + modified: r.modified, + loading: false + }); + } + }); + } + + handleCompare = (withKey: string) => { + const path = getProfileComparePath( + this.props.profile.name, + this.props.profile.language, + this.props.organization, + withKey + ); + this.context.router.push(path); + }; + + render() { + const { profile, profiles, location } = this.props; + const { withKey } = location.query; + const { left, right, inLeft, inRight, modified } = this.state; + + return ( +
+
+ + + {this.state.loading && } +
+ + {left != null && + inLeft != null && + right != null && + inRight != null && + modified != null && + } +
+ ); + } +} 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.js deleted file mode 100644 index b3a19a37f5c..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js +++ /dev/null @@ -1,32 +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 { translate } from '../../../helpers/l10n'; - -export default class ComparisonEmpty extends React.PureComponent { - render() { - return ( -
- {translate('quality_profile.empty_comparison')} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx new file mode 100644 index 00000000000..a6a2c390289 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.tsx @@ -0,0 +1,29 @@ +/* + * 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 { translate } from '../../../helpers/l10n'; + +export default function ComparisonEmpty() { + return ( +
+ {translate('quality_profile.empty_comparison')} +
+ ); +} 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.js deleted file mode 100644 index c0a0086f006..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js +++ /dev/null @@ -1,63 +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 Select from 'react-select'; -import { translate } from '../../../helpers/l10n'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - profile: Profile, - profiles: Array, - onCompare: string => void, - withKey: string -}; -*/ - -export default class ComparisonForm extends React.PureComponent { - /*:: props: Props; */ - - handleChange(option /*: { value: string } */) { - this.props.onCompare(option.value); - } - - render() { - const { profile, profiles, withKey } = this.props; - const options = profiles - .filter(p => p.language === profile.language && p !== profile) - .map(p => ({ value: p.key, label: p.name })); - - return ( -
- - +
+ ); + } +} 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.js deleted file mode 100644 index b13c88ecace..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js +++ /dev/null @@ -1,192 +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 ComparisonEmpty from './ComparisonEmpty'; -import SeverityIcon from '../../../components/shared/SeverityIcon'; -import { translateWithParameters } from '../../../helpers/l10n'; -import { getRulesUrl } from '../../../helpers/urls'; - -/*:: -type Params = { [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; */ - - renderRule(rule /*: { key: string, name: string } */, severity /*: string */) { - return ( -
- {' '} - {rule.name} -
- ); - } - - renderParameters(params /*: Params */) { - if (!params) { - return null; - } - return ( -
    - {Object.keys(params).map(key => -
  • - - {key} - {': '} - {params[key]} - -
  • - )} -
- ); - } - - renderLeft() { - if (this.props.inLeft.length === 0) { - return null; - } - const header = ( - - -
- {translateWithParameters( - 'quality_profiles.x_rules_only_in', - this.props.inLeft.length - )}{' '} - {this.props.left.name} -
- -   - - ); - const rows = this.props.inLeft.map(rule => - - - {this.renderRule(rule, rule.severity)} - -   - - ); - return [header, ...rows]; - } - - renderRight() { - if (this.props.inRight.length === 0) { - return null; - } - const header = ( - -   - -
- {translateWithParameters( - 'quality_profiles.x_rules_only_in', - this.props.inRight.length - )}{' '} - {this.props.right.name} -
- - - ); - const rows = this.props.inRight.map(rule => - -   - - {this.renderRule(rule, rule.severity)} - - - ); - return [header, ...rows]; - } - - renderModified() { - if (this.props.modified.length === 0) { - return null; - } - const header = ( - - -
- {translateWithParameters( - 'quality_profiles.x_rules_have_different_configuration', - this.props.modified.length - )} -
- - - ); - const secondHeader = ( - - -
- {this.props.left.name} -
- - -
- {this.props.right.name} -
- - - ); - const rows = this.props.modified.map(rule => - - - {this.renderRule(rule, rule.left.severity)} - {this.renderParameters(rule.left.params)} - - - {this.renderRule(rule, rule.right.severity)} - {this.renderParameters(rule.right.params)} - - - ); - return [header, secondHeader, ...rows]; - } - - render() { - if (!this.props.inLeft.length && !this.props.inRight.length && !this.props.modified.length) { - return ; - } - - return ( - - - {this.renderLeft()} - {this.renderRight()} - {this.renderModified()} - -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx new file mode 100644 index 00000000000..f29c2ec1c2b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx @@ -0,0 +1,190 @@ +/* + * 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 ComparisonEmpty from './ComparisonEmpty'; +import SeverityIcon from '../../../components/shared/SeverityIcon'; +import { translateWithParameters } from '../../../helpers/l10n'; +import { getRulesUrl } from '../../../helpers/urls'; + +type Params = { [p: string]: string }; + +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; +} + +export default class ComparisonResults extends React.PureComponent { + renderRule(rule: { key: string; name: string }, severity: string) { + return ( +
+ {' '} + {rule.name} +
+ ); + } + + renderParameters(params: Params) { + if (!params) { + return null; + } + return ( +
    + {Object.keys(params).map(key => +
  • + + {key} + {': '} + {params[key]} + +
  • + )} +
+ ); + } + + renderLeft() { + if (this.props.inLeft.length === 0) { + return null; + } + const header = ( + + +
+ {translateWithParameters( + 'quality_profiles.x_rules_only_in', + this.props.inLeft.length + )}{' '} + {this.props.left.name} +
+ +   + + ); + const rows = this.props.inLeft.map(rule => + + + {this.renderRule(rule, rule.severity)} + +   + + ); + return [header, ...rows]; + } + + renderRight() { + if (this.props.inRight.length === 0) { + return null; + } + const header = ( + +   + +
+ {translateWithParameters( + 'quality_profiles.x_rules_only_in', + this.props.inRight.length + )}{' '} + {this.props.right.name} +
+ + + ); + const rows = this.props.inRight.map(rule => + +   + + {this.renderRule(rule, rule.severity)} + + + ); + return [header, ...rows]; + } + + renderModified() { + if (this.props.modified.length === 0) { + return null; + } + const header = ( + + +
+ {translateWithParameters( + 'quality_profiles.x_rules_have_different_configuration', + this.props.modified.length + )} +
+ + + ); + const secondHeader = ( + + +
+ {this.props.left.name} +
+ + +
+ {this.props.right.name} +
+ + + ); + const rows = this.props.modified.map(rule => + + + {this.renderRule(rule, rule.left.severity)} + {this.renderParameters(rule.left.params)} + + + {this.renderRule(rule, rule.right.severity)} + {this.renderParameters(rule.right.params)} + + + ); + return [header, secondHeader, ...rows]; + } + + render() { + if (!this.props.inLeft.length && !this.props.inRight.length && !this.props.modified.length) { + return ; + } + + return ( + + + {this.renderLeft()} + {this.renderRight()} + {this.renderModified()} + +
+ ); + } +} 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.js deleted file mode 100644 index b972451e628..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js +++ /dev/null @@ -1,45 +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 { shallow } from 'enzyme'; -import React from 'react'; -import Select from 'react-select'; -import ComparisonForm from '../ComparisonForm'; -import { createFakeProfile } from '../../utils'; - -it('should render Select with right options', () => { - const profile = createFakeProfile(); - const profiles = [ - profile, - createFakeProfile({ key: 'another', name: 'another name' }), - createFakeProfile({ key: 'java', name: 'java', language: 'java' }) - ]; - - const output = shallow( - true} - /> - ).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__/ComparisonForm-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx new file mode 100644 index 00000000000..55edbd993fe --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.tsx @@ -0,0 +1,44 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import ComparisonForm from '../ComparisonForm'; +import { createFakeProfile } from '../../utils'; + +it('should render Select with right options', () => { + const profile = createFakeProfile(); + const profiles = [ + profile, + createFakeProfile({ key: 'another', name: 'another name' }), + createFakeProfile({ key: 'java', name: 'java', language: 'java' }) + ]; + + const output = shallow( + true} + /> + ).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.js deleted file mode 100644 index d346aa2f480..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.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 { shallow } from 'enzyme'; -import React from 'react'; -import { Link } from 'react-router'; -import ComparisonResults from '../ComparisonResults'; -import ComparisonEmpty from '../ComparisonEmpty'; -import SeverityIcon from '../../../../components/shared/SeverityIcon'; - -it('should render ComparisonEmpty', () => { - const output = shallow( - - ); - expect(output.is(ComparisonEmpty)).toBe(true); -}); - -it('should compare', () => { - const inLeft = [{ key: 'rule1', name: 'rule1', severity: 'BLOCKER' }]; - const inRight = [ - { key: 'rule2', name: 'rule2', severity: 'CRITICAL' }, - { key: 'rule3', name: 'rule3', severity: 'MAJOR' } - ]; - const modified = [ - { - key: 'rule4', - name: 'rule4', - left: { - severity: 'BLOCKER', - params: { foo: 'bar' } - }, - right: { - severity: 'INFO', - params: { foo: 'qwe' } - } - } - ]; - - const output = shallow( - - ); - - const leftDiffs = output.find('.js-comparison-in-left'); - expect(leftDiffs.length).toBe(1); - expect(leftDiffs.find(Link).length).toBe(1); - expect(leftDiffs.find(Link).prop('to')).toContain('rule_key=rule1'); - expect(leftDiffs.find(Link).prop('children')).toContain('rule1'); - expect(leftDiffs.find(SeverityIcon).length).toBe(1); - expect(leftDiffs.find(SeverityIcon).prop('severity')).toBe('BLOCKER'); - - const rightDiffs = output.find('.js-comparison-in-right'); - expect(rightDiffs.length).toBe(2); - expect(rightDiffs.at(0).find(Link).length).toBe(1); - expect(rightDiffs.at(0).find(Link).prop('to')).toContain('rule_key=rule2'); - expect(rightDiffs.at(0).find(Link).prop('children')).toContain('rule2'); - expect(rightDiffs.at(0).find(SeverityIcon).length).toBe(1); - expect(rightDiffs.at(0).find(SeverityIcon).prop('severity')).toBe('CRITICAL'); - - const modifiedDiffs = output.find('.js-comparison-modified'); - expect(modifiedDiffs.length).toBe(1); - expect(modifiedDiffs.find(Link).at(0).prop('to')).toContain('rule_key=rule4'); - expect(modifiedDiffs.find(Link).at(0).prop('children')).toContain('rule4'); - expect(modifiedDiffs.find(SeverityIcon).length).toBe(2); - expect(modifiedDiffs.text()).toContain('bar'); - expect(modifiedDiffs.text()).toContain('qwe'); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx new file mode 100644 index 00000000000..c3200b06612 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.tsx @@ -0,0 +1,96 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import { Link } from 'react-router'; +import ComparisonResults from '../ComparisonResults'; +import ComparisonEmpty from '../ComparisonEmpty'; +import SeverityIcon from '../../../../components/shared/SeverityIcon'; + +it('should render ComparisonEmpty', () => { + const output = shallow( + + ); + expect(output.is(ComparisonEmpty)).toBe(true); +}); + +it('should compare', () => { + const inLeft = [{ key: 'rule1', name: 'rule1', severity: 'BLOCKER' }]; + const inRight = [ + { key: 'rule2', name: 'rule2', severity: 'CRITICAL' }, + { key: 'rule3', name: 'rule3', severity: 'MAJOR' } + ]; + const modified = [ + { + key: 'rule4', + name: 'rule4', + left: { + severity: 'BLOCKER', + params: { foo: 'bar' } + }, + right: { + severity: 'INFO', + params: { foo: 'qwe' } + } + } + ]; + + const output = shallow( + + ); + + const leftDiffs = output.find('.js-comparison-in-left'); + expect(leftDiffs.length).toBe(1); + expect(leftDiffs.find(Link).length).toBe(1); + expect(leftDiffs.find(Link).prop('to')).toContain('rule_key=rule1'); + expect(leftDiffs.find(Link).prop('children')).toContain('rule1'); + expect(leftDiffs.find(SeverityIcon).length).toBe(1); + expect(leftDiffs.find(SeverityIcon).prop('severity')).toBe('BLOCKER'); + + const rightDiffs = output.find('.js-comparison-in-right'); + expect(rightDiffs.length).toBe(2); + expect(rightDiffs.at(0).find(Link).length).toBe(1); + expect(rightDiffs.at(0).find(Link).prop('to')).toContain('rule_key=rule2'); + expect(rightDiffs.at(0).find(Link).prop('children')).toContain('rule2'); + expect(rightDiffs.at(0).find(SeverityIcon).length).toBe(1); + expect(rightDiffs.at(0).find(SeverityIcon).prop('severity')).toBe('CRITICAL'); + + const modifiedDiffs = output.find('.js-comparison-modified'); + expect(modifiedDiffs.length).toBe(1); + expect(modifiedDiffs.find(Link).at(0).prop('to')).toContain('rule_key=rule4'); + expect(modifiedDiffs.find(Link).at(0).prop('children')).toContain('rule4'); + expect(modifiedDiffs.find(SeverityIcon).length).toBe(2); + expect(modifiedDiffs.text()).toContain('bar'); + expect(modifiedDiffs.text()).toContain('qwe'); +}); 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.js deleted file mode 100644 index b0f80ee623b..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js +++ /dev/null @@ -1,134 +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 { 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'; - -/*:: -type Props = { - children: React.Element<*>, - currentUser: { permissions: { global: Array } }, - languages: Array<*>, - onRequestFail: Object => void, - organization: { name: string, canAdmin?: boolean, key: string } | null -}; -*/ - -/*:: -type State = { - loading: boolean, - exporters?: Array, - profiles?: Array<*> -}; -*/ - -export default class App extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { loading: true }; - - componentWillMount() { - const html = document.querySelector('html'); - if (html) { - html.classList.add('dashboard-page'); - } - } - - componentDidMount() { - this.mounted = true; - this.loadData(); - } - - componentWillUnmount() { - this.mounted = false; - const html = document.querySelector('html'); - if (html) { - html.classList.remove('dashboard-page'); - } - } - - fetchProfiles() { - const { organization } = this.props; - const data = organization ? { organization: organization.key } : {}; - return searchQualityProfiles(data); - } - - loadData() { - this.setState({ loading: true }); - Promise.all([getExporters(), this.fetchProfiles()]).then(responses => { - if (this.mounted) { - const [exporters, profiles] = responses; - this.setState({ - exporters, - profiles: sortProfiles(profiles), - loading: false - }); - } - }); - } - - updateProfiles = () => { - return this.fetchProfiles().then(profiles => { - if (this.mounted) { - this.setState({ profiles: sortProfiles(profiles) }); - } - }); - }; - - renderChild() { - if (this.state.loading) { - return ; - } - const { organization } = this.props; - const finalLanguages = Object.values(this.props.languages); - - const canAdmin = organization - ? organization.canAdmin - : this.props.currentUser.permissions.global.includes('profileadmin'); - - return React.cloneElement(this.props.children, { - profiles: this.state.profiles, - languages: finalLanguages, - exporters: this.state.exporters, - updateProfiles: this.updateProfiles, - onRequestFail: this.props.onRequestFail, - organization: organization ? organization.key : null, - canAdmin - }); - } - - render() { - return ( -
- - - {this.renderChild()} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx new file mode 100644 index 00000000000..44013b73e70 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx @@ -0,0 +1,128 @@ +/* + * 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 { searchQualityProfiles, getExporters } from '../../../api/quality-profiles'; +import { sortProfiles } from '../utils'; +import { translate } from '../../../helpers/l10n'; +import OrganizationHelmet from '../../../components/common/OrganizationHelmet'; +import '../styles.css'; +import { IExporter, IProfile } from '../types'; + +interface Props { + children: React.ReactElement; + currentUser: { permissions: { global: Array } }; + languages: Array<{}>; + onRequestFail: (reasong: any) => void; + organization: { name: string; canAdmin?: boolean; key: string } | null; +} + +interface State { + loading: boolean; + exporters?: IExporter[]; + profiles?: IProfile[]; +} + +export default class App extends React.PureComponent { + mounted: boolean; + state: State = { loading: true }; + + componentWillMount() { + const html = document.querySelector('html'); + if (html) { + html.classList.add('dashboard-page'); + } + } + + componentDidMount() { + this.mounted = true; + this.loadData(); + } + + componentWillUnmount() { + this.mounted = false; + const html = document.querySelector('html'); + if (html) { + html.classList.remove('dashboard-page'); + } + } + + fetchProfiles() { + const { organization } = this.props; + const data = organization ? { organization: organization.key } : {}; + return searchQualityProfiles(data); + } + + loadData() { + this.setState({ loading: true }); + Promise.all([getExporters(), this.fetchProfiles()]).then(responses => { + if (this.mounted) { + const [exporters, profiles] = responses; + this.setState({ + exporters, + profiles: sortProfiles(profiles), + loading: false + }); + } + }); + } + + updateProfiles = () => { + return this.fetchProfiles().then((profiles: any) => { + if (this.mounted) { + this.setState({ profiles: sortProfiles(profiles) }); + } + }); + }; + + renderChild() { + if (this.state.loading) { + return ; + } + const { organization } = this.props; + const finalLanguages = Object.values(this.props.languages); + + const canAdmin = organization + ? organization.canAdmin + : this.props.currentUser.permissions.global.includes('profileadmin'); + + return React.cloneElement(this.props.children, { + profiles: this.state.profiles, + languages: finalLanguages, + exporters: this.state.exporters, + updateProfiles: this.updateProfiles, + onRequestFail: this.props.onRequestFail, + organization: organization ? organization.key : null, + canAdmin + }); + } + + render() { + return ( +
+ + + {this.renderChild()} +
+ ); + } +} 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.js deleted file mode 100644 index a9809ffe0dc..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js +++ /dev/null @@ -1,37 +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 { connect } from 'react-redux'; -import App from './App'; -import { getLanguages, getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer'; -import { onFail } from '../../../store/rootActions'; - -const mapStateToProps = (state, ownProps) => ({ - currentUser: getCurrentUser(state), - languages: getLanguages(state), - organization: ownProps.params.organizationKey - ? getOrganizationByKey(state, ownProps.params.organizationKey) - : null -}); - -const mapDispatchToProps = dispatch => ({ - onRequestFail: error => onFail(dispatch)(error) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx new file mode 100644 index 00000000000..9eb3af6d784 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx @@ -0,0 +1,37 @@ +/* + * 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 { connect } from 'react-redux'; +import App from './App'; +import { getLanguages, getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer'; +import { onFail } from '../../../store/rootActions'; + +const mapStateToProps = (state: any, ownProps: any) => ({ + currentUser: getCurrentUser(state), + languages: getLanguages(state), + organization: ownProps.params.organizationKey + ? getOrganizationByKey(state, ownProps.params.organizationKey) + : null +}); + +const mapDispatchToProps = (dispatch: any) => ({ + onRequestFail: (error: any) => onFail(dispatch)(error) +}); + +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.js deleted file mode 100644 index fa2e1635620..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.js +++ /dev/null @@ -1,56 +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 classNames from 'classnames'; -import Tooltip from '../../../components/controls/Tooltip'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = {| - className?: string, - tooltip?: boolean -|}; -*/ - -export default function BuiltInBadge(props /*: Props */) { - const badge = ( -
- {translate('quality_profiles.built_in')} -
- ); - - const overlay = ( - - {translate('quality_profiles.built_in.description.1')}{' '} - {translate('quality_profiles.built_in.description.2')} - - ); - - return props.tooltip - ? - {badge} - - : badge; -} - -BuiltInBadge.defaultProps = { - tooltip: true -}; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx new file mode 100644 index 00000000000..7a70614d3e5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInBadge.tsx @@ -0,0 +1,49 @@ +/* + * 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 classNames from 'classnames'; +import Tooltip from '../../../components/controls/Tooltip'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + className?: string; + tooltip?: boolean; +} + +export default function BuiltInBadge({ className, tooltip = true }: Props) { + const badge = ( +
+ {translate('quality_profiles.built_in')} +
+ ); + + const overlay = ( + + {translate('quality_profiles.built_in.description.1')}{' '} + {translate('quality_profiles.built_in.description.2')} + + ); + + return tooltip + ? + {badge} + + : badge; +} 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.js deleted file mode 100644 index 4ad268e4982..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.js +++ /dev/null @@ -1,139 +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 Modal from 'react-modal'; -/*:: import type { Profile } from '../propTypes'; */ -import { copyProfile } from '../../../api/quality-profiles'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; - -/*:: -type Props = { - onClose: () => void, - onCopy: string => void, - onRequestFail: Object => void, - profile: Profile -}; -*/ - -/*:: -type State = { - loading: boolean, - name: ?string -}; -*/ - -export default class CopyProfileForm extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { loading: false, name: null }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => { - this.setState({ name: event.currentTarget.value }); - }; - - handleFormSubmit = (event /*: Event */) => { - event.preventDefault(); - - const { name } = this.state; - - if (name != null) { - this.setState({ loading: true }); - copyProfile(this.props.profile.key, name).then( - profile => this.props.onCopy(profile.name), - error => { - if (this.mounted) { - this.setState({ loading: false }); - } - this.props.onRequestFail(error); - } - ); - } - }; - - render() { - const { profile } = this.props; - const header = translateWithParameters( - 'quality_profiles.copy_x_title', - profile.name, - profile.languageName - ); - const submitDisabled = - this.state.loading || !this.state.name || this.state.name === profile.name; - - return ( - -
-
-

- {header} -

-
-
-
- - -
-
-
- {this.state.loading && } - - - {translate('cancel')} - -
- -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx new file mode 100644 index 00000000000..4d24898081d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx @@ -0,0 +1,133 @@ +/* + * 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 Modal from 'react-modal'; +import { copyProfile } from '../../../api/quality-profiles'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + onClose: () => void; + onCopy: (name: string) => void; + onRequestFail: (reasong: any) => void; + profile: IProfile; +} + +interface State { + loading: boolean; + name: string | null; +} + +export default class CopyProfileForm extends React.PureComponent { + mounted: boolean; + state: State = { loading: false, name: null }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + handleCancelClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + handleNameChange = (event: React.SyntheticEvent) => { + this.setState({ name: event.currentTarget.value }); + }; + + handleFormSubmit = (event: React.SyntheticEvent) => { + event.preventDefault(); + + const { name } = this.state; + + if (name != null) { + this.setState({ loading: true }); + copyProfile(this.props.profile.key, name).then( + (profile: any) => this.props.onCopy(profile.name), + (error: any) => { + if (this.mounted) { + this.setState({ loading: false }); + } + this.props.onRequestFail(error); + } + ); + } + }; + + render() { + const { profile } = this.props; + const header = translateWithParameters( + 'quality_profiles.copy_x_title', + profile.name, + profile.languageName + ); + const submitDisabled = + this.state.loading || !this.state.name || this.state.name === profile.name; + + return ( + +
+
+

+ {header} +

+
+
+
+ + +
+
+
+ {this.state.loading && } + + + {translate('cancel')} + +
+ +
+ ); + } +} 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.js deleted file mode 100644 index 975ca0a32db..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.js +++ /dev/null @@ -1,124 +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 Modal from 'react-modal'; -/*:: import type { Profile } from '../propTypes'; */ -import { deleteProfile } from '../../../api/quality-profiles'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; - -/*:: -type Props = { - onClose: () => void, - onDelete: () => void, - onRequestFail: Object => void, - profile: Profile -}; -*/ - -/*:: -type State = { - loading: boolean -}; -*/ - -export default class DeleteProfileForm extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { loading: false, name: null }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleFormSubmit = (event /*: Event */) => { - event.preventDefault(); - this.setState({ loading: true }); - deleteProfile(this.props.profile.key).then(this.props.onDelete, error => { - if (this.mounted) { - this.setState({ loading: false }); - } - this.props.onRequestFail(error); - }); - }; - - render() { - const { profile } = this.props; - const header = translate('quality_profiles.delete_confirm_title'); - - return ( - -
-
-

- {header} -

-
-
-
- {profile.childrenCount > 0 - ?
-
- {translate('quality_profiles.this_profile_has_descendants')} -
-

- {translateWithParameters( - 'quality_profiles.are_you_sure_want_delete_profile_x_and_descendants', - profile.name, - profile.languageName - )} -

-
- :

- {translateWithParameters( - 'quality_profiles.are_you_sure_want_delete_profile_x', - profile.name, - profile.languageName - )} -

} -
-
- {this.state.loading && } - - - {translate('cancel')} - -
- - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx new file mode 100644 index 00000000000..5a7b22719db --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx @@ -0,0 +1,119 @@ +/* + * 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 Modal from 'react-modal'; +import { deleteProfile } from '../../../api/quality-profiles'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + onClose: () => void; + onDelete: () => void; + onRequestFail: (reason: any) => void; + profile: IProfile; +} + +interface State { + loading: boolean; + name: string | null; +} + +export default class DeleteProfileForm extends React.PureComponent { + mounted: boolean; + state: State = { loading: false, name: null }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + handleCancelClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + handleFormSubmit = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ loading: true }); + deleteProfile(this.props.profile.key).then(this.props.onDelete, (error: any) => { + if (this.mounted) { + this.setState({ loading: false }); + } + this.props.onRequestFail(error); + }); + }; + + render() { + const { profile } = this.props; + const header = translate('quality_profiles.delete_confirm_title'); + + return ( + +
+
+

+ {header} +

+
+
+
+ {profile.childrenCount > 0 + ?
+
+ {translate('quality_profiles.this_profile_has_descendants')} +
+

+ {translateWithParameters( + 'quality_profiles.are_you_sure_want_delete_profile_x_and_descendants', + profile.name, + profile.languageName + )} +

+
+ :

+ {translateWithParameters( + 'quality_profiles.are_you_sure_want_delete_profile_x', + profile.name, + profile.languageName + )} +

} +
+
+ {this.state.loading && } + + + {translate('cancel')} + +
+ + + ); + } +} 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.js deleted file mode 100644 index 8a2b2f805f0..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js +++ /dev/null @@ -1,221 +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'; -import { Link } from 'react-router'; -import RenameProfileForm from './RenameProfileForm'; -import CopyProfileForm from './CopyProfileForm'; -import DeleteProfileForm from './DeleteProfileForm'; -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; */ - - static defaultProps = { - fromList: false - }; - - static contextTypes = { - router: PropTypes.object - }; - - constructor(props /*: Props */) { - super(props); - this.state = { - copyFormOpen: false, - deleteFormOpen: false, - renameFormOpen: false - }; - } - - handleRenameClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ renameFormOpen: true }); - }; - - handleProfileRename = (name /*: string */) => { - this.closeRenameForm(); - this.props.updateProfiles().then(() => { - if (!this.props.fromList) { - this.context.router.replace( - getProfilePath(name, this.props.profile.language, this.props.organization) - ); - } - }); - }; - - closeRenameForm = () => { - this.setState({ renameFormOpen: false }); - }; - - handleCopyClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ copyFormOpen: true }); - }; - - handleProfileCopy = (name /*: string */) => { - this.props.updateProfiles().then(() => { - this.context.router.push( - getProfilePath(name, this.props.profile.language, this.props.organization) - ); - }); - }; - - closeCopyForm = () => { - this.setState({ copyFormOpen: false }); - }; - - handleSetDefaultClick = (e /*: SyntheticInputEvent */) => { - e.preventDefault(); - setDefaultProfile(this.props.profile.key).then(this.props.updateProfiles); - }; - - handleDeleteClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ deleteFormOpen: true }); - }; - - handleProfileDelete = () => { - this.context.router.replace(getProfilesPath(this.props.organization)); - this.props.updateProfiles(); - }; - - closeDeleteForm = () => { - this.setState({ deleteFormOpen: false }); - }; - - render() { - const { profile, canAdmin } = this.props; - - // FIXME use org, name and lang - const backupUrl = - window.baseUrl + '/api/qualityprofiles/backup?profileKey=' + encodeURIComponent(profile.key); - - const activateMoreUrl = getRulesUrl( - { - qprofile: profile.key, - activation: 'false' - }, - this.props.organization - ); - - return ( - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx new file mode 100644 index 00000000000..6d1ad5c0120 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx @@ -0,0 +1,215 @@ +/* + * 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 PropTypes from 'prop-types'; +import { Link } from 'react-router'; +import RenameProfileForm from './RenameProfileForm'; +import CopyProfileForm from './CopyProfileForm'; +import DeleteProfileForm from './DeleteProfileForm'; +import { translate } from '../../../helpers/l10n'; +import { getRulesUrl } from '../../../helpers/urls'; +import { setDefaultProfile } from '../../../api/quality-profiles'; +import { getProfilePath, getProfileComparePath, getProfilesPath } from '../utils'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + fromList?: boolean; + onRequestFail: (reasong: any) => void; + organization: string | null; + profile: IProfile; + updateProfiles: () => Promise; +} + +interface State { + copyFormOpen: boolean; + deleteFormOpen: boolean; + renameFormOpen: boolean; +} + +export default class ProfileActions extends React.PureComponent { + static defaultProps = { + fromList: false + }; + + static contextTypes = { + router: PropTypes.object + }; + + constructor(props: Props) { + super(props); + this.state = { + copyFormOpen: false, + deleteFormOpen: false, + renameFormOpen: false + }; + } + + handleRenameClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ renameFormOpen: true }); + }; + + handleProfileRename = (name: string) => { + this.closeRenameForm(); + this.props.updateProfiles().then(() => { + if (!this.props.fromList) { + this.context.router.replace( + getProfilePath(name, this.props.profile.language, this.props.organization) + ); + } + }); + }; + + closeRenameForm = () => { + this.setState({ renameFormOpen: false }); + }; + + handleCopyClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ copyFormOpen: true }); + }; + + handleProfileCopy = (name: string) => { + this.props.updateProfiles().then(() => { + this.context.router.push( + getProfilePath(name, this.props.profile.language, this.props.organization) + ); + }); + }; + + closeCopyForm = () => { + this.setState({ copyFormOpen: false }); + }; + + handleSetDefaultClick = (e: React.SyntheticEvent) => { + e.preventDefault(); + setDefaultProfile(this.props.profile.key).then(this.props.updateProfiles); + }; + + handleDeleteClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ deleteFormOpen: true }); + }; + + handleProfileDelete = () => { + this.context.router.replace(getProfilesPath(this.props.organization)); + this.props.updateProfiles(); + }; + + closeDeleteForm = () => { + this.setState({ deleteFormOpen: false }); + }; + + render() { + const { profile, canAdmin } = this.props; + + // FIXME use org, name and lang + const backupUrl = + (window as any).baseUrl + + '/api/qualityprofiles/backup?profileKey=' + + encodeURIComponent(profile.key); + + const activateMoreUrl = getRulesUrl( + { + qprofile: profile.key, + activation: 'false' + }, + this.props.organization + ); + + return ( + + ); + } +} 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.js deleted file mode 100644 index f44f53c9e35..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js +++ /dev/null @@ -1,105 +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 Helmet from 'react-helmet'; -import ProfileNotFound from './ProfileNotFound'; -import ProfileHeader from '../details/ProfileHeader'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - canAdmin: boolean, - children: React.Element<*>, - location: { - pathname: string, - query: { key?: string, language: string, name: string } - }, - onRequestFail: Object => void, - organization: ?string, - profiles: Array, - router: { replace: ({}) => void }, - updateProfiles: () => Promise<*> -}; -*/ - -export default class ProfileContainer extends React.PureComponent { - /*:: props: Props; */ - - componentDidMount() { - const { location, profiles, router } = this.props; - if (location.query.key) { - // try to find a quality profile with the given key - // if managed to find one, redirect to a new version - // otherwise do nothing, `render` will show not found page - const profile = profiles.find(profile => profile.key === location.query.key); - if (profile) { - router.replace({ - pathname: location.pathname, - query: { language: profile.language, name: profile.name } - }); - } - } - } - - render() { - const { organization, profiles, location, ...other } = this.props; - const { key, language, name } = location.query; - - if (key) { - // if there is a `key` parameter, - // then if we managed to find a quality profile with this key - // then we will be redirected in `componentDidMount` - // otherwise show `ProfileNotFound` - const profile = profiles.find(profile => profile.key === location.query.key); - return profile ? null : ; - } - - const profile = profiles.find( - profile => profile.language === language && profile.name === name - ); - - if (!profile) { - return ; - } - - const child = React.cloneElement(this.props.children, { - onRequestFail: this.props.onRequestFail, - organization, - profile, - profiles, - ...other - }); - - return ( -
- - - {child} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx new file mode 100644 index 00000000000..ee6d302acdd --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx @@ -0,0 +1,100 @@ +/* + * 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 Helmet from 'react-helmet'; +import ProfileNotFound from './ProfileNotFound'; +import ProfileHeader from '../details/ProfileHeader'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + children: React.ReactElement; + location: { + pathname: string; + query: { key?: string; language: string; name: string }; + }; + onRequestFail: (reasong: any) => void; + organization: string | null; + profiles: IProfile[]; + router: { replace: ({}) => void }; + updateProfiles: () => Promise; +} + +export default class ProfileContainer extends React.PureComponent { + componentDidMount() { + const { location, profiles, router } = this.props; + if (location.query.key) { + // try to find a quality profile with the given key + // if managed to find one, redirect to a new version + // otherwise do nothing, `render` will show not found page + const profile = profiles.find(profile => profile.key === location.query.key); + if (profile) { + router.replace({ + pathname: location.pathname, + query: { language: profile.language, name: profile.name } + }); + } + } + } + + render() { + const { organization, profiles, location, ...other } = this.props; + const { key, language, name } = location.query; + + if (key) { + // if there is a `key` parameter, + // then if we managed to find a quality profile with this key + // then we will be redirected in `componentDidMount` + // otherwise show `ProfileNotFound` + const profile = profiles.find(profile => profile.key === location.query.key); + return profile ? null : ; + } + + const profile = profiles.find( + profile => profile.language === language && profile.name === name + ); + + if (!profile) { + return ; + } + + const child = React.cloneElement(this.props.children, { + onRequestFail: this.props.onRequestFail, + organization, + profile, + profiles, + ...other + }); + + return ( +
+ + + {child} +
+ ); + } +} 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.js deleted file mode 100644 index ae878a4ba6b..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js +++ /dev/null @@ -1,51 +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 { 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 ( - - {translate('never')} - - ); - } - - return ( - - {moment(date).fromNow()} - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx new file mode 100644 index 00000000000..947b15e419c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.tsx @@ -0,0 +1,36 @@ +/* + * 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 { translate } from '../../../helpers/l10n'; + +interface Props { + date?: string; +} + +export default function ProfileDate({ date }: Props) { + return date + ? + {moment(date).fromNow()} + + : + {translate('never')} + ; +} 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.js deleted file mode 100644 index 2ff0534c108..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js +++ /dev/null @@ -1,48 +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 { getProfilePath } from '../utils'; - -/*:: -type Props = { - children?: React.Element<*>, - language: string, - name: string, - organization: ?string -}; -*/ - -export default class ProfileLink extends React.PureComponent { - /*:: props: Props; */ - - render() { - const { name, language, organization, children, ...other } = this.props; - return ( - - {children} - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx new file mode 100644 index 00000000000..8b69532ad74 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.tsx @@ -0,0 +1,41 @@ +/* + * 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 { getProfilePath } from '../utils'; + +interface Props { + className?: string; + children?: React.ReactElement | string; + language: string; + name: string; + organization: string | null; +} + +export default function ProfileLink({ name, language, organization, children, ...other }: Props) { + return ( + + {children} + + ); +} 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.js deleted file mode 100644 index 7dce1cc0ce1..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js +++ /dev/null @@ -1,50 +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 { 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; */ - - render() { - return ( -
-
- - {translate('quality_profiles.page')} - -
- -
- {translate('quality_profiles.not_found')} -
-
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx new file mode 100644 index 00000000000..a6fd496502c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.tsx @@ -0,0 +1,43 @@ +/* + * 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 { IndexLink } from 'react-router'; +import { translate } from '../../../helpers/l10n'; +import { getProfilesPath } from '../utils'; + +interface Props { + organization: string | null; +} + +export default function ProfileNotFound(props: Props) { + return ( +
+
+ + {translate('quality_profiles.page')} + +
+ +
+ {translate('quality_profiles.not_found')} +
+
+ ); +} 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.js deleted file mode 100644 index 37d63394d21..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.js +++ /dev/null @@ -1,139 +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 Modal from 'react-modal'; -/*:: import type { Profile } from '../propTypes'; */ -import { renameProfile } from '../../../api/quality-profiles'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; - -/*:: -type Props = { - onClose: () => void, - onRename: string => void, - onRequestFail: Object => void, - profile: Profile -}; -*/ - -/*:: -type State = { - loading: boolean, - name: ?string -}; -*/ - -export default class RenameProfileForm extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { loading: false, name: null }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => { - this.setState({ name: event.currentTarget.value }); - }; - - handleFormSubmit = (event /*: Event */) => { - event.preventDefault(); - - const { name } = this.state; - - if (name != null) { - this.setState({ loading: true }); - renameProfile(this.props.profile.key, name).then( - () => this.props.onRename(name), - error => { - if (this.mounted) { - this.setState({ loading: false }); - } - this.props.onRequestFail(error); - } - ); - } - }; - - render() { - const { profile } = this.props; - const header = translateWithParameters( - 'quality_profiles.rename_x_title', - profile.name, - profile.languageName - ); - const submitDisabled = - this.state.loading || !this.state.name || this.state.name === profile.name; - - return ( - -
-
-

- {header} -

-
-
-
- - -
-
-
- {this.state.loading && } - - - {translate('cancel')} - -
- -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx new file mode 100644 index 00000000000..1d1491975ec --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx @@ -0,0 +1,133 @@ +/* + * 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 Modal from 'react-modal'; +import { renameProfile } from '../../../api/quality-profiles'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + onClose: () => void; + onRename: (name: string) => void; + onRequestFail: (reason: any) => void; + profile: IProfile; +} + +interface State { + loading: boolean; + name: string | null; +} + +export default class RenameProfileForm extends React.PureComponent { + mounted: boolean; + state: State = { loading: false, name: null }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + handleCancelClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + handleNameChange = (event: React.SyntheticEvent) => { + this.setState({ name: event.currentTarget.value }); + }; + + handleFormSubmit = (event: React.SyntheticEvent) => { + event.preventDefault(); + + const { name } = this.state; + + if (name != null) { + this.setState({ loading: true }); + renameProfile(this.props.profile.key, name).then( + () => this.props.onRename(name), + (error: any) => { + if (this.mounted) { + this.setState({ loading: false }); + } + this.props.onRequestFail(error); + } + ); + } + }; + + render() { + const { profile } = this.props; + const header = translateWithParameters( + 'quality_profiles.rename_x_title', + profile.name, + profile.languageName + ); + const submitDisabled = + this.state.loading || !this.state.name || this.state.name === profile.name; + + return ( + +
+
+

+ {header} +

+
+
+
+ + +
+
+
+ {this.state.loading && } + + + {translate('cancel')} + +
+ +
+ ); + } +} 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.js deleted file mode 100644 index 08aa98c6b32..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.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. - */ -import { shallow } from 'enzyme'; -import React from 'react'; -import Helmet from 'react-helmet'; -import ProfileContainer from '../ProfileContainer'; -import ProfileNotFound from '../ProfileNotFound'; -import ProfileHeader from '../../details/ProfileHeader'; -import { createFakeProfile } from '../../utils'; - -it('should render ProfileHeader', () => { - const targetProfile = createFakeProfile({ language: 'js', name: 'fake' }); - const profiles = [targetProfile, createFakeProfile({ language: 'js', name: 'another' })]; - const updateProfiles = jest.fn(); - const output = shallow( - -
- - ); - const header = output.find(ProfileHeader); - expect(header.length).toBe(1); - expect(header.prop('profile')).toBe(targetProfile); - expect(header.prop('canAdmin')).toBe(false); - expect(header.prop('updateProfiles')).toBe(updateProfiles); -}); - -it('should render ProfileNotFound', () => { - const profiles = [ - createFakeProfile({ language: 'js', name: 'fake' }), - createFakeProfile({ language: 'js', name: 'another' }) - ]; - const output = shallow( - true}> -
- - ); - expect(output.is(ProfileNotFound)).toBe(true); -}); - -it('should render Helmet', () => { - const profiles = [createFakeProfile({ language: 'js', name: 'First Profile' })]; - const updateProfiles = jest.fn(); - const output = shallow( - -
- - ); - const helmet = output.find(Helmet); - expect(helmet.length).toBe(1); - expect(helmet.prop('title')).toContain('First Profile'); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx new file mode 100644 index 00000000000..1c0efc638ab --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx @@ -0,0 +1,89 @@ +/* + * 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import Helmet from 'react-helmet'; +import ProfileContainer from '../ProfileContainer'; +import ProfileNotFound from '../ProfileNotFound'; +import ProfileHeader from '../../details/ProfileHeader'; +import { createFakeProfile } from '../../utils'; + +it('should render ProfileHeader', () => { + const targetProfile = createFakeProfile({ language: 'js', name: 'fake' }); + const profiles = [targetProfile, createFakeProfile({ language: 'js', name: 'another' })]; + const updateProfiles = jest.fn(); + const output = shallow( + +
+ + ); + const header = output.find(ProfileHeader); + expect(header.length).toBe(1); + expect(header.prop('profile')).toBe(targetProfile); + expect(header.prop('canAdmin')).toBe(false); + expect(header.prop('updateProfiles')).toBe(updateProfiles); +}); + +it('should render ProfileNotFound', () => { + const profiles = [ + createFakeProfile({ language: 'js', name: 'fake' }), + createFakeProfile({ language: 'js', name: 'another' }) + ]; + const output = shallow( + +
+ + ); + expect(output.is(ProfileNotFound)).toBe(true); +}); + +it('should render Helmet', () => { + const profiles = [createFakeProfile({ language: 'js', name: 'First Profile' })]; + const updateProfiles = jest.fn(); + const output = shallow( + +
+ + ); + const helmet = output.find(Helmet); + expect(helmet.length).toBe(1); + expect(helmet.prop('title')).toContain('First Profile'); +}); 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.js deleted file mode 100644 index f7d019e63d8..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.js +++ /dev/null @@ -1,150 +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 Modal from 'react-modal'; -import Select from 'react-select'; -import { sortBy } from 'lodash'; -import { changeProfileParent } from '../../../api/quality-profiles'; -import { translate } from '../../../helpers/l10n'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - onChange: () => void, - onClose: () => void, - onRequestFail: Object => void, - profile: Profile, - profiles: Array -}; -*/ - -/*:: -type State = { - loading: boolean, - selected: ?string -}; -*/ - -export default class ChangeParentForm extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { - loading: false, - selected: null - }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleSelectChange = (option /*: { value: string } */) => { - this.setState({ selected: option.value }); - }; - - handleFormSubmit = (event /*: Event */) => { - 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); - }); - } - }; - - render() { - const { profiles } = this.props; - - const options = [ - { label: translate('none'), value: '' }, - ...sortBy(profiles, 'name').map(profile => ({ - label: profile.isBuiltIn - ? `${profile.name} (${translate('quality_profiles.built_in')})` - : profile.name, - value: profile.key - })) - ]; - - const submitDisabled = - this.state.loading || - this.state.selected == null || - this.state.selected === this.props.profile.parentKey; - - return ( - -
-
-

- {translate('quality_profiles.change_parent')} -

-
-
-
- - +
+
+
+ {this.state.loading && } + + + {translate('cancel')} + +
+ +
+ ); + } +} 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.js deleted file mode 100644 index a3277635118..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.js +++ /dev/null @@ -1,105 +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 Modal from 'react-modal'; -import escapeHtml from 'escape-html'; -/*:: import type { Profile } from '../propTypes'; */ -import SelectList from '../../../components/SelectList'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = { - onClose: () => void, - organization: ?string, - profile: Profile -}; -*/ - -export default class ChangeProjectsForm extends React.PureComponent { - /*:: container: HTMLElement; */ - /*:: props: Props; */ - - handleCloseClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - renderSelectList = () => { - const { key } = this.props.profile; - - const searchUrl = - window.baseUrl + '/api/qualityprofiles/projects?key=' + encodeURIComponent(key); - - new SelectList({ - 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', - extra: { profileKey: key }, - selectParameter: 'projectUuid', - selectParameterValue: 'uuid', - labels: { - selected: translate('quality_gates.projects.with'), - deselected: translate('quality_gates.projects.without'), - all: translate('quality_gates.projects.all'), - noResults: translate('quality_gates.projects.noResults') - }, - tooltips: { - select: translate('quality_profiles.projects.select_hint'), - deselect: translate('quality_profiles.projects.deselect_hint') - } - }); - }; - - render() { - const header = translate('projects'); - - return ( - -
-

- {header} -

-
- -
-
(this.container = node)} /> -
- - - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx new file mode 100644 index 00000000000..19085883c03 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeProjectsForm.tsx @@ -0,0 +1,101 @@ +/* + * 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 Modal from 'react-modal'; +import * as escapeHtml from 'escape-html'; +import SelectList from '../../../components/SelectList'; +import { translate } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + onClose: () => void; + organization: string | null; + profile: IProfile; +} + +export default class ChangeProjectsForm extends React.PureComponent { + container: HTMLElement; + + handleCloseClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + renderSelectList = () => { + const { key } = this.props.profile; + + const searchUrl = + (window as any).baseUrl + '/api/qualityprofiles/projects?key=' + encodeURIComponent(key); + + new (SelectList as any)({ + searchUrl, + el: this.container, + width: '100%', + readOnly: false, + focusSearch: false, + 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', + labels: { + selected: translate('quality_gates.projects.with'), + deselected: translate('quality_gates.projects.without'), + all: translate('quality_gates.projects.all'), + noResults: translate('quality_gates.projects.noResults') + }, + tooltips: { + select: translate('quality_profiles.projects.select_hint'), + deselect: translate('quality_profiles.projects.deselect_hint') + } + }); + }; + + render() { + const header = translate('projects'); + + return ( + +
+

+ {header} +

+
+ +
+
(this.container = node as HTMLElement)} /> +
+ + + + ); + } +} 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.js deleted file mode 100644 index b157db49a68..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js +++ /dev/null @@ -1,59 +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 ProfileRules from './ProfileRules'; -import ProfileProjects from './ProfileProjects'; -import ProfileInheritance from './ProfileInheritance'; -import ProfileExporters from './ProfileExporters'; -/*:: import type { Profile, Exporter } from '../propTypes'; */ - -/*:: -type Props = { - canAdmin: boolean, - exporters: Array, - onRequestFail: Object => void, - organization: ?string, - profile: Profile, - profiles: Array, - updateProfiles: () => Promise<*> -}; -*/ - -export default class ProfileDetails extends React.PureComponent { - /*:: props: Props; */ - - render() { - return ( -
-
-
- - -
-
- - -
-
-
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx new file mode 100644 index 00000000000..a01130a889b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx @@ -0,0 +1,52 @@ +/* + * 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 ProfileRules from './ProfileRules'; +import ProfileProjects from './ProfileProjects'; +import ProfileInheritance from './ProfileInheritance'; +import ProfileExporters from './ProfileExporters'; +import { IExporter, IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + exporters: IExporter[]; + onRequestFail: (reasong: any) => void; + organization: string | null; + profile: IProfile; + profiles: IProfile[]; + updateProfiles: () => Promise; +} + +export default function ProfileDetails(props: Props) { + return ( +
+
+
+ + +
+
+ + +
+
+
+ ); +} 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.js deleted file mode 100644 index 04f3c58df29..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js +++ /dev/null @@ -1,79 +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 { stringify } from 'querystring'; -import React from 'react'; -import { translate } from '../../../helpers/l10n'; -/*:: import type { Profile, Exporter } from '../propTypes'; */ - -/*:: -type Props = { - exporters: Array, - organization: ?string, - profile: Profile -}; -*/ - -export default class ProfileExporters extends React.PureComponent { - /*:: props: Props; */ - - getExportUrl(exporter /*: Exporter */) { - const { organization, profile } = this.props; - - const path = '/api/qualityprofiles/export'; - const parameters /*: { [string]: string } */ = { - exporterKey: exporter.key, - language: profile.language, - name: profile.name - }; - if (organization) { - Object.assign(parameters, { organization }); - } - return window.baseUrl + path + '?' + stringify(parameters); - } - - render() { - const { exporters, profile } = this.props; - const exportersForLanguage = exporters.filter(e => e.languages.includes(profile.language)); - - if (exportersForLanguage.length === 0) { - return null; - } - - return ( -
-
-

- {translate('quality_profiles.exporters')} -

-
- -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx new file mode 100644 index 00000000000..71913fae114 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.tsx @@ -0,0 +1,74 @@ +/* + * 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 { stringify } from 'querystring'; +import * as React from 'react'; +import { translate } from '../../../helpers/l10n'; +import { IProfile, IExporter } from '../types'; + +interface Props { + exporters: IExporter[]; + organization: string | null; + profile: IProfile; +} + +export default class ProfileExporters extends React.PureComponent { + getExportUrl(exporter: IExporter) { + const { organization, profile } = this.props; + + const path = '/api/qualityprofiles/export'; + const parameters = { + exporterKey: exporter.key, + language: profile.language, + name: profile.name + }; + if (organization) { + Object.assign(parameters, { organization }); + } + return (window as any).baseUrl + path + '?' + stringify(parameters); + } + + render() { + const { exporters, profile } = this.props; + const exportersForLanguage = exporters.filter(e => e.languages.includes(profile.language)); + + if (exportersForLanguage.length === 0) { + return null; + } + + return ( +
+
+

+ {translate('quality_profiles.exporters')} +

+
+ +
+ ); + } +} 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.js deleted file mode 100644 index f5691c5ccea..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js +++ /dev/null @@ -1,159 +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, IndexLink } from 'react-router'; -import ProfileLink from '../components/ProfileLink'; -import ProfileActions from '../components/ProfileActions'; -import ProfileDate from '../components/ProfileDate'; -import BuiltInBadge from '../components/BuiltInBadge'; -import { translate } from '../../../helpers/l10n'; -import { - isStagnant, - getProfilesPath, - getProfilesForLanguagePath, - getProfileChangelogPath -} from '../utils'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - canAdmin: boolean, - onRequestFail: Object => void, - organization: ?string, - profile: Profile, - updateProfiles: () => Promise<*> -}; -*/ - -export default class ProfileHeader extends React.PureComponent { - /*:: props: Props; */ - - renderUpdateDate() { - const { profile } = this.props; - let inner = ( - - {translate('quality_profiles.updated_')} - - ); - if (isStagnant(profile)) { - inner = ( - - {inner} - - ); - } - return ( -
  • - {inner} -
  • - ); - } - - renderUsageDate() { - const { profile } = this.props; - let inner = ( - - {translate('quality_profiles.used_')} - - ); - if (!profile.lastUsed) { - inner = ( - - {inner} - - ); - } - - return ( -
  • - {inner} -
  • - ); - } - - render() { - const { organization, profile } = this.props; - - return ( -
    -
    - - {translate('quality_profiles.page')} - - {' / '} - - {profile.languageName} - -
    - -

    - - - {profile.name} - - - {profile.isBuiltIn && } -

    - -
    -
      - {this.renderUpdateDate()} - {this.renderUsageDate()} -
    • - - {translate('changelog')} - -
    • -
    • -
      - - -
      -
    • -
    -
    - - {profile.isBuiltIn && -
    - {translate('quality_profiles.built_in.description.1')} -
    - {translate('quality_profiles.built_in.description.2')} -
    } -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx new file mode 100644 index 00000000000..ba0598251d6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx @@ -0,0 +1,154 @@ +/* + * 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, IndexLink } from 'react-router'; +import ProfileLink from '../components/ProfileLink'; +import ProfileActions from '../components/ProfileActions'; +import ProfileDate from '../components/ProfileDate'; +import BuiltInBadge from '../components/BuiltInBadge'; +import { translate } from '../../../helpers/l10n'; +import { + isStagnant, + getProfilesPath, + getProfilesForLanguagePath, + getProfileChangelogPath +} from '../utils'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + onRequestFail: (reasong: any) => void; + profile: IProfile; + organization: string | null; + updateProfiles: () => Promise; +} + +export default class ProfileHeader extends React.PureComponent { + renderUpdateDate() { + const { profile } = this.props; + let inner = ( + + {translate('quality_profiles.updated_')} + + ); + if (isStagnant(profile)) { + inner = ( + + {inner} + + ); + } + return ( +
  • + {inner} +
  • + ); + } + + renderUsageDate() { + const { profile } = this.props; + let inner = ( + + {translate('quality_profiles.used_')} + + ); + if (!profile.lastUsed) { + inner = ( + + {inner} + + ); + } + + return ( +
  • + {inner} +
  • + ); + } + + render() { + const { organization, profile } = this.props; + + return ( +
    +
    + + {translate('quality_profiles.page')} + + {' / '} + + {profile.languageName} + +
    + +

    + + + {profile.name} + + + {profile.isBuiltIn && } +

    + +
    +
      + {this.renderUpdateDate()} + {this.renderUsageDate()} +
    • + + {translate('changelog')} + +
    • +
    • +
      + + +
      +
    • +
    +
    + + {profile.isBuiltIn && +
    + {translate('quality_profiles.built_in.description.1')} +
    + {translate('quality_profiles.built_in.description.2')} +
    } +
    + ); + } +} 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.js deleted file mode 100644 index 9669bd0aa11..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js +++ /dev/null @@ -1,191 +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 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, - updateProfiles: () => Promise<*> -}; -*/ - -/*:: -type ProfileInheritanceDetails = { - activeRuleCount: number, - isBuiltIn: boolean, - key: string, - language: string, - name: string, - overridingRuleCount?: number -}; -*/ - -/*:: -type State = { - ancestors?: Array, - children?: Array, - formOpen: boolean, - loading: boolean, - profile?: ProfileInheritanceDetails -}; -*/ - -export default class ProfileInheritance extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { - formOpen: false, - loading: true - }; - - componentDidMount() { - this.mounted = true; - this.loadData(); - } - - componentDidUpdate(prevProps /*: Props */) { - if (prevProps.profile !== this.props.profile) { - this.loadData(); - } - } - - componentWillUnmount() { - this.mounted = false; - } - - loadData() { - getProfileInheritance(this.props.profile.key).then(r => { - if (this.mounted) { - const { ancestors, children } = r; - this.setState({ - children, - ancestors: ancestors.reverse(), - profile: r.profile, - loading: false - }); - } - }); - } - - handleChangeParentClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ formOpen: true }); - }; - - closeForm = () => { - this.setState({ formOpen: false }); - }; - - handleParentChange = () => { - this.props.updateProfiles(); - this.closeForm(); - }; - - render() { - const { profile, profiles } = this.props; - const { ancestors } = this.state; - - const highlightCurrent = - !this.state.loading && - ancestors != null && - this.state.children != null && - (ancestors.length > 0 || this.state.children.length > 0); - - const currentClassName = classNames('js-inheritance-current', { - selected: highlightCurrent - }); - - const extendsBuiltIn = ancestors != null && ancestors.some(profile => profile.isBuiltIn); - - return ( -
    -
    -

    - {translate('quality_profiles.profile_inheritance')} -

    - {this.props.canAdmin && - !this.props.profile.isBuiltIn && - } -
    - - {!this.state.loading && - - - {ancestors != null && - ancestors.map((ancestor, index) => - - )} - - - - {this.state.children != null && - this.state.children.map(child => - - )} - -
    } - - {this.state.formOpen && - p !== profile && p.language === profile.language)} - />} -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx new file mode 100644 index 00000000000..a7c6173deec --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx @@ -0,0 +1,185 @@ +/* + * 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 classNames from 'classnames'; +import ProfileInheritanceBox from './ProfileInheritanceBox'; +import ChangeParentForm from './ChangeParentForm'; +import { translate } from '../../../helpers/l10n'; +import { getProfileInheritance } from '../../../api/quality-profiles'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + onRequestFail: (reason: any) => void; + organization: string | null; + profile: IProfile; + profiles: IProfile[]; + updateProfiles: () => Promise; +} + +interface ProfileInheritanceDetails { + activeRuleCount: number; + isBuiltIn: boolean; + key: string; + language: string; + name: string; + overridingRuleCount?: number; +} + +interface State { + ancestors?: Array; + children?: Array; + formOpen: boolean; + loading: boolean; + profile?: ProfileInheritanceDetails; +} + +export default class ProfileInheritance extends React.PureComponent { + mounted: boolean; + + state: State = { + formOpen: false, + loading: true + }; + + componentDidMount() { + this.mounted = true; + this.loadData(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.profile !== this.props.profile) { + this.loadData(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + loadData() { + getProfileInheritance(this.props.profile.key).then((r: any) => { + if (this.mounted) { + const { ancestors, children } = r; + this.setState({ + children, + ancestors: ancestors.reverse(), + profile: r.profile, + loading: false + }); + } + }); + } + + handleChangeParentClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ formOpen: true }); + }; + + closeForm = () => { + this.setState({ formOpen: false }); + }; + + handleParentChange = () => { + this.props.updateProfiles(); + this.closeForm(); + }; + + render() { + const { profile, profiles } = this.props; + const { ancestors } = this.state; + + const highlightCurrent = + !this.state.loading && + ancestors != null && + this.state.children != null && + (ancestors.length > 0 || this.state.children.length > 0); + + const currentClassName = classNames('js-inheritance-current', { + selected: highlightCurrent + }); + + const extendsBuiltIn = ancestors != null && ancestors.some(profile => profile.isBuiltIn); + + return ( +
    +
    +

    + {translate('quality_profiles.profile_inheritance')} +

    + {this.props.canAdmin && + !this.props.profile.isBuiltIn && + } +
    + + {!this.state.loading && + + + {ancestors != null && + ancestors.map((ancestor, index) => + + )} + + {this.state.profile != null && + } + + {this.state.children != null && + this.state.children.map(child => + + )} + +
    } + + {this.state.formOpen && + p !== profile && p.language === profile.language)} + />} +
    + ); + } +} 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 ( - - -
    - {this.props.displayLink - ? - {profile.name} - - : profile.name} - {profile.isBuiltIn && } - {extendsBuiltIn && - - - } -
    - - - - {translateWithParameters('quality_profile.x_active_rules', profile.activeRuleCount)} - - - - {profile.overridingRuleCount != null && -

    - {translateWithParameters( - 'quality_profiles.x_overridden_rules', - profile.overridingRuleCount - )} -

    } - - - ); - } -} 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 ( + + +
    + {displayLink + ? + {profile.name} + + : profile.name} + {profile.isBuiltIn && } + {extendsBuiltIn && + + + } +
    + + + + {translateWithParameters('quality_profile.x_active_rules', profile.activeRuleCount)} + + + + {profile.overridingRuleCount != null && +

    + {translateWithParameters( + 'quality_profiles.x_overridden_rules', + profile.overridingRuleCount + )} +

    } + + + ); +} 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.js deleted file mode 100644 index 984b7995b0f..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js +++ /dev/null @@ -1,167 +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 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 */ = { - formOpen: false, - loading: true, - projects: null - }; - - componentDidMount() { - this.mounted = true; - this.loadProjects(); - } - - componentDidUpdate(prevProps /*: Props */) { - if (prevProps.profile !== this.props.profile) { - this.loadProjects(); - } - } - - componentWillUnmount() { - this.mounted = false; - } - - loadProjects() { - if (this.props.profile.isDefault) { - return; - } - - const data = { key: this.props.profile.key }; - getProfileProjects(data).then(r => { - if (this.mounted) { - this.setState({ - projects: r.results, - more: r.more, - loading: false - }); - } - }); - } - - handleChangeClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ formOpen: true }); - }; - - closeForm = () => { - this.setState({ formOpen: false }); - this.props.updateProfiles(); - }; - - renderDefault() { - return ( -
    - - {translate('default')} - - {translate('quality_profiles.projects_for_default')} -
    - ); - } - - renderProjects() { - const { projects } = this.state; - - if (projects == null) { - return null; - } - - if (projects.length === 0) { - return ( -
    - {translate('quality_profiles.no_projects_associated_to_profile')} -
    - ); - } - - return ( -
      - {projects.map(project => -
    • - - {project.name} - -
    • - )} -
    - ); - } - - render() { - return ( -
    -
    -

    - {translate('projects')} -

    - - {this.props.canAdmin && - !this.props.profile.isDefault && -
    - -
    } -
    - - {this.props.profile.isDefault ? this.renderDefault() : this.renderProjects()} - - {this.state.formOpen && - } -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx new file mode 100644 index 00000000000..92d30c277ba --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.tsx @@ -0,0 +1,162 @@ +/* + * 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 ChangeProjectsForm from './ChangeProjectsForm'; +import QualifierIcon from '../../../components/shared/QualifierIcon'; +import { getProfileProjects } from '../../../api/quality-profiles'; +import { translate } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + organization: string | null; + profile: IProfile; + updateProfiles: () => Promise; +} + +interface State { + formOpen: boolean; + loading: boolean; + more?: boolean; + projects: Array<{ key: string; name: string; uuid: string }> | null; +} + +export default class ProfileProjects extends React.PureComponent { + mounted: boolean; + + state: State = { + formOpen: false, + loading: true, + projects: null + }; + + componentDidMount() { + this.mounted = true; + this.loadProjects(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.profile !== this.props.profile) { + this.loadProjects(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + loadProjects() { + if (this.props.profile.isDefault) { + return; + } + + const data = { key: this.props.profile.key }; + getProfileProjects(data).then((r: any) => { + if (this.mounted) { + this.setState({ + projects: r.results, + more: r.more, + loading: false + }); + } + }); + } + + handleChangeClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ formOpen: true }); + }; + + closeForm = () => { + this.setState({ formOpen: false }); + this.props.updateProfiles(); + }; + + renderDefault() { + return ( +
    + + {translate('default')} + + {translate('quality_profiles.projects_for_default')} +
    + ); + } + + renderProjects() { + const { projects } = this.state; + + if (projects == null) { + return null; + } + + if (projects.length === 0) { + return ( +
    + {translate('quality_profiles.no_projects_associated_to_profile')} +
    + ); + } + + return ( +
      + {projects.map(project => +
    • + + {project.name} + +
    • + )} +
    + ); + } + + render() { + return ( +
    +
    +

    + {translate('projects')} +

    + + {this.props.canAdmin && + !this.props.profile.isDefault && +
    + +
    } +
    + + {this.props.profile.isDefault ? this.renderDefault() : this.renderProjects()} + + {this.state.formOpen && + } +
    + ); + } +} 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.js deleted file mode 100644 index ceb3fbed7c1..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js +++ /dev/null @@ -1,216 +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 { keyBy } from 'lodash'; -import ProfileRulesRowOfType from './ProfileRulesRowOfType'; -import ProfileRulesRowTotal from './ProfileRulesRowTotal'; -import ProfileRulesDeprecatedWarning from './ProfileRulesDeprecatedWarning'; -import ProfileRulesSonarWayComparison from './ProfileRulesSonarWayComparison'; -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'; */ - -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 */ = { - activatedTotal: null, - activatedByType: keyBy(TYPES.map(t => ({ val: t, count: null })), 'val'), - allByType: keyBy(TYPES.map(t => ({ val: t, count: null })), 'val'), - compareToSonarWay: null, - loading: true, - total: null - }; - - componentDidMount() { - this.mounted = true; - this.loadRules(); - } - - componentDidUpdate(prevProps /*: Props */) { - if (prevProps.profile !== this.props.profile) { - this.loadRules(); - } - } - - componentWillUnmount() { - this.mounted = false; - } - - loadProfile() { - if (this.props.profile.isBuiltIn) { - return Promise.resolve(null); - } - return getQualityProfiles({ - compareToSonarWay: true, - profile: this.props.profile.key - }); - } - - loadAllRules() { - return searchRules({ - languages: this.props.profile.language, - ps: 1, - facets: 'types' - }); - } - - loadActivatedRules() { - return searchRules({ - qprofile: this.props.profile.key, - activation: 'true', - ps: 1, - facets: 'types' - }); - } - - loadRules() { - this.setState({ loading: true }); - Promise.all([ - this.loadAllRules(), - this.loadActivatedRules(), - this.loadProfile() - ]).then(responses => { - if (this.mounted) { - const [allRules, activatedRules, showProfile] = responses; - this.setState({ - activatedTotal: activatedRules.total, - allByType: keyBy(takeFacet(allRules, 'types'), 'val'), - activatedByType: keyBy(takeFacet(activatedRules, 'types'), 'val'), - compareToSonarWay: showProfile && showProfile.compareToSonarWay, - loading: false, - total: allRules.total - }); - } - }); - } - - getRulesCountForType(type /*: string */) /*: ?number */ { - return this.state.activatedByType && this.state.activatedByType[type] - ? this.state.activatedByType[type].count - : null; - } - - getRulesTotalForType(type /*: string */) /*: ?number */ { - return this.state.allByType && this.state.allByType[type] - ? this.state.allByType[type].count - : null; - } - - render() { - const { organization, profile } = this.props; - const { compareToSonarWay } = this.state; - const activateMoreUrl = getRulesUrl( - { qprofile: profile.key, activation: 'false' }, - organization - ); - - return ( -
    -
    - - - - - - - - - - - {TYPES.map(type => - - )} - -
    -

    - {translate('rules')} -

    -
    - {translate('active')} - - {translate('inactive')} -
    - - {this.props.canAdmin && - !profile.isBuiltIn && -
    - - {translate('quality_profiles.activate_more')} - -
    } -
    - {profile.activeDeprecatedRuleCount > 0 && - } - {compareToSonarWay != null && - compareToSonarWay.missingRuleCount > 0 && - } -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx new file mode 100644 index 00000000000..2fc1879190c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.tsx @@ -0,0 +1,216 @@ +/* + * 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 { keyBy } from 'lodash'; +import ProfileRulesRowOfType from './ProfileRulesRowOfType'; +import ProfileRulesRowTotal from './ProfileRulesRowTotal'; +import ProfileRulesDeprecatedWarning from './ProfileRulesDeprecatedWarning'; +import ProfileRulesSonarWayComparison from './ProfileRulesSonarWayComparison'; +import { searchRules, takeFacet } from '../../../api/rules'; +import { getQualityProfiles } from '../../../api/quality-profiles'; +import { getRulesUrl } from '../../../helpers/urls'; +import { translate } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +const TYPES = ['BUG', 'VULNERABILITY', 'CODE_SMELL']; + +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 { + 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'), + compareToSonarWay: null, + loading: true, + total: null + }; + + componentDidMount() { + this.mounted = true; + this.loadRules(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.profile !== this.props.profile) { + this.loadRules(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + loadProfile() { + if (this.props.profile.isBuiltIn) { + return Promise.resolve(null); + } + return getQualityProfiles({ + compareToSonarWay: true, + profile: this.props.profile.key + }); + } + + loadAllRules() { + return searchRules({ + languages: this.props.profile.language, + ps: 1, + facets: 'types' + }); + } + + loadActivatedRules() { + return searchRules({ + qprofile: this.props.profile.key, + activation: 'true', + ps: 1, + facets: 'types' + }); + } + + loadRules() { + this.setState({ loading: true }); + Promise.all([ + this.loadAllRules(), + this.loadActivatedRules(), + this.loadProfile() + ]).then(responses => { + if (this.mounted) { + const [allRules, activatedRules, showProfile] = responses; + this.setState({ + activatedTotal: activatedRules.total, + allByType: keyBy(takeFacet(allRules, 'types'), 'val'), + activatedByType: keyBy(takeFacet(activatedRules, 'types'), 'val'), + compareToSonarWay: showProfile && showProfile.compareToSonarWay, + loading: false, + total: allRules.total + }); + } + }); + } + + getRulesCountForType(type: string) { + return this.state.activatedByType && this.state.activatedByType[type] + ? this.state.activatedByType[type].count + : null; + } + + getRulesTotalForType(type: string) { + return this.state.allByType && this.state.allByType[type] + ? this.state.allByType[type].count + : null; + } + + render() { + const { organization, profile } = this.props; + const { compareToSonarWay } = this.state; + const activateMoreUrl = getRulesUrl( + { qprofile: profile.key, activation: 'false' }, + organization + ); + + return ( +
    +
    + + + + + + + + + + + {TYPES.map(type => + + )} + +
    +

    + {translate('rules')} +

    +
    + {translate('active')} + + {translate('inactive')} +
    + + {this.props.canAdmin && + !profile.isBuiltIn && +
    + + {translate('quality_profiles.activate_more')} + +
    } +
    + {profile.activeDeprecatedRuleCount > 0 && + } + {compareToSonarWay != null && + compareToSonarWay.missingRuleCount > 0 && + } +
    + ); + } +} 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.js deleted file mode 100644 index a74e0829787..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.js +++ /dev/null @@ -1,46 +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 Tooltip from '../../../components/controls/Tooltip'; -import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = { activeDeprecatedRules: number, organization: ?string, profile: string }; -*/ - -export default function ProfileRulesDeprecatedWarning(props /*: Props */) { - const url = getDeprecatedActiveRulesUrl({ qprofile: props.profile }, props.organization); - return ( -
    - - {translate('quality_profiles.deprecated_rules')} - - - - - - {props.activeDeprecatedRules} - -
    - ); -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx new file mode 100644 index 00000000000..3e69b0c86be --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx @@ -0,0 +1,47 @@ +/* + * 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 Tooltip from '../../../components/controls/Tooltip'; +import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + activeDeprecatedRules: number; + organization: string | null; + profile: string; +} + +export default function ProfileRulesDeprecatedWarning(props: Props) { + const url = getDeprecatedActiveRulesUrl({ qprofile: props.profile }, props.organization); + return ( +
    + + {translate('quality_profiles.deprecated_rules')} + + + + + + {props.activeDeprecatedRules} + +
    + ); +} 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.js deleted file mode 100644 index a899b495348..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.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 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 -}; -*/ - -export default function ProfileRulesRowOfType(props /*: Props */) { - const activeRulesUrl = getRulesUrl( - { qprofile: props.qprofile, activation: 'true', types: props.type }, - props.organization - ); - const inactiveRulesUrl = getRulesUrl( - { qprofile: props.qprofile, activation: 'false', types: props.type }, - props.organization - ); - let inactiveCount = null; - if (props.count != null && props.total != null) { - inactiveCount = props.total - props.count; - } - - return ( - - - - - {translate('issue.type', props.type, 'plural')} - - - - {props.count != null && - - {formatMeasure(props.count, 'SHORT_INT')} - } - - - {inactiveCount != null && - (inactiveCount > 0 - ? - {formatMeasure(inactiveCount, 'SHORT_INT')} - - : 0)} - - - ); -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.tsx new file mode 100644 index 00000000000..b13a5ed9797 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowOfType.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 { 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'; + +interface Props { + count: number | null; + organization: string | null; + qprofile: string; + total: number | null; + type: string; +} + +export default function ProfileRulesRowOfType(props: Props) { + const activeRulesUrl = getRulesUrl( + { qprofile: props.qprofile, activation: 'true', types: props.type }, + props.organization + ); + const inactiveRulesUrl = getRulesUrl( + { qprofile: props.qprofile, activation: 'false', types: props.type }, + props.organization + ); + let inactiveCount = null; + if (props.count != null && props.total != null) { + inactiveCount = props.total - props.count; + } + + return ( + + + + + {translate('issue.type', props.type, 'plural')} + + + + {props.count != null && + + {formatMeasure(props.count, 'SHORT_INT', null)} + } + + + {inactiveCount != null && + (inactiveCount > 0 + ? + {formatMeasure(inactiveCount, 'SHORT_INT', null)} + + : 0)} + + + ); +} 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.js deleted file mode 100644 index 1cb16d7623c..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.js +++ /dev/null @@ -1,77 +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 { formatMeasure } from '../../../helpers/measures'; -import { getRulesUrl } from '../../../helpers/urls'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = { - count: ?number, - organization: ?string, - qprofile: string, - total: ?number -}; -*/ - -export default function ProfileRulesRowTotal(props /*: Props */) { - const activeRulesUrl = getRulesUrl( - { qprofile: props.qprofile, activation: 'true' }, - props.organization - ); - const inactiveRulesUrl = getRulesUrl( - { qprofile: props.qprofile, activation: 'false' }, - props.organization - ); - let inactiveCount = null; - if (props.count != null && props.total != null) { - inactiveCount = props.total - props.count; - } - - return ( - - - - {translate('total')} - - - - {props.count != null && - - - {formatMeasure(props.count, 'SHORT_INT')} - - } - - - {inactiveCount != null && - (inactiveCount > 0 - ? - - {formatMeasure(inactiveCount, 'SHORT_INT')} - - - : 0)} - - - ); -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx new file mode 100644 index 00000000000..4f97d20776b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRowTotal.tsx @@ -0,0 +1,74 @@ +/* + * 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 { formatMeasure } from '../../../helpers/measures'; +import { getRulesUrl } from '../../../helpers/urls'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + count: number | null; + organization: string | null; + qprofile: string; + total: number | null; +} + +export default function ProfileRulesRowTotal(props: Props) { + const activeRulesUrl = getRulesUrl( + { qprofile: props.qprofile, activation: 'true' }, + props.organization + ); + const inactiveRulesUrl = getRulesUrl( + { qprofile: props.qprofile, activation: 'false' }, + props.organization + ); + let inactiveCount = null; + if (props.count != null && props.total != null) { + inactiveCount = props.total - props.count; + } + + return ( + + + + {translate('total')} + + + + {props.count != null && + + + {formatMeasure(props.count, 'SHORT_INT', null)} + + } + + + {inactiveCount != null && + (inactiveCount > 0 + ? + + {formatMeasure(inactiveCount, 'SHORT_INT', null)} + + + : 0)} + + + ); +} 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.js deleted file mode 100644 index 1e4a4c27c46..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.js +++ /dev/null @@ -1,61 +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 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 -}; -*/ - -export default function ProfileRulesSonarWayComparison(props /*: Props */) { - const url = getRulesUrl( - { - qprofile: props.profile, - activation: false, - compareToProfile: props.sonarway, - languages: props.language - }, - props.organization - ); - - return ( -
    - - {translate('quality_profiles.sonarway_missing_rules')} - - - - - - {props.sonarWayMissingRules} - -
    - ); -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx new file mode 100644 index 00000000000..cc7470d93ab --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx @@ -0,0 +1,58 @@ +/* + * 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 Tooltip from '../../../components/controls/Tooltip'; +import { getRulesUrl } from '../../../helpers/urls'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + language: string; + organization: string | null; + profile: string; + sonarway: string; + sonarWayMissingRules: number; +} + +export default function ProfileRulesSonarWayComparison(props: Props) { + const url = getRulesUrl( + { + qprofile: props.profile, + activation: false, + compareToProfile: props.sonarway, + languages: props.language + }, + props.organization + ); + + return ( +
    + + {translate('quality_profiles.sonarway_missing_rules')} + + + + + + {props.sonarWayMissingRules} + +
    + ); +} 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.js deleted file mode 100644 index cd62b6a21d6..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.js +++ /dev/null @@ -1,159 +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 { shallow } from 'enzyme'; -import ProfileRules from '../ProfileRules'; -import { doAsync } from '../../../../helpers/testUtils'; -import * as apiRules from '../../../../api/rules'; -import * as apiQP from '../../../../api/quality-profiles'; - -const PROFILE = { - key: 'foo', - name: 'Foo', - isBuiltIn: false, - isDefault: false, - isInherited: false, - language: 'java', - languageName: 'Java', - activeRuleCount: 68, - activeDeprecatedRuleCount: 0, - rulesUpdatedAt: '2017-06-28T12:58:44+0000', - depth: 0, - childrenCount: 0 -}; - -const apiResponseAll = { - total: 243, - facets: [ - { - property: 'types', - values: [ - { val: 'CODE_SMELL', count: 168 }, - { val: 'BUG', count: 68 }, - { val: 'VULNERABILITY', count: 7 } - ] - } - ] -}; - -const apiResponseActive = { - total: 68, - facets: [ - { - property: 'types', - values: [ - { val: 'BUG', count: 68 }, - { val: 'CODE_SMELL', count: 0 }, - { val: 'VULNERABILITY', count: 0 } - ] - } - ] -}; - -// Mock api some api functions -// eslint-disable-next-line -apiRules.searchRules = data => - Promise.resolve(data.activation === 'true' ? apiResponseActive : apiResponseAll); -// eslint-disable-next-line -apiQP.getQualityProfiles = () => - Promise.resolve({ - compareToSonarWay: { - profile: 'sonarway', - profileName: 'Sonar way', - missingRuleCount: 4 - } - }); - -it('should render the quality profiles rules with sonarway comparison', () => { - const wrapper = shallow(); - wrapper.instance().mounted = true; - wrapper.instance().loadRules(); - return doAsync(() => { - wrapper.update(); - expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(1); - expect(wrapper).toMatchSnapshot(); - }); -}); - -it('should show a button to activate more rules for admins', () => { - const wrapper = shallow(); - expect(wrapper.find('.js-activate-rules')).toMatchSnapshot(); -}); - -it('should show a deprecated rules warning message', () => { - const wrapper = shallow( - - ); - expect(wrapper.find('ProfileRulesDeprecatedWarning')).toMatchSnapshot(); -}); - -it('should not show a button to activate more rules on built in profiles', () => { - const wrapper = shallow( - - ); - expect(wrapper.find('.js-activate-rules')).toHaveLength(0); -}); - -it('should not show a button to activate more rules on built in profiles', () => { - const wrapper = shallow( - - ); - expect(wrapper.find('.js-activate-rules')).toHaveLength(0); -}); - -it('should not show sonarway comparison for built in profiles', () => { - // eslint-disable-next-line - apiQP.getQualityProfiles = jest.fn(() => Promise.resolve()); - const wrapper = shallow( - - ); - wrapper.instance().mounted = true; - wrapper.instance().loadRules(); - return doAsync(() => { - wrapper.update(); - expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(0); - expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(0); - }); -}); - -it('should not show sonarway comparison if there is no missing rules', () => { - // eslint-disable-next-line - apiQP.getQualityProfiles = jest.fn(() => - Promise.resolve({ - compareToSonarWay: { - profile: 'sonarway', - profileName: 'Sonar way', - missingRuleCount: 0 - } - }) - ); - const wrapper = shallow(); - wrapper.instance().mounted = true; - wrapper.instance().loadRules(); - return doAsync(() => { - wrapper.update(); - expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(1); - expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(0); - }); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx new file mode 100644 index 00000000000..91e5ed96cfc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRules-test.tsx @@ -0,0 +1,158 @@ +/* + * 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 { shallow } from 'enzyme'; +import ProfileRules from '../ProfileRules'; +import { doAsync } from '../../../../helpers/testUtils'; +import * as apiRules from '../../../../api/rules'; +import * as apiQP from '../../../../api/quality-profiles'; + +const PROFILE = { + key: 'foo', + name: 'Foo', + isBuiltIn: false, + isDefault: false, + isInherited: false, + language: 'java', + languageName: 'Java', + activeRuleCount: 68, + activeDeprecatedRuleCount: 0, + rulesUpdatedAt: '2017-06-28T12:58:44+0000', + depth: 0, + childrenCount: 0 +}; + +const apiResponseAll = { + total: 243, + facets: [ + { + property: 'types', + values: [ + { val: 'CODE_SMELL', count: 168 }, + { val: 'BUG', count: 68 }, + { val: 'VULNERABILITY', count: 7 } + ] + } + ] +}; + +const apiResponseActive = { + total: 68, + facets: [ + { + property: 'types', + values: [ + { val: 'BUG', count: 68 }, + { val: 'CODE_SMELL', count: 0 }, + { val: 'VULNERABILITY', count: 0 } + ] + } + ] +}; + +// Mock api some api functions +(apiRules as any).searchRules = (data: any) => + Promise.resolve(data.activation === 'true' ? apiResponseActive : apiResponseAll); +(apiQP as any).getQualityProfiles = () => + Promise.resolve({ + compareToSonarWay: { + profile: 'sonarway', + profileName: 'Sonar way', + missingRuleCount: 4 + } + }); + +it('should render the quality profiles rules with sonarway comparison', () => { + const wrapper = shallow(); + const instance = wrapper.instance() as any; + instance.mounted = true; + instance.loadRules(); + return doAsync(() => { + wrapper.update(); + expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(1); + expect(wrapper).toMatchSnapshot(); + }); +}); + +it('should show a button to activate more rules for admins', () => { + const wrapper = shallow(); + expect(wrapper.find('.js-activate-rules')).toMatchSnapshot(); +}); + +it('should show a deprecated rules warning message', () => { + const wrapper = shallow( + + ); + expect(wrapper.find('ProfileRulesDeprecatedWarning')).toMatchSnapshot(); +}); + +it('should not show a button to activate more rules on built in profiles', () => { + const wrapper = shallow( + + ); + expect(wrapper.find('.js-activate-rules')).toHaveLength(0); +}); + +it('should not show a button to activate more rules on built in profiles', () => { + const wrapper = shallow( + + ); + expect(wrapper.find('.js-activate-rules')).toHaveLength(0); +}); + +it('should not show sonarway comparison for built in profiles', () => { + (apiQP as any).getQualityProfiles = jest.fn(() => Promise.resolve()); + const wrapper = shallow( + + ); + const instance = wrapper.instance() as any; + instance.mounted = true; + instance.loadRules(); + return doAsync(() => { + wrapper.update(); + expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(0); + expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(0); + }); +}); + +it('should not show sonarway comparison if there is no missing rules', () => { + (apiQP as any).getQualityProfiles = jest.fn(() => + Promise.resolve({ + compareToSonarWay: { + profile: 'sonarway', + profileName: 'Sonar way', + missingRuleCount: 0 + } + }) + ); + const wrapper = shallow(); + const instance = wrapper.instance() as any; + instance.mounted = true; + instance.loadRules(); + return doAsync(() => { + wrapper.update(); + expect(apiQP.getQualityProfiles).toHaveBeenCalledTimes(1); + expect(wrapper.find('ProfileRulesSonarWayComparison')).toHaveLength(0); + }); +}); 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.js deleted file mode 100644 index 9a3387280e9..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.js +++ /dev/null @@ -1,31 +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 { shallow } from 'enzyme'; -import ProfileRulesDeprecatedWarning from '../ProfileRulesDeprecatedWarning'; - -it('should render correctly', () => { - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx new file mode 100644 index 00000000000..c306d6856c3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesDeprecatedWarning-test.tsx @@ -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 * as React from 'react'; +import { shallow } from 'enzyme'; +import ProfileRulesDeprecatedWarning from '../ProfileRulesDeprecatedWarning'; + +it('should render correctly', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); 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.js deleted file mode 100644 index dea445e01bf..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.js +++ /dev/null @@ -1,70 +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 { shallow } from 'enzyme'; -import ProfileRulesRowOfType from '../ProfileRulesRowOfType'; - -it('should render correctly', () => { - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); - -it('should render correctly if there is 0 rules', () => { - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); - -it('should render correctly if there is missing data', () => { - expect( - shallow( - - ) - ).toMatchSnapshot(); - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx new file mode 100644 index 00000000000..b8a3bc56505 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowOfType-test.tsx @@ -0,0 +1,69 @@ +/* + * 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 { shallow } from 'enzyme'; +import ProfileRulesRowOfType from '../ProfileRulesRowOfType'; + +it('should render correctly', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); + +it('should render correctly if there is 0 rules', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); + +it('should render correctly if there is missing data', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); 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.js deleted file mode 100644 index 20f2d697d5f..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.js +++ /dev/null @@ -1,44 +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 { shallow } from 'enzyme'; -import ProfileRulesRowTotal from '../ProfileRulesRowTotal'; - -it('should render correctly', () => { - expect( - shallow() - ).toMatchSnapshot(); -}); - -it('should render correctly if there is 0 rules', () => { - expect( - shallow() - ).toMatchSnapshot(); -}); - -it('should render correctly if there is missing data', () => { - expect( - shallow() - ).toMatchSnapshot(); - expect( - shallow() - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx new file mode 100644 index 00000000000..3428f58ea6b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesRowTotal-test.tsx @@ -0,0 +1,43 @@ +/* + * 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 { shallow } from 'enzyme'; +import ProfileRulesRowTotal from '../ProfileRulesRowTotal'; + +it('should render correctly', () => { + expect( + shallow() + ).toMatchSnapshot(); +}); + +it('should render correctly if there is 0 rules', () => { + expect( + shallow() + ).toMatchSnapshot(); +}); + +it('should render correctly if there is missing data', () => { + expect( + shallow() + ).toMatchSnapshot(); + expect( + shallow() + ).toMatchSnapshot(); +}); 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.js deleted file mode 100644 index ef992d630ba..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.js +++ /dev/null @@ -1,37 +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 { shallow } from 'enzyme'; -import ProfileRulesSonarWayComparison from '../ProfileRulesSonarWayComparison'; - -it('should render correctly', () => { - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx new file mode 100644 index 00000000000..50914b7a094 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileRulesSonarWayComparison-test.tsx @@ -0,0 +1,36 @@ +/* + * 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 { shallow } from 'enzyme'; +import ProfileRulesSonarWayComparison from '../ProfileRulesSonarWayComparison'; + +it('should render correctly', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); 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.js.snap deleted file mode 100644 index 22be4264e2a..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.js.snap +++ /dev/null @@ -1,86 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render the quality profiles rules with sonarway comparison 1`] = ` -
    -
    - - - - - - - - - - - - - - -
    -

    - rules -

    -
    - active - - inactive -
    -
    - -
    -`; - -exports[`should show a button to activate more rules for admins 1`] = ` - - quality_profiles.activate_more - -`; - -exports[`should show a deprecated rules warning message 1`] = ` - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap new file mode 100644 index 00000000000..22be4264e2a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRules-test.tsx.snap @@ -0,0 +1,86 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render the quality profiles rules with sonarway comparison 1`] = ` +
    +
    + + + + + + + + + + + + + + +
    +

    + rules +

    +
    + active + + inactive +
    +
    + +
    +`; + +exports[`should show a button to activate more rules for admins 1`] = ` + + quality_profiles.activate_more + +`; + +exports[`should show a deprecated rules warning message 1`] = ` + +`; 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.js.snap deleted file mode 100644 index 54fa91cc49d..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.js.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -
    - - quality_profiles.deprecated_rules - - - - - - 18 - -
    -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap new file mode 100644 index 00000000000..54fa91cc49d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +
    + + quality_profiles.deprecated_rules + + + + + + 18 + +
    +`; 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.js.snap deleted file mode 100644 index 62866095c17..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.js.snap +++ /dev/null @@ -1,120 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - - - - issue.type.BUG.plural - - - - - 3 - - - - - 7 - - - -`; - -exports[`should render correctly if there is 0 rules 1`] = ` - - - - - issue.type.VULNERABILITY.plural - - - - - 0 - - - - - 0 - - - -`; - -exports[`should render correctly if there is missing data 1`] = ` - - - - - issue.type.VULNERABILITY.plural - - - - - 5 - - - - -`; - -exports[`should render correctly if there is missing data 2`] = ` - - - - - issue.type.VULNERABILITY.plural - - - - - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap new file mode 100644 index 00000000000..62866095c17 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowOfType-test.tsx.snap @@ -0,0 +1,120 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + + + + + issue.type.BUG.plural + + + + + 3 + + + + + 7 + + + +`; + +exports[`should render correctly if there is 0 rules 1`] = ` + + + + + issue.type.VULNERABILITY.plural + + + + + 0 + + + + + 0 + + + +`; + +exports[`should render correctly if there is missing data 1`] = ` + + + + + issue.type.VULNERABILITY.plural + + + + + 5 + + + + +`; + +exports[`should render correctly if there is missing data 2`] = ` + + + + + issue.type.VULNERABILITY.plural + + + + + +`; 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.js.snap deleted file mode 100644 index f8686659326..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.js.snap +++ /dev/null @@ -1,112 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - - - total - - - - - - 3 - - - - - - - 7 - - - - -`; - -exports[`should render correctly if there is 0 rules 1`] = ` - - - - total - - - - - - 0 - - - - - - 0 - - - -`; - -exports[`should render correctly if there is missing data 1`] = ` - - - - total - - - - - - 5 - - - - - -`; - -exports[`should render correctly if there is missing data 2`] = ` - - - - total - - - - - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap new file mode 100644 index 00000000000..f8686659326 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesRowTotal-test.tsx.snap @@ -0,0 +1,112 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + + + + total + + + + + + 3 + + + + + + + 7 + + + + +`; + +exports[`should render correctly if there is 0 rules 1`] = ` + + + + total + + + + + + 0 + + + + + + 0 + + + +`; + +exports[`should render correctly if there is missing data 1`] = ` + + + + total + + + + + + 5 + + + + + +`; + +exports[`should render correctly if there is missing data 2`] = ` + + + + total + + + + + +`; 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.js.snap deleted file mode 100644 index 481846b23ad..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.js.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -
    - - quality_profiles.sonarway_missing_rules - - - - - - 158 - -
    -`; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap new file mode 100644 index 00000000000..481846b23ad --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +
    + + quality_profiles.sonarway_missing_rules + + + + + + 158 + +
    +`; 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.js deleted file mode 100644 index d95984ce033..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.js +++ /dev/null @@ -1,204 +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 Modal from 'react-modal'; -import 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, name: string }>, - language?: string, - loading: boolean, - name: string, - preloading: boolean -}; -*/ - -export default class CreateProfileForm extends React.PureComponent { - /*:: form: HTMLFormElement; */ - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { importers: [], loading: false, name: '', preloading: true }; - - componentDidMount() { - this.mounted = true; - this.fetchImporters(); - } - - componentWillUnmount() { - this.mounted = false; - } - - fetchImporters() { - getImporters().then(importers => { - if (this.mounted) { - this.setState({ importers, preloading: false }); - } - }); - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleNameChange = (event /*: { currentTarget: HTMLInputElement } */) => { - this.setState({ name: event.currentTarget.value }); - }; - - handleLanguageChange = (option /*: { value: string } */) => { - this.setState({ language: option.value }); - }; - - handleFormSubmit = (event /*: Event */) => { - event.preventDefault(); - - this.setState({ loading: true }); - - const data = new FormData(this.form); - if (this.props.organization) { - data.append('organization', this.props.organization); - } - - createQualityProfile(data).then( - response => this.props.onCreate(response.profile), - error => { - if (this.mounted) { - this.setState({ loading: false }); - } - this.props.onRequestFail(error); - } - ); - }; - - render() { - const header = translate('quality_profiles.new_profile'); - - const languages = sortBy(this.props.languages, 'name'); - const selectedLanguage = this.state.language || languages[0].key; - const importers = this.state.importers.filter(importer => - importer.languages.includes(selectedLanguage) - ); - - return ( - -
    (this.form = node)}> -
    -

    - {header} -

    -
    - - {this.state.preloading - ?
    - -
    - :
    -
    - - -
    -
    - - -

    - {translate('quality_profiles.optional_configuration_file')} -

    -
    - )} -
    } - -
    - {this.state.loading && } - {!this.state.preloading && - } - - {translate('cancel')} - -
    - -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx new file mode 100644 index 00000000000..8f6d589cff8 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx @@ -0,0 +1,196 @@ +/* + * 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 Modal from 'react-modal'; +import * as Select from 'react-select'; +import { sortBy } from 'lodash'; +import { getImporters, createQualityProfile } from '../../../api/quality-profiles'; +import { translate } from '../../../helpers/l10n'; + +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; name: string }>; + language?: string; + loading: boolean; + name: string; + preloading: boolean; +} + +export default class CreateProfileForm extends React.PureComponent { + /*:: form: HTMLFormElement; */ + mounted: boolean; + state: State = { importers: [], loading: false, name: '', preloading: true }; + + componentDidMount() { + this.mounted = true; + this.fetchImporters(); + } + + componentWillUnmount() { + this.mounted = false; + } + + fetchImporters() { + getImporters().then( + (importers: Array<{ key: string; languages: Array; name: string }>) => { + if (this.mounted) { + this.setState({ importers, preloading: false }); + } + } + ); + } + + handleCancelClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + handleNameChange = (event: React.SyntheticEvent) => { + this.setState({ name: event.currentTarget.value }); + }; + + handleLanguageChange = (option: { value: string }) => { + this.setState({ language: option.value }); + }; + + handleFormSubmit = (event: React.SyntheticEvent) => { + event.preventDefault(); + + this.setState({ loading: true }); + + const data = new FormData(event.currentTarget); + if (this.props.organization) { + data.append('organization', this.props.organization); + } + + createQualityProfile(data).then( + (response: any) => this.props.onCreate(response.profile), + (error: any) => { + if (this.mounted) { + this.setState({ loading: false }); + } + this.props.onRequestFail(error); + } + ); + }; + + render() { + const header = translate('quality_profiles.new_profile'); + + const languages = sortBy(this.props.languages, 'name'); + const selectedLanguage = this.state.language || languages[0].key; + const importers = this.state.importers.filter(importer => + importer.languages.includes(selectedLanguage) + ); + + return ( + +
    +
    +

    + {header} +

    +
    + + {this.state.preloading + ?
    + +
    + :
    +
    + + +
    +
    + + +

    + {translate('quality_profiles.optional_configuration_file')} +

    +
    + )} +
    } + +
    + {this.state.loading && } + {!this.state.preloading && + } + + {translate('cancel')} + +
    + +
    + ); + } +} 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.js deleted file mode 100644 index 4be28f3dd04..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js +++ /dev/null @@ -1,48 +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 EvolutionDeprecated from './EvolutionDeprecated'; -import EvolutionStagnant from './EvolutionStagnant'; -import EvolutionRules from './EvolutionRules'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - organization: ?string, - profiles: Array -}; -*/ - -export default class Evolution extends React.PureComponent { - /*:: props: Props; */ - - render() { - const { organization, profiles } = this.props; - - return ( -
    - - - -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx new file mode 100644 index 00000000000..f238580d1e2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.tsx @@ -0,0 +1,39 @@ +/* + * 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 EvolutionDeprecated from './EvolutionDeprecated'; +import EvolutionStagnant from './EvolutionStagnant'; +import EvolutionRules from './EvolutionRules'; +import { IProfile } from '../types'; + +interface Props { + organization: string | null; + profiles: IProfile[]; +} + +export default function Evolution({ organization, profiles }: Props) { + return ( +
    + + + +
    + ); +} 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 -}; -*/ - -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 ( -
    -
    - - {translate('quality_profiles.deprecated_rules')} - -
    -
    - {translateWithParameters( - 'quality_profiles.deprecated_rules_are_still_activated', - profilesWithDeprecations.length - )} -
    -
      - {sortedProfiles.map(profile => -
    • -
      - - {profile.name} - -
      -
      - {profile.languageName} - {', '} - - {translateWithParameters( - 'quality_profile.x_rules', - profile.activeDeprecatedRuleCount - )} - -
      -
    • - )} -
    -
    - ); - } -} 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 ( +
    +
    + + {translate('quality_profiles.deprecated_rules')} + +
    +
    + {translateWithParameters( + 'quality_profiles.deprecated_rules_are_still_activated', + profilesWithDeprecations.length + )} +
    +
      + {sortedProfiles.map(profile => +
    • +
      + + {profile.name} + +
      +
      + {profile.languageName} + {', '} + + {translateWithParameters( + 'quality_profile.x_rules', + profile.activeDeprecatedRuleCount + )} + +
      +
    • + )} +
    +
    + ); +} 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.js deleted file mode 100644 index 042c04a73b6..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js +++ /dev/null @@ -1,134 +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 { sortBy } from 'lodash'; -import { searchRules } from '../../../api/rules'; -import { translateWithParameters, translate } from '../../../helpers/l10n'; -import { getRulesUrl } from '../../../helpers/urls'; -import { formatMeasure } from '../../../helpers/measures'; - -const RULES_LIMIT = 10; - -const PERIOD_START_MOMENT = moment().subtract(1, 'year'); - -function parseRules(r) { - const { rules, actives } = r; - return rules.map(rule => { - const activations = actives[rule.key]; - return { ...rule, activations: activations ? activations.length : 0 }; - }); -} - -/*:: -type Props = { - organization: ?string -}; -*/ - -export default class EvolutionRules extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state = {}; - - componentDidMount() { - this.mounted = true; - this.loadLatestRules(); - } - - componentWillUnmount() { - this.mounted = false; - } - - loadLatestRules() { - const data = { - available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD'), - s: 'createdAt', - asc: false, - ps: RULES_LIMIT, - f: 'name,langName,actives' - }; - - searchRules(data).then(r => { - if (this.mounted) { - this.setState({ - latestRules: sortBy(parseRules(r), 'langName'), - latestRulesTotal: r.total - }); - } - }); - } - - render() { - if (!this.state.latestRulesTotal) { - return null; - } - - const newRulesUrl = getRulesUrl( - { - available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD') - }, - this.props.organization - ); - - return ( -
    -
    - - {translate('quality_profiles.latest_new_rules')} - -
    -
      - {this.state.latestRules.map(rule => -
    • -
      - - {' '}{rule.name} - -
      - {rule.activations - ? translateWithParameters( - 'quality_profiles.latest_new_rules.activated', - rule.langName, - rule.activations - ) - : translateWithParameters( - 'quality_profiles.latest_new_rules.not_activated', - rule.langName - )} -
      -
      -
    • - )} -
    - {this.state.latestRulesTotal > RULES_LIMIT && -
    - - {translate('see_all')} {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT')} - -
    } -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx new file mode 100644 index 00000000000..c9e3e1f46e1 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.tsx @@ -0,0 +1,142 @@ +/* + * 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 { sortBy } from 'lodash'; +import { searchRules } from '../../../api/rules'; +import { translateWithParameters, translate } from '../../../helpers/l10n'; +import { getRulesUrl } from '../../../helpers/urls'; +import { formatMeasure } from '../../../helpers/measures'; + +const RULES_LIMIT = 10; + +const PERIOD_START_MOMENT = moment().subtract(1, 'year'); + +function parseRules(r: any) { + const { rules, actives } = r; + return rules.map((rule: any) => { + const activations = actives[rule.key]; + return { ...rule, activations: activations ? activations.length : 0 }; + }); +} + +interface Props { + organization: string | null; +} + +interface IRule { + activations: number; + key: string; + langName: string; + name: string; +} + +interface State { + latestRules?: Array; + latestRulesTotal?: number; +} + +export default class EvolutionRules extends React.PureComponent { + mounted: boolean; + state: State = {}; + + componentDidMount() { + this.mounted = true; + this.loadLatestRules(); + } + + componentWillUnmount() { + this.mounted = false; + } + + loadLatestRules() { + const data = { + available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD'), + s: 'createdAt', + asc: false, + ps: RULES_LIMIT, + f: 'name,langName,actives' + }; + + searchRules(data).then((r: any) => { + if (this.mounted) { + this.setState({ + latestRules: sortBy(parseRules(r), 'langName'), + latestRulesTotal: r.total + }); + } + }); + } + + render() { + if (!this.state.latestRulesTotal || !this.state.latestRules) { + return null; + } + + const newRulesUrl = getRulesUrl( + { + available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD') + }, + this.props.organization + ); + + return ( +
    +
    + + {translate('quality_profiles.latest_new_rules')} + +
    +
      + {this.state.latestRules.map(rule => +
    • +
      + + {' '}{rule.name} + +
      + {rule.activations + ? translateWithParameters( + 'quality_profiles.latest_new_rules.activated', + rule.langName, + rule.activations + ) + : translateWithParameters( + 'quality_profiles.latest_new_rules.not_activated', + rule.langName + )} +
      +
      +
    • + )} +
    + {this.state.latestRulesTotal > RULES_LIMIT && +
    + + {translate('see_all')} {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT', null)} + +
    } +
    + ); + } +} 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 -}; -*/ - -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 ( -
    -
    - - {translate('quality_profiles.stagnant_profiles')} - -
    -
    - {translate('quality_profiles.not_updated_more_than_year')} -
    -
      - {outdated.map(profile => -
    • -
      - - {profile.name} - -
      -
      - {profile.languageName} - {', '} - updated on {moment(profile.rulesUpdatedAt).format('LL')} -
      -
    • - )} -
    -
    - ); - } -} 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 ( +
    +
    + + {translate('quality_profiles.stagnant_profiles')} + +
    +
    + {translate('quality_profiles.not_updated_more_than_year')} +
    +
      + {outdated.map(profile => +
    • +
      + + {profile.name} + +
      +
      + {profile.languageName} + {', '} + updated on {moment(profile.rulesUpdatedAt).format('LL')} +
      +
    • + )} +
    +
    + ); +} 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.js deleted file mode 100644 index 95f63d8cd4c..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js +++ /dev/null @@ -1,58 +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 PageHeader from './PageHeader'; -import Evolution from './Evolution'; -import ProfilesList from './ProfilesList'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - canAdmin: boolean, - languages: Array<{ key: string, name: string }>, - location: { query: { [string]: string } }, - onRequestFail: Object => void, - organization?: string, - profiles: Array, - updateProfiles: () => Promise<*> -}; -*/ - -export default class HomeContainer extends React.PureComponent { - /*:: props: Props; */ - - render() { - return ( -
    - - -
    -
    - -
    -
    - -
    -
    -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx new file mode 100644 index 00000000000..cd3b21502a5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx @@ -0,0 +1,51 @@ +/* + * 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 PageHeader from './PageHeader'; +import Evolution from './Evolution'; +import ProfilesList from './ProfilesList'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + languages: Array<{ key: string; name: string }>; + location: { query: { [p: string]: string } }; + onRequestFail: (reason: any) => void; + organization: string | null; + profiles: Array; + updateProfiles: () => Promise; +} + +export default function HomeContainer(props: Props) { + return ( +
    + + +
    +
    + +
    +
    + +
    +
    +
    + ); +} 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.js deleted file mode 100644 index 44ba30feeb7..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js +++ /dev/null @@ -1,134 +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'; -import CreateProfileForm from './CreateProfileForm'; -import RestoreProfileForm from './RestoreProfileForm'; -/*:: import type { Profile } from '../propTypes'; */ -import { getProfilePath } from '../utils'; -import { translate } from '../../../helpers/l10n'; - -/*:: -type Props = { - canAdmin: boolean, - languages: Array<{ key: string, name: string }>, - onRequestFail: Object => void, - organization: ?string, - updateProfiles: () => Promise<*> -}; -*/ - -/*:: -type State = { - createFormOpen: boolean, - restoreFormOpen: boolean -}; -*/ - -export default class PageHeader extends React.PureComponent { - /*:: props: Props; */ - - static contextTypes = { - router: PropTypes.object - }; - - state /*: State */ = { - createFormOpen: false, - restoreFormOpen: false - }; - - handleCreateClick = (event /*: Event & { currentTarget: HTMLButtonElement } */) => { - event.preventDefault(); - event.currentTarget.blur(); - this.setState({ createFormOpen: true }); - }; - - handleCreate = (profile /*: Profile */) => { - this.props.updateProfiles().then(() => { - this.context.router.push( - getProfilePath(profile.name, profile.language, this.props.organization) - ); - }); - }; - - closeCreateForm = () => { - this.setState({ createFormOpen: false }); - }; - - handleRestoreClick = (event /*: Event */) => { - event.preventDefault(); - this.setState({ restoreFormOpen: true }); - }; - - closeRestoreForm = () => { - this.setState({ restoreFormOpen: false }); - }; - - render() { - return ( -
    -

    - {translate('quality_profiles.page')} -

    - - {this.props.canAdmin && -
    - - - -
    } - -
    - {translate('quality_profiles.intro1')} -
    - {translate('quality_profiles.intro2')} -
    - - {this.state.restoreFormOpen && - } - - {this.state.createFormOpen && - } -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx new file mode 100644 index 00000000000..0f3b2b9c19f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx @@ -0,0 +1,127 @@ +/* + * 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 PropTypes from 'prop-types'; +import CreateProfileForm from './CreateProfileForm'; +import RestoreProfileForm from './RestoreProfileForm'; +import { getProfilePath } from '../utils'; +import { translate } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +interface Props { + canAdmin: boolean; + languages: Array<{ key: string; name: string }>; + onRequestFail: (reason: any) => void; + organization: string | null; + updateProfiles: () => Promise; +} + +interface State { + createFormOpen: boolean; + restoreFormOpen: boolean; +} + +export default class PageHeader extends React.PureComponent { + static contextTypes = { + router: PropTypes.object + }; + + state = { + createFormOpen: false, + restoreFormOpen: false + }; + + handleCreateClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + event.currentTarget.blur(); + this.setState({ createFormOpen: true }); + }; + + handleCreate = (profile: IProfile) => { + this.props.updateProfiles().then(() => { + this.context.router.push( + getProfilePath(profile.name, profile.language, this.props.organization) + ); + }); + }; + + closeCreateForm = () => { + this.setState({ createFormOpen: false }); + }; + + handleRestoreClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.setState({ restoreFormOpen: true }); + }; + + closeRestoreForm = () => { + this.setState({ restoreFormOpen: false }); + }; + + render() { + return ( +
    +

    + {translate('quality_profiles.page')} +

    + + {this.props.canAdmin && +
    + + + +
    } + +
    + {translate('quality_profiles.intro1')} +
    + {translate('quality_profiles.intro2')} +
    + + {this.state.restoreFormOpen && + } + + {this.state.createFormOpen && + } +
    + ); + } +} 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.js deleted file mode 100644 index b912a9662a5..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js +++ /dev/null @@ -1,130 +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 { 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'; */ - -/*:: -type Props = { - canAdmin: boolean, - languages: Array<{ key: string, name: string }>, - location: { query: { [string]: string } }, - onRequestFail: Object => void, - organization: ?string, - profiles: Array, - updateProfiles: () => Promise<*> -}; -*/ - -export default class ProfilesList extends React.PureComponent { - /*:: props: Props; */ - - renderProfiles(profiles /*: Array */) { - return profiles.map(profile => - - ); - } - - renderHeader(languageKey /*: string */, profilesCount /*: number */) { - const language = this.props.languages.find(l => l.key === languageKey); - - if (!language) { - return null; - } - - return ( - - - - {language.name} - {', '} - {translateWithParameters('quality_profiles.x_profiles', profilesCount)} - - - {translate('quality_profiles.list.projects')} - - - {translate('quality_profiles.list.rules')} - - - {translate('quality_profiles.list.updated')} - - - {translate('quality_profiles.list.used')} - - {this.props.canAdmin &&  } - - - ); - } - - render() { - 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 languagesToShow = sortBy(Object.keys(profilesToShow)); - - return ( -
    - - - {Object.keys(profilesToShow).length === 0 && -
    - {translate('no_results')} -
    } - - {languagesToShow.map(languageKey => -
    - - {profilesToShow[languageKey] != null && - this.renderHeader(languageKey, profilesToShow[languageKey].length)} - - - - {profilesToShow[languageKey] != null && - this.renderProfiles(profilesToShow[languageKey])} - - -
    -
    - )} -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx new file mode 100644 index 00000000000..6f4c8f8c17b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx @@ -0,0 +1,128 @@ +/* + * 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 { groupBy, pick, sortBy } from 'lodash'; +import ProfilesListRow from './ProfilesListRow'; +import ProfilesListHeader from './ProfilesListHeader'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { IProfile } from '../types'; + +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; +} + +export default class ProfilesList extends React.PureComponent { + renderProfiles(profiles: IProfile[]) { + return profiles.map(profile => + + ); + } + + renderHeader(languageKey: string, profilesCount: number) { + const language = this.props.languages.find(l => l.key === languageKey); + + if (!language) { + return null; + } + + return ( + + + + {language.name} + {', '} + {translateWithParameters('quality_profiles.x_profiles', profilesCount)} + + + {translate('quality_profiles.list.projects')} + + + {translate('quality_profiles.list.rules')} + + + {translate('quality_profiles.list.updated')} + + + {translate('quality_profiles.list.used')} + + {this.props.canAdmin &&  } + + + ); + } + + render() { + const { profiles, languages } = this.props; + const { language } = this.props.location.query; + + const profilesIndex: { [language: string]: IProfile[] } = groupBy( + profiles, + profile => profile.language + ); + + const profilesToShow: { [language: string]: IProfile[] } = language + ? pick(profilesIndex, language) + : profilesIndex; + + const languagesToShow = sortBy(Object.keys(profilesToShow)); + + return ( +
    + + + {Object.keys(profilesToShow).length === 0 && +
    + {translate('no_results')} +
    } + + {languagesToShow.map(languageKey => +
    + + {profilesToShow[languageKey] != null && + this.renderHeader(languageKey, profilesToShow[languageKey].length)} + + + {profilesToShow[languageKey] != null && + this.renderProfiles(profilesToShow[languageKey])} + +
    +
    + )} +
    + ); + } +} 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.js deleted file mode 100644 index ab76d1a4df3..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js +++ /dev/null @@ -1,99 +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 { 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; */ - - renderFilterToggle() { - const { languages, currentFilter } = this.props; - const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); - - const label = currentLanguage - ? translateWithParameters('quality_profiles.x_Profiles', currentLanguage.name) - : translate('quality_profiles.all_profiles'); - - return ( - - {label} - - ); - } - - renderFilterMenu() { - return ( -
      -
    • - - {translate('quality_profiles.all_profiles')} - -
    • - {this.props.languages.map(language => -
    • - - {language.name} - -
    • - )} -
    - ); - } - - render() { - if (this.props.languages.length < 2) { - return null; - } - - const { languages, currentFilter } = this.props; - const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); - - // if unknown language, then - if (currentFilter && !currentLanguage) { - return null; - } - - return ( -
    -
    - {this.renderFilterToggle()} - {this.renderFilterMenu()} -
    -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.tsx new file mode 100644 index 00000000000..15b98d6a2d4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.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 { IndexLink } from 'react-router'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { getProfilesPath, getProfilesForLanguagePath } from '../utils'; + +interface Props { + currentFilter?: string; + languages: Array<{ key: string; name: string }>; + organization: string | null; +} + +export default class ProfilesListHeader extends React.PureComponent { + renderFilterToggle() { + const { languages, currentFilter } = this.props; + const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); + + const label = currentLanguage + ? translateWithParameters('quality_profiles.x_Profiles', currentLanguage.name) + : translate('quality_profiles.all_profiles'); + + return ( + + {label} + + ); + } + + renderFilterMenu() { + return ( +
      +
    • + + {translate('quality_profiles.all_profiles')} + +
    • + {this.props.languages.map(language => +
    • + + {language.name} + +
    • + )} +
    + ); + } + + render() { + if (this.props.languages.length < 2) { + return null; + } + + const { languages, currentFilter } = this.props; + const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); + + // if unknown language, then + if (currentFilter && !currentLanguage) { + return null; + } + + return ( +
    +
    + {this.renderFilterToggle()} + {this.renderFilterMenu()} +
    +
    + ); + } +} 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.js deleted file mode 100644 index f9d18056d2e..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js +++ /dev/null @@ -1,186 +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 ProfileLink from '../components/ProfileLink'; -import ProfileDate from '../components/ProfileDate'; -import ProfileActions from '../components/ProfileActions'; -import BuiltInBadge from '../components/BuiltInBadge'; -import { translate } from '../../../helpers/l10n'; -import { getRulesUrl } from '../../../helpers/urls'; -import { isStagnant } from '../utils'; -/*:: import type { Profile } from '../propTypes'; */ - -/*:: -type Props = { - canAdmin: boolean, - onRequestFail: Object => void, - organization: ?string, - profile: Profile, - updateProfiles: () => Promise<*> -}; -*/ - -export default class ProfilesListRow extends React.PureComponent { - /*:: props: Props; */ - - renderName() { - const { profile } = this.props; - const offset = 25 * (profile.depth - 1); - return ( -
    - - {profile.name} - - {profile.isBuiltIn && } -
    - ); - } - - renderProjects() { - const { profile } = this.props; - - if (profile.isDefault) { - return ( - - {translate('default')} - - ); - } - - return ( - - {profile.projectCount} - - ); - } - - renderRules() { - const { profile } = this.props; - - const activeRulesUrl = getRulesUrl( - { - qprofile: profile.key, - activation: 'true' - }, - this.props.organization - ); - - const deprecatedRulesUrl = getRulesUrl( - { - qprofile: profile.key, - activation: 'true', - statuses: 'DEPRECATED' - }, - this.props.organization - ); - - return ( -
    - {profile.activeDeprecatedRuleCount > 0 && - - - {profile.activeDeprecatedRuleCount} - - } - - - {profile.activeRuleCount} - -
    - ); - } - - renderUpdateDate() { - const date = ; - if (isStagnant(this.props.profile)) { - return ( - - {date} - - ); - } else { - return date; - } - } - - renderUsageDate() { - const { lastUsed } = this.props.profile; - const date = ; - if (!lastUsed) { - return ( - - {date} - - ); - } else { - return date; - } - } - - render() { - return ( - - - {this.renderName()} - - - {this.renderProjects()} - - - {this.renderRules()} - - - {this.renderUpdateDate()} - - - {this.renderUsageDate()} - - {this.props.canAdmin && - -
    - - -
    - } - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx new file mode 100644 index 00000000000..2d982c34db4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx @@ -0,0 +1,180 @@ +/* + * 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 ProfileLink from '../components/ProfileLink'; +import ProfileDate from '../components/ProfileDate'; +import ProfileActions from '../components/ProfileActions'; +import BuiltInBadge from '../components/BuiltInBadge'; +import { translate } from '../../../helpers/l10n'; +import { getRulesUrl } from '../../../helpers/urls'; +import { isStagnant } from '../utils'; +import { IProfile } from '../types'; +import Tooltip from '../../../components/controls/Tooltip'; + +interface Props { + canAdmin: boolean; + onRequestFail: (reason: any) => void; + organization: string | null; + profile: IProfile; + updateProfiles: () => Promise; +} + +export default class ProfilesListRow extends React.PureComponent { + renderName() { + const { profile } = this.props; + const offset = 25 * (profile.depth - 1); + return ( +
    + + {profile.name} + + {profile.isBuiltIn && } +
    + ); + } + + renderProjects() { + const { profile } = this.props; + + if (profile.isDefault) { + return ( + + {translate('default')} + + ); + } + + return ( + + {profile.projectCount} + + ); + } + + renderRules() { + const { profile } = this.props; + + const activeRulesUrl = getRulesUrl( + { + qprofile: profile.key, + activation: 'true' + }, + this.props.organization + ); + + const deprecatedRulesUrl = getRulesUrl( + { + qprofile: profile.key, + activation: 'true', + statuses: 'DEPRECATED' + }, + this.props.organization + ); + + return ( +
    + {profile.activeDeprecatedRuleCount > 0 && + + + + {profile.activeDeprecatedRuleCount} + + + } + + + {profile.activeRuleCount} + +
    + ); + } + + renderUpdateDate() { + const date = ; + if (isStagnant(this.props.profile)) { + return ( + + {date} + + ); + } else { + return date; + } + } + + renderUsageDate() { + const { lastUsed } = this.props.profile; + const date = ; + if (!lastUsed) { + return ( + + {date} + + ); + } else { + return date; + } + } + + render() { + return ( + + + {this.renderName()} + + + {this.renderProjects()} + + + {this.renderRules()} + + + {this.renderUpdateDate()} + + + {this.renderUsageDate()} + + {this.props.canAdmin && + +
    + + +
    + } + + ); + } +} 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.js deleted file mode 100644 index 26411abb34c..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.js +++ /dev/null @@ -1,162 +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 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 -}; -*/ - -/*:: -type 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 }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleCancelClick = (event /*: Event */) => { - event.preventDefault(); - this.props.onClose(); - }; - - handleFormSubmit = (event /*: Event */) => { - event.preventDefault(); - - this.setState({ loading: true }); - - const data = new FormData(this.form); - if (this.props.organization) { - data.append('organization', this.props.organization); - } - - restoreQualityProfile(data).then( - response => { - if (this.mounted) { - this.setState({ - loading: false, - profile: response.profile, - ruleFailures: response.ruleFailures, - ruleSuccesses: response.ruleSuccesses - }); - } - this.props.onRestore(); - }, - error => { - if (this.mounted) { - this.setState({ loading: false }); - } - this.props.onRequestFail(error); - } - ); - }; - - render() { - const header = translate('quality_profiles.restore_profile'); - - const { loading, profile, ruleFailures, ruleSuccesses } = this.state; - - return ( - -
    (this.form = node)}> -
    -

    - {header} -

    -
    - -
    - {profile != null && ruleSuccesses != null - ? ruleFailures - ?
    - {translateWithParameters( - 'quality_profiles.restore_profile.warning', - profile.name, - ruleSuccesses, - ruleFailures - )} -
    - :
    - {translateWithParameters( - 'quality_profiles.restore_profile.success', - profile.name, - ruleSuccesses - )} -
    - :
    - - -
    } -
    - - {ruleSuccesses == null - ?
    - {loading && } - - - {translate('cancel')} - -
    - : } - -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx new file mode 100644 index 00000000000..5f12d61f662 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx @@ -0,0 +1,152 @@ +/* + * 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 Modal from 'react-modal'; +import { restoreQualityProfile } from '../../../api/quality-profiles'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; + +interface Props { + onClose: () => void; + onRequestFail: (reason: any) => void; + onRestore: () => void; + organization: string | null; +} + +interface State { + loading: boolean; + profile?: { name: string }; + ruleFailures?: number; + ruleSuccesses?: number; +} + +export default class RestoreProfileForm extends React.PureComponent { + mounted: boolean; + state: State = { loading: false }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + handleCancelClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + this.props.onClose(); + }; + + handleFormSubmit = (event: React.SyntheticEvent) => { + event.preventDefault(); + + this.setState({ loading: true }); + + const data = new FormData(event.currentTarget); + if (this.props.organization) { + data.append('organization', this.props.organization); + } + + restoreQualityProfile(data).then( + (response: any) => { + if (this.mounted) { + this.setState({ + loading: false, + profile: response.profile, + ruleFailures: response.ruleFailures, + ruleSuccesses: response.ruleSuccesses + }); + } + this.props.onRestore(); + }, + (error: any) => { + if (this.mounted) { + this.setState({ loading: false }); + } + this.props.onRequestFail(error); + } + ); + }; + + render() { + const header = translate('quality_profiles.restore_profile'); + + const { loading, profile, ruleFailures, ruleSuccesses } = this.state; + + return ( + +
    +
    +

    + {header} +

    +
    + +
    + {profile != null && ruleSuccesses != null + ? ruleFailures + ?
    + {translateWithParameters( + 'quality_profiles.restore_profile.warning', + profile.name, + ruleSuccesses, + ruleFailures + )} +
    + :
    + {translateWithParameters( + 'quality_profiles.restore_profile.success', + profile.name, + ruleSuccesses + )} +
    + :
    + + +
    } +
    + + {ruleSuccesses == null + ?
    + {loading && } + + + {translate('cancel')} + +
    + : } + +
    + ); + } +} 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 -}; -*/ - -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.js deleted file mode 100644 index 1d7b96fe647..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js +++ /dev/null @@ -1,68 +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 { withRouter } from 'react-router'; - -const routes = [ - { - getComponent(state, callback) { - import('./components/AppContainer').then(i => i.default).then(AppContainer => { - if (state.params.organizationKey) { - callback(null, AppContainer); - } else { - import('../organizations/forSingleOrganization') - .then(i => i.default) - .then(forSingleOrganization => callback(null, forSingleOrganization(AppContainer))); - } - }); - }, - getIndexRoute(_, callback) { - import('./home/HomeContainer').then(i => callback(null, { component: i.default })); - }, - childRoutes: [ - { - getComponent(_, callback) { - import('./components/ProfileContainer').then(i => callback(null, withRouter(i.default))); - }, - childRoutes: [ - { - path: 'show', - getComponent(_, callback) { - import('./details/ProfileDetails').then(i => callback(null, i.default)); - } - }, - { - path: 'changelog', - getComponent(_, callback) { - import('./changelog/ChangelogContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'compare', - getComponent(_, callback) { - import('./compare/ComparisonContainer').then(i => callback(null, i.default)); - } - } - ] - } - ] - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts new file mode 100644 index 00000000000..cac3704b319 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.ts @@ -0,0 +1,68 @@ +/* + * 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 { withRouter, RouterState, IndexRouteProps, RouteComponent } from 'react-router'; + +const routes = [ + { + 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); + } else { + import('../organizations/forSingleOrganization') + .then(i => i.default) + .then(forSingleOrganization => callback(null, forSingleOrganization(AppContainer))); + } + }); + }, + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./home/HomeContainer').then(i => callback(null, { component: i.default })); + }, + childRoutes: [ + { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/ProfileContainer').then(i => callback(null, withRouter(i.default))); + }, + childRoutes: [ + { + path: 'show', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./details/ProfileDetails').then(i => callback(null, i.default)); + } + }, + { + path: 'changelog', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./changelog/ChangelogContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'compare', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./compare/ComparisonContainer').then(i => callback(null, i.default)); + } + } + ] + } + ] + } +]; + +export default routes; 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.js deleted file mode 100644 index 60ec46e6572..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js +++ /dev/null @@ -1,128 +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 { sortBy } from 'lodash'; -import moment from 'moment'; -/*:: import type { Profile } from './propTypes'; */ - -export function sortProfiles(profiles /*: Array */) { - const result = []; - const sorted = sortBy(profiles, 'name'); - - function retrieveChildren(parent) { - return sorted.filter( - p => (parent == null && p.parentKey == null) || (parent != null && p.parentKey === parent.key) - ); - } - - function putProfile(profile = null, depth = 1) { - const children = retrieveChildren(profile); - - if (profile != null) { - result.push({ ...profile, childrenCount: children.length, depth }); - } - - children.forEach(child => putProfile(child, depth + 1)); - } - - sorted - .filter( - profile => profile.parentKey == null || sorted.find(p => p.key === profile.parentKey) == null - ) - .forEach(profile => putProfile(profile)); - - return result; -} - -export function createFakeProfile(overrides /*: {} */) { - return { - key: 'key', - name: 'name', - isDefault: false, - isInherited: false, - language: 'js', - languageName: 'JavaScript', - activeRuleCount: 10, - activeDeprecatedRuleCount: 2, - projectCount: 3, - ...overrides - }; -} - -export function isStagnant(profile /*: Profile */) { - return moment().diff(moment(profile.userUpdatedAt), 'years') >= 1; -} - -export const getProfilesPath = (organization /*: ?string */) => - organization ? `/organizations/${organization}/quality_profiles` : '/profiles'; - -export const getProfilesForLanguagePath = ( - language /*: string */, - organization /*: ?string */ -) => ({ - pathname: getProfilesPath(organization), - query: { language } -}); - -export const getProfilePath = ( - name /*: string */, - language /*: string */, - organization /*: ?string */ -) => ({ - pathname: getProfilesPath(organization) + '/show', - query: { name, language } -}); - -export const getProfileComparePath = ( - name /*: string */, - language /*: string */, - organization /*: ?string */, - withKey /*: ?string */ -) => { - const query /*: Object */ = { language, name }; - if (withKey) { - Object.assign(query, { withKey }); - } - return { - pathname: getProfilesPath(organization) + '/compare', - query - }; -}; - -export const getProfileChangelogPath = ( - name /*: string */, - language /*: string */, - organization /*: ?string */, - filter /*: ?{ since?: string, to?: string } */ -) => { - const query /*: Object */ = { language, name }; - if (filter) { - if (filter.since) { - Object.assign(query, { since: filter.since }); - } - if (filter.to) { - Object.assign(query, { to: filter.to }); - } - } - return { - pathname: getProfilesPath(organization) + '/changelog', - query - }; -}; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/utils.ts b/server/sonar-web/src/main/js/apps/quality-profiles/utils.ts new file mode 100644 index 00000000000..890f3879e63 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/utils.ts @@ -0,0 +1,120 @@ +/* + * 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 { sortBy } from 'lodash'; +import * as moment from 'moment'; +import { IProfile } from './types'; + +export function sortProfiles(profiles: IProfile[]) { + const result: IProfile[] = []; + const sorted = sortBy(profiles, 'name'); + + function retrieveChildren(parent: IProfile | null) { + return sorted.filter( + p => (parent == null && p.parentKey == null) || (parent != null && p.parentKey === parent.key) + ); + } + + function putProfile(profile: IProfile | null = null, depth: number = 1) { + const children = retrieveChildren(profile); + + if (profile != null) { + result.push({ ...profile, childrenCount: children.length, depth }); + } + + children.forEach(child => putProfile(child, depth + 1)); + } + + sorted + .filter( + profile => profile.parentKey == null || sorted.find(p => p.key === profile.parentKey) == null + ) + .forEach(profile => putProfile(profile)); + + return result; +} + +export function createFakeProfile(overrides?: any) { + return { + key: 'key', + name: 'name', + isDefault: false, + isInherited: false, + language: 'js', + languageName: 'JavaScript', + activeRuleCount: 10, + activeDeprecatedRuleCount: 2, + projectCount: 3, + ...overrides + }; +} + +export function isStagnant(profile: IProfile) { + return moment().diff(moment(profile.userUpdatedAt), 'years') >= 1; +} + +export const getProfilesPath = (organization: string | null) => + organization ? `/organizations/${organization}/quality_profiles` : '/profiles'; + +export const getProfilesForLanguagePath = (language: string, organization: string | null) => ({ + pathname: getProfilesPath(organization), + query: { language } +}); + +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 | null, + withKey?: string +) => { + const query = { language, name }; + if (withKey) { + Object.assign(query, { withKey }); + } + return { + pathname: getProfilesPath(organization) + '/compare', + query + }; +}; + +export const getProfileChangelogPath = ( + name: string, + language: string, + organization: string | null, + filter?: { since?: string; to?: string } +) => { + const query = { language, name }; + if (filter) { + if (filter.since) { + Object.assign(query, { since: filter.since }); + } + if (filter.to) { + Object.assign(query, { to: filter.to }); + } + } + return { + pathname: getProfilesPath(organization) + '/changelog', + query + }; +}; 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 ( -
    -

    - {"You're not authorized to access this page. Please contact the administrator."} -

    - - {!!message && -

    - Reason : {message} -

    } - -
    - Home -
    -
    - ); - } -} 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 ( +
    +

    + {"You're not authorized to access this page. Please contact the administrator."} +

    + + {!!message && +

    + Reason : {message} +

    } + +
    + Home +
    +
    + ); +} diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.js b/server/sonar-web/src/main/js/apps/sessions/routes.js deleted file mode 100644 index 32e367c391f..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/routes.js +++ /dev/null @@ -1,41 +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 = [ - { - path: 'new', - getComponent(_, callback) { - import('./components/LoginFormContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'logout', - getComponent(_, callback) { - import('./components/Logout').then(i => callback(null, i.default)); - } - }, - { - path: 'unauthorized', - getComponent(_, callback) { - import('./components/Unauthorized').then(i => callback(null, i.default)); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.ts b/server/sonar-web/src/main/js/apps/sessions/routes.ts new file mode 100644 index 00000000000..ce1a2e80c70 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/routes.ts @@ -0,0 +1,43 @@ +/* + * 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, RouteComponent } from 'react-router'; + +const routes = [ + { + path: 'new', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/LoginFormContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'logout', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/Logout').then(i => callback(null, i.default)); + } + }, + { + path: 'unauthorized', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/Unauthorized').then(i => callback(null, i.default)); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/settings/routes.js b/server/sonar-web/src/main/js/apps/settings/routes.js deleted file mode 100644 index 9a408f19fe8..00000000000 --- a/server/sonar-web/src/main/js/apps/settings/routes.js +++ /dev/null @@ -1,46 +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('./components/AppContainer').then(i => callback(null, { component: i.default })); - } - }, - { - path: 'licenses', - getComponent(_, callback) { - import('./licenses/LicensesApp').then(i => callback(null, i.default)); - } - }, - { - path: 'encryption', - getComponent(_, callback) { - import('./encryption/EncryptionAppContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'server_id', - getComponent(_, callback) { - import('./serverId/ServerIdAppContainer').then(i => callback(null, i.default)); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/settings/routes.ts b/server/sonar-web/src/main/js/apps/settings/routes.ts new file mode 100644 index 00000000000..54afd122a3d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/routes.ts @@ -0,0 +1,48 @@ +/* + * 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, RouteComponent, IndexRouteProps } from 'react-router'; + +const routes = [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/AppContainer').then(i => callback(null, { component: i.default })); + } + }, + { + path: 'licenses', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./licenses/LicensesApp').then(i => callback(null, i.default)); + } + }, + { + path: 'encryption', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./encryption/EncryptionAppContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'server_id', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./serverId/ServerIdAppContainer').then(i => callback(null, i.default)); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index 81c884ae5d6..00000000000 --- a/server/sonar-web/src/main/js/apps/update-center/routes.js +++ /dev/null @@ -1,54 +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('./components/UpdateCenterAppContainer').then(i => - callback(null, { component: i.default }) - ); - } - }, - { - path: 'installed', - getComponent(_, callback) { - import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'updates', - getComponent(_, callback) { - import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'available', - getComponent(_, callback) { - import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); - } - }, - { - path: 'system', - getComponent(_, callback) { - import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/update-center/routes.ts b/server/sonar-web/src/main/js/apps/update-center/routes.ts new file mode 100644 index 00000000000..e41cfdc073a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/update-center/routes.ts @@ -0,0 +1,56 @@ +/* + * 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, RouteComponent, IndexRouteProps } from 'react-router'; + +const routes = [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/UpdateCenterAppContainer').then(i => + callback(null, { component: i.default }) + ); + } + }, + { + path: 'installed', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'updates', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'available', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); + } + }, + { + path: 'system', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/UpdateCenterAppContainer').then(i => callback(null, i.default)); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/apps/users/routes.js b/server/sonar-web/src/main/js/apps/users/routes.js deleted file mode 100644 index b07c3c9c5c2..00000000000 --- a/server/sonar-web/src/main/js/apps/users/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('./components/UsersAppContainer').then(i => callback(null, { component: i.default })); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/users/routes.ts b/server/sonar-web/src/main/js/apps/users/routes.ts new file mode 100644 index 00000000000..88751d8b803 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/users/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('./components/UsersAppContainer').then(i => callback(null, { component: i.default })); + } + } +]; + +export default routes; 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.js deleted file mode 100644 index 5993b47eea4..00000000000 --- a/server/sonar-web/src/main/js/apps/web-api/routes.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. - */ -const routes = [ - { - getIndexRoute(_, callback) { - import('./components/WebApiApp').then(i => callback(null, { component: i.default })); - } - }, - { - path: '**', - getComponent(_, callback) { - import('./components/WebApiApp').then(i => callback(null, i.default)); - } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/web-api/routes.ts b/server/sonar-web/src/main/js/apps/web-api/routes.ts new file mode 100644 index 00000000000..a76c3f27e93 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/web-api/routes.ts @@ -0,0 +1,36 @@ +/* + * 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, RouteComponent, IndexRouteProps } from 'react-router'; + +const routes = [ + { + getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) { + import('./components/WebApiApp').then(i => callback(null, { component: (i as any).default })); + } + }, + { + path: '**', + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/WebApiApp').then(i => callback(null, (i as any).default)); + } + } +]; + +export default routes; diff --git a/server/sonar-web/src/main/js/components/SelectList/index.js b/server/sonar-web/src/main/js/components/SelectList/index.js index 9c89ab5517f..23e2c7184eb 100644 --- a/server/sonar-web/src/main/js/components/SelectList/index.js +++ b/server/sonar-web/src/main/js/components/SelectList/index.js @@ -107,10 +107,9 @@ const SelectListItemView = Backbone.View.extend({ remove(postpone) { if (postpone) { - const that = this; - that.$el.addClass(this.model.get('selected') ? 'added' : 'removed'); - setTimeout(function() { - Backbone.View.prototype.remove.call(that, arguments); + this.$el.addClass(this.model.get('selected') ? 'added' : 'removed'); + setTimeout(() => { + Backbone.View.prototype.remove.call(this, arguments); }, 500); } else { Backbone.View.prototype.remove.call(this, arguments); diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.js b/server/sonar-web/src/main/js/components/controls/DateInput.js deleted file mode 100644 index 9da950af99a..00000000000 --- a/server/sonar-web/src/main/js/components/controls/DateInput.js +++ /dev/null @@ -1,90 +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 $ from 'jquery'; -import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import { pick } from 'lodash'; -import './styles.css'; - -export default class DateInput extends React.PureComponent { - static propTypes = { - className: PropTypes.string, - value: PropTypes.string, - format: PropTypes.string, - name: PropTypes.string, - placeholder: PropTypes.string, - onChange: PropTypes.func.isRequired - }; - - static defaultProps = { - value: '', - format: 'yy-mm-dd' - }; - - componentDidMount() { - this.attachDatePicker(); - } - - componentWillReceiveProps(nextProps) { - this.refs.input.value = nextProps.value; - } - - handleChange() { - const { value } = this.refs.input; - this.props.onChange(value); - } - - attachDatePicker() { - const opts = { - dateFormat: this.props.format, - changeMonth: true, - changeYear: true, - onSelect: this.handleChange.bind(this) - }; - - if ($.fn && $.fn.datepicker) { - $(this.refs.input).datepicker(opts); - } - } - - render() { - const inputProps = pick(this.props, ['placeholder', 'name']); - - /* eslint max-len: 0 */ - return ( - - - - - - - - - ); - } -} diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.tsx b/server/sonar-web/src/main/js/components/controls/DateInput.tsx new file mode 100644 index 00000000000..a1f4a4e70d9 --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx @@ -0,0 +1,92 @@ +/* + * 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 $ from 'jquery'; +import * as React from 'react'; +import * as classNames from 'classnames'; +import { pick } from 'lodash'; +import './styles.css'; + +interface Props { + className?: string; + value?: string; + format?: string; + name: string; + placeholder: string; + onChange: (value: string) => void; +} + +export default class DateInput extends React.PureComponent { + input: HTMLInputElement; + + static defaultProps = { + value: '', + format: 'yy-mm-dd' + }; + + componentDidMount() { + this.attachDatePicker(); + } + + componentWillReceiveProps(nextProps: Props) { + if (nextProps.value != null) { + this.input.value = nextProps.value; + } + } + + handleChange() { + const { value } = this.input; + this.props.onChange(value); + } + + attachDatePicker() { + const opts = { + dateFormat: this.props.format, + changeMonth: true, + changeYear: true, + onSelect: this.handleChange.bind(this) + }; + + if ($.fn && ($.fn as any).datepicker) { + ($(this.refs.input) as any).datepicker(opts); + } + } + + render() { + const inputProps = pick(this.props, ['placeholder', 'name']); + + return ( + + (this.input = node as HTMLInputElement)} + type="text" + defaultValue={this.props.value} + readOnly={true} + {...inputProps} + /> + + + + + + + ); + } +} diff --git a/server/sonar-web/src/main/js/components/controls/ListFooter.js b/server/sonar-web/src/main/js/components/controls/ListFooter.js deleted file mode 100644 index 24711f088db..00000000000 --- a/server/sonar-web/src/main/js/components/controls/ListFooter.js +++ /dev/null @@ -1,70 +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 classNames from 'classnames'; -import React from 'react'; -import PropTypes from 'prop-types'; -import { translate, translateWithParameters } from '../../helpers/l10n'; -import { formatMeasure } from '../../helpers/measures'; - -export default class ListFooter extends React.PureComponent { - static propTypes = { - count: PropTypes.number.isRequired, - total: PropTypes.number.isRequired, - loadMore: PropTypes.func, - ready: PropTypes.bool - }; - - static defaultProps = { - ready: true - }; - - canLoadMore() { - return typeof this.props.loadMore === 'function'; - } - - handleLoadMore = event => { - event.preventDefault(); - event.target.blur(); - this.props.loadMore(); - }; - - render() { - const hasMore = this.props.total > this.props.count; - const loadMoreLink = ( - - {translate('show_more')} - - ); - const className = classNames('spacer-top note text-center', { - 'new-loading': !this.props.ready - }); - - return ( -
    - {translateWithParameters( - 'x_of_y_shown', - formatMeasure(this.props.count, 'INT'), - formatMeasure(this.props.total, 'INT') - )} - {this.canLoadMore() && hasMore ? loadMoreLink : null} -
    - ); - } -} diff --git a/server/sonar-web/src/main/js/components/controls/ListFooter.tsx b/server/sonar-web/src/main/js/components/controls/ListFooter.tsx new file mode 100644 index 00000000000..7d5df6797d5 --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/ListFooter.tsx @@ -0,0 +1,61 @@ +/* + * 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 classNames from 'classnames'; +import { translate, translateWithParameters } from '../../helpers/l10n'; +import { formatMeasure } from '../../helpers/measures'; + +interface Props { + count: number; + loadMore?: () => void; + ready?: boolean; + total: number; +} + +export default function ListFooter({ ready = true, ...props }: Props) { + const handleLoadMore = (event: React.SyntheticEvent) => { + event.preventDefault(); + event.currentTarget.blur(); + if (props.loadMore) { + props.loadMore(); + } + }; + + const hasMore = props.total > props.count; + const loadMoreLink = ( + + {translate('show_more')} + + ); + const className = classNames('spacer-top note text-center', { + 'new-loading': !ready + }); + + return ( +
    + {translateWithParameters( + 'x_of_y_shown', + formatMeasure(props.count, 'INT', null), + formatMeasure(props.total, 'INT', null) + )} + {props.loadMore != null && hasMore ? loadMoreLink : null} +
    + ); +} diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.js b/server/sonar-web/src/main/js/components/controls/Tooltip.js deleted file mode 100644 index 68197750050..00000000000 --- a/server/sonar-web/src/main/js/components/controls/Tooltip.js +++ /dev/null @@ -1,39 +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 TooltipCore from 'rc-tooltip'; - -export default class Tooltip extends React.PureComponent { - /*:: props: { - placement?: string - }; -*/ - - static defaultProps = { - placement: 'bottom' - }; - - render() { - return ( - - ); - } -} diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx new file mode 100644 index 00000000000..f33a4f1677c --- /dev/null +++ b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx @@ -0,0 +1,35 @@ +/* + * 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 TooltipCore from 'rc-tooltip'; + +interface Props { + overlay: React.ReactNode; + placement?: string; + [attr: string]: any; +} + +export default function Tooltip(props: Props) { + return ; +} + +(Tooltip as React.StatelessComponent).defaultProps = { + placement: 'bottom' +}; diff --git a/server/sonar-web/src/main/js/components/icons-components/BugIcon.js b/server/sonar-web/src/main/js/components/icons-components/BugIcon.js deleted file mode 100644 index 48726f839d0..00000000000 --- a/server/sonar-web/src/main/js/components/icons-components/BugIcon.js +++ /dev/null @@ -1,42 +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'; - -/*:: -type Props = { className?: string, size?: number }; -*/ - -export default function BugIcon({ className, size = 16 } /*: Props */) { - /* eslint-disable max-len */ - return ( - - - - ); -} diff --git a/server/sonar-web/src/main/js/components/icons-components/BugIcon.tsx b/server/sonar-web/src/main/js/components/icons-components/BugIcon.tsx new file mode 100644 index 00000000000..eb5f504ecb8 --- /dev/null +++ b/server/sonar-web/src/main/js/components/icons-components/BugIcon.tsx @@ -0,0 +1,42 @@ +/* + * 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'; + +interface Props { + className?: string; + size?: number; +} + +export default function BugIcon({ className, size = 16 }: Props) { + /* eslint-disable max-len */ + return ( + + + + ); +} diff --git a/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.js b/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.js deleted file mode 100644 index 108e4203e75..00000000000 --- a/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.js +++ /dev/null @@ -1,42 +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'; - -/*:: -type Props = { className?: string, size?: number }; -*/ - -export default function CodeSmellIcon({ className, size = 16 } /*: Props */) { - /* eslint-disable max-len */ - return ( - - - - ); -} diff --git a/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.tsx b/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.tsx new file mode 100644 index 00000000000..767a69fd195 --- /dev/null +++ b/server/sonar-web/src/main/js/components/icons-components/CodeSmellIcon.tsx @@ -0,0 +1,42 @@ +/* + * 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'; + +interface Props { + className?: string; + size?: number; +} + +export default function CodeSmellIcon({ className, size = 16 }: Props) { + /* eslint-disable max-len */ + return ( + + + + ); +} diff --git a/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.js b/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.js deleted file mode 100644 index 1d3b5b18e26..00000000000 --- a/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.js +++ /dev/null @@ -1,42 +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'; - -/*:: -type Props = { className?: string, size?: number }; -*/ - -export default function VulnerabilityIcon({ className, size = 16 } /*: Props */) { - /* eslint-disable max-len */ - return ( - - - - ); -} diff --git a/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.tsx b/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.tsx new file mode 100644 index 00000000000..f0fbe93ef53 --- /dev/null +++ b/server/sonar-web/src/main/js/components/icons-components/VulnerabilityIcon.tsx @@ -0,0 +1,42 @@ +/* + * 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'; + +interface Props { + className?: string; + size?: number; +} + +export default function VulnerabilityIcon({ className, size = 16 }: Props) { + /* eslint-disable max-len */ + return ( + + + + ); +} diff --git a/server/sonar-web/src/main/js/components/shared/QualifierIcon.js b/server/sonar-web/src/main/js/components/shared/QualifierIcon.js deleted file mode 100644 index e00dc8ab41f..00000000000 --- a/server/sonar-web/src/main/js/components/shared/QualifierIcon.js +++ /dev/null @@ -1,45 +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 classNames from 'classnames'; - -/*:: -type Props = { - className?: string, - qualifier: ?string -}; -*/ - -export default class QualifierIcon extends React.PureComponent { - /*:: props: Props; */ - - render() { - if (!this.props.qualifier) { - return null; - } - - const className = classNames( - 'icon-qualifier-' + this.props.qualifier.toLowerCase(), - this.props.className - ); - - return ; - } -} diff --git a/server/sonar-web/src/main/js/components/shared/QualifierIcon.tsx b/server/sonar-web/src/main/js/components/shared/QualifierIcon.tsx new file mode 100644 index 00000000000..802d90c10d2 --- /dev/null +++ b/server/sonar-web/src/main/js/components/shared/QualifierIcon.tsx @@ -0,0 +1,36 @@ +/* + * 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 classNames from 'classnames'; + +interface Props { + className?: string; + qualifier: string | null; +} + +export default function QualifierIcon(props: Props) { + if (!props.qualifier) { + return null; + } + + const className = classNames('icon-qualifier-' + props.qualifier.toLowerCase(), props.className); + + return ; +} diff --git a/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js b/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js deleted file mode 100644 index 83feca0536e..00000000000 --- a/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js +++ /dev/null @@ -1,65 +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 BugIcon from '../icons-components/BugIcon'; -import VulnerabilityIcon from '../icons-components/VulnerabilityIcon'; -import CodeSmellIcon from '../icons-components/CodeSmellIcon'; - -export default class IssueTypeIcon extends React.PureComponent { - /*:: props: { - className?: string, - query: string - }; -*/ - - renderIcon() { - switch (this.props.query.toLowerCase()) { - case 'bug': - case 'bugs': - case 'new_bugs': - return ; - case 'vulnerability': - case 'vulnerabilities': - case 'new_vulnerabilities': - return ; - case 'code_smell': - case 'code_smells': - case 'new_code_smells': - return ; - default: - return null; - } - } - - render() { - const icon = this.renderIcon(); - - if (!icon) { - return null; - } - - return this.props.className - ? - {icon} - - : icon; - } -} diff --git a/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.tsx b/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.tsx new file mode 100644 index 00000000000..63aae3cc815 --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.tsx @@ -0,0 +1,60 @@ +/* + * 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 BugIcon from '../icons-components/BugIcon'; +import VulnerabilityIcon from '../icons-components/VulnerabilityIcon'; +import CodeSmellIcon from '../icons-components/CodeSmellIcon'; + +interface Props { + className?: string; + query: string; +} + +export default function IssueTypeIcon(props: Props) { + let icon; + + switch (props.query.toLowerCase()) { + case 'bug': + case 'bugs': + case 'new_bugs': + icon = ; + break; + case 'vulnerability': + case 'vulnerabilities': + case 'new_vulnerabilities': + icon = ; + break; + case 'code_smell': + case 'code_smells': + case 'new_code_smells': + icon = ; + break; + } + + if (!icon) { + return null; + } + + return props.className + ? + {icon} + + : icon; +} diff --git a/server/sonar-web/src/main/js/components/ui/Level.js b/server/sonar-web/src/main/js/components/ui/Level.js deleted file mode 100644 index 2ba079f1995..00000000000 --- a/server/sonar-web/src/main/js/components/ui/Level.js +++ /dev/null @@ -1,51 +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 classNames from 'classnames'; -import { formatMeasure } from '../../helpers/measures'; -import './Level.css'; - -export default class Level extends React.PureComponent { - static propTypes = { - className: PropTypes.string, - level: PropTypes.oneOf(['ERROR', 'WARN', 'OK', 'NONE']).isRequired, - small: PropTypes.bool, - muted: PropTypes.bool - }; - - static defaultProps = { - small: false, - muted: false - }; - - render() { - const formatted = formatMeasure(this.props.level, 'LEVEL'); - const className = classNames(this.props.className, 'level', 'level-' + this.props.level, { - 'level-small': this.props.small, - 'level-muted': this.props.muted - }); - return ( - - {formatted} - - ); - } -} diff --git a/server/sonar-web/src/main/js/components/ui/Level.tsx b/server/sonar-web/src/main/js/components/ui/Level.tsx new file mode 100644 index 00000000000..b5495695578 --- /dev/null +++ b/server/sonar-web/src/main/js/components/ui/Level.tsx @@ -0,0 +1,43 @@ +/* + * 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 classNames from 'classnames'; +import { formatMeasure } from '../../helpers/measures'; +import './Level.css'; + +interface Props { + className?: string; + level: string; + small?: boolean; + muted?: boolean; +} + +export default function Level(props: Props) { + const formatted = formatMeasure(props.level, 'LEVEL', null); + const className = classNames(props.className, 'level', 'level-' + props.level, { + 'level-small': props.small, + 'level-muted': props.muted + }); + return ( + + {formatted} + + ); +} diff --git a/server/sonar-web/src/main/js/typings/rc-tooltip.d.ts b/server/sonar-web/src/main/js/typings/rc-tooltip.d.ts new file mode 100644 index 00000000000..b10195eca40 --- /dev/null +++ b/server/sonar-web/src/main/js/typings/rc-tooltip.d.ts @@ -0,0 +1,54 @@ +/* + * 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. + */ +declare module 'rc-tooltip' { + export type Trigger = 'hover' | 'click' | 'focus'; + export type Placement = + | 'left' + | 'right' + | 'top' + | 'bottom' + | 'topLeft' + | 'topRight' + | 'bottomLeft' + | 'bottomRight'; + + export interface Props extends React.Props { + overlayClassName?: string; + trigger?: Trigger[]; + mouseEnterDelay?: number; + mouseLeaveDelay?: number; + overlayStyle?: React.CSSProperties; + prefixCls?: string; + transitionName?: string; + onVisibleChange?: () => void; + visible?: boolean; + defaultVisible?: boolean; + placement?: Placement | Object; + align?: Object; + onPopupAlign?: (popupDomNode: Element, align: Object) => void; + overlay: React.ReactNode; + arrowContent?: React.ReactNode; + getTooltipContainer?: () => Element; + destroyTooltipOnHide?: boolean; + } + + // the next line is crucial, it is absent in the original typings + export default class Tooltip extends React.Component {} +} diff --git a/server/sonar-web/tsconfig.json b/server/sonar-web/tsconfig.json index 6f5b468c4b0..427192d12e7 100644 --- a/server/sonar-web/tsconfig.json +++ b/server/sonar-web/tsconfig.json @@ -9,7 +9,7 @@ "target": "es5", "jsx": "react", "lib": ["es2017", "dom"], - "module": "es2015", + "module": "esnext", "moduleResolution": "node", "typeRoots": ["./src/main/js/typings", "./node_modules/@types"] }, diff --git a/server/sonar-web/yarn.lock b/server/sonar-web/yarn.lock index 75d358da6cb..b3a14ca74f1 100644 --- a/server/sonar-web/yarn.lock +++ b/server/sonar-web/yarn.lock @@ -24,6 +24,10 @@ "@types/cheerio" "*" "@types/react" "*" +"@types/escape-html@0.0.19": + version "0.0.19" + resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-0.0.19.tgz#595ff7bd7ee510af54517819de24abdcea6f3507" + "@types/history@^3": version "3.2.1" resolved "https://registry.yarnpkg.com/@types/history/-/history-3.2.1.tgz#0039ab0e0be2a0cc22bac171d27a44588103d123" @@ -32,6 +36,10 @@ version "20.0.7" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-20.0.7.tgz#39cd215db8bda03928dceb933a1e63eb2cbd210e" +"@types/jquery@3.2.11": + version "3.2.11" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.2.11.tgz#9119f91bb103b16ae8c4375b019a9b341b409f50" + "@types/lodash@4.14.73": version "4.14.73" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.73.tgz#9837e47db8643ba5bcef2c7921f37d90f9c24213" @@ -51,6 +59,18 @@ "@types/node" "*" "@types/react" "*" +"@types/react-helmet@5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-5.0.3.tgz#614e706cb73120936c7c067404809f8c2f1a840c" + dependencies: + "@types/react" "*" + +"@types/react-modal@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-2.2.0.tgz#e92bb8454e53030581f263e3fb7e7d27e3eb85b8" + dependencies: + "@types/react" "*" + "@types/react-redux@5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-5.0.3.tgz#cd68de0c49c516b940fdc6f688535596b5d6eca4" @@ -65,6 +85,12 @@ "@types/history" "^3" "@types/react" "*" +"@types/react-select@1.0.51": + version "1.0.51" + resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-1.0.51.tgz#47e7787b068c34395251e95a0981cff8034eddcc" + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@16.0.2": version "16.0.2" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.2.tgz#0b31a73cdde6272b719e5b05a7df6d1e2654a804"