From 71d4a992b83b41c2b4fa6dc8456584ee8c3324ef Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Fri, 11 Nov 2016 15:28:22 +0100 Subject: [PATCH] SONAR-8382 Create landing page for anonymous users --- server/sonar-web/src/main/js/api/auth.js | 38 ++++ server/sonar-web/src/main/js/app/index.js | 2 + .../main/js/apps/about/components/AboutApp.js | 134 +++++++++++++ .../apps/about/components/AboutCleanCode.js | 42 ++++ .../js/apps/about/components/AboutIssues.js | 77 ++++++++ .../apps/about/components/AboutLeakPeriod.js | 47 +++++ .../js/apps/about/components/AboutProjects.js | 43 +++++ .../about/components/AboutQualityGates.js | 47 +++++ .../js/apps/about/components/AboutScanners.js | 135 +++++++++++++ .../apps/about/components/AboutStandards.js | 46 +++++ .../js/apps/about/components/DropImage.js | 36 ++++ .../main/js/apps/about/components/IconLock.js | 29 +++ .../js/apps/about/components/LoginForm.js | 81 ++++++++ .../js/apps/about/components/LoginSection.js | 47 +++++ .../apps/about/components/OAuthProvider.css | 28 +++ .../js/apps/about/components/OAuthProvider.js | 46 +++++ .../src/main/js/apps/about/routes.js | 26 +++ .../src/main/js/apps/about/styles.css | 179 ++++++++++++++++++ server/sonar-web/src/main/js/helpers/urls.js | 2 +- server/sonar-web/src/main/js/main/app.js | 2 + .../js/main/nav/global/global-nav-branding.js | 2 +- .../main/nav/templates/nav-shortcuts-help.hbs | 1 + .../app/controllers/about_controller.rb | 27 +++ .../app/controllers/dashboard_controller.rb | 50 ++--- .../app/controllers/landing_controller.rb | 31 +++ .../WEB-INF/app/views/about/index.html.erb | 18 ++ .../app/views/layouts/_layout.html.erb | 1 + .../src/main/webapp/WEB-INF/config/routes.rb | 4 +- .../webapp/images/recognized-standards.svg | 26 +++ .../main/webapp/images/scanner-logos/ant.svg | 8 + .../webapp/images/scanner-logos/gradle.svg | 10 + .../webapp/images/scanner-logos/jenkins.svg | 46 +++++ .../webapp/images/scanner-logos/maven.svg | 7 + .../webapp/images/scanner-logos/msbuild.svg | 3 + .../webapp/images/scanner-logos/sonarqube.svg | 7 + .../images/understanding-leak-period.svg | 13 ++ .../images/understanding-quality-gates.svg | 17 ++ 37 files changed, 1325 insertions(+), 33 deletions(-) create mode 100644 server/sonar-web/src/main/js/api/auth.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutApp.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutIssues.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutProjects.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutScanners.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/AboutStandards.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/DropImage.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/IconLock.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/LoginForm.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/LoginSection.js create mode 100644 server/sonar-web/src/main/js/apps/about/components/OAuthProvider.css create mode 100644 server/sonar-web/src/main/js/apps/about/components/OAuthProvider.js create mode 100644 server/sonar-web/src/main/js/apps/about/routes.js create mode 100644 server/sonar-web/src/main/js/apps/about/styles.css create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/controllers/about_controller.rb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/controllers/landing_controller.rb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/about/index.html.erb create mode 100644 server/sonar-web/src/main/webapp/images/recognized-standards.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/ant.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/gradle.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/jenkins.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/maven.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/msbuild.svg create mode 100644 server/sonar-web/src/main/webapp/images/scanner-logos/sonarqube.svg create mode 100644 server/sonar-web/src/main/webapp/images/understanding-leak-period.svg create mode 100644 server/sonar-web/src/main/webapp/images/understanding-quality-gates.svg diff --git a/server/sonar-web/src/main/js/api/auth.js b/server/sonar-web/src/main/js/api/auth.js new file mode 100644 index 00000000000..064ca296aaf --- /dev/null +++ b/server/sonar-web/src/main/js/api/auth.js @@ -0,0 +1,38 @@ +/* + * 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. + */ +import { request } from '../helpers/request'; + +const basicCheckStatus = response => { + if (response.status >= 200 && response.status < 300) { + return response; + } else { + const error = new Error(response.status); + error.response = response; + throw error; + } +}; + +export const login = (login, password) => ( + request('/api/authentication/login') + .setMethod('POST') + .setData({ login, password }) + .submit() + .then(basicCheckStatus) +); diff --git a/server/sonar-web/src/main/js/app/index.js b/server/sonar-web/src/main/js/app/index.js index 84268cf4861..3ed7485fed3 100644 --- a/server/sonar-web/src/main/js/app/index.js +++ b/server/sonar-web/src/main/js/app/index.js @@ -23,6 +23,7 @@ import { Router, Route, useRouterHistory } from 'react-router'; import { createHistory } from 'history'; import { Provider } from 'react-redux'; import App from './components/App'; +import aboutRoutes from '../apps/about/routes'; import accountRoutes from '../apps/account/routes'; import projectsRoutes from '../apps/projects/routes'; import qualityGatesRoutes from '../apps/quality-gates/routes'; @@ -44,6 +45,7 @@ window.sonarqube.appStarted.then(options => { + {aboutRoutes} {accountRoutes} {projectsRoutes} {qualityGatesRoutes} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js new file mode 100644 index 00000000000..bc4c24d3c7c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js @@ -0,0 +1,134 @@ +/* + * 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. + */ +import React from 'react'; +import keyBy from 'lodash/keyBy'; +import LoginSection from './LoginSection'; +import LoginForm from './LoginForm'; +import AboutProjects from './AboutProjects'; +import AboutCleanCode from './AboutCleanCode'; +import AboutIssues from './AboutIssues'; +import AboutQualityGates from './AboutQualityGates'; +import AboutLeakPeriod from './AboutLeakPeriod'; +import AboutStandards from './AboutStandards'; +import AboutScanners from './AboutScanners'; +import { translate } from '../../../helpers/l10n'; +import '../styles.css'; +import { searchProjects } from '../../../api/components'; +import { getFacet } from '../../../api/issues'; + +export default class AboutApp extends React.Component { + state = { + loading: true + }; + + componentDidMount () { + this.mounted = true; + this.loadData(); + } + + componentWillUnmount () { + this.mounted = false; + } + + loadProjects () { + return searchProjects({ ps: 1 }).then(r => r.paging.total); + } + + loadIssues () { + return getFacet({ resolved: false }, 'types').then(r => keyBy(r.facet, 'val')); + } + + loadData () { + Promise.all([ + window.sonarqube.appStarted, + this.loadProjects(), + this.loadIssues() + ]).then(responses => { + if (this.mounted) { + const [options, projectsCount, issueTypes] = responses; + this.setState({ + projectsCount, + issueTypes, + logoUrl: options.logoUrl, + logoWidth: options.logoWidth, + loading: false + }); + } + }); + } + + render () { + if (this.state.loading) { + return null; + } + + const isAuthenticated = !!window.SS.user; + const { signUpAllowed } = window.sonarqube; + const loginFormShown = !isAuthenticated && this.props.location.query.login !== undefined; + + const logoUrl = this.state.logoUrl || `${window.baseUrl}/images/logo.svg`; + const logoWidth = this.state.logoWidth || 100; + const logoHeight = 30; + const logoTitle = this.state.logoUrl ? '' : translate('layout.sonar.slogan'); + + return ( +
+
+ +
+ {logoTitle}/ +
+ + {loginFormShown ? ( +
+ +
+ ) : ( +
+ + {!isAuthenticated && } +
+ )} + + {signUpAllowed && ( +
+ No account yet? Sign up +
+ )} +
+ + + + + + + + + + + + +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js new file mode 100644 index 00000000000..1da76b6945e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js @@ -0,0 +1,42 @@ +/* + * 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. + */ +import React from 'react'; +import DropImage from './DropImage'; + +export default class AboutCleanCode extends React.Component { + render () { + return ( +
+
+

Keep your code clean by fixing the leak

+

+ By fixing new issues as they appear in code, you create and maintain a clean code base. +
+ Even on legacy projects, focusing on keeping new code clean will eventually yield a code base you can be + proud of. +

+
+ +
+
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js b/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js new file mode 100644 index 00000000000..d097d4bca08 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js @@ -0,0 +1,77 @@ +/* + * 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. + */ +import React from 'react'; +import { formatMeasure } from '../../../helpers/measures'; +import { getIssuesUrl } from '../../../helpers/urls'; + +export default class AboutIssues extends React.Component { + static propTypes = { + bugs: React.PropTypes.number.isRequired, + vulnerabilities: React.PropTypes.number.isRequired, + codeSmells: React.PropTypes.number.isRequired + }; + + render () { + return ( +
+
+

Track incoming issues using the SonarQube Quality Model

+
+
+ + {formatMeasure(this.props.bugs, 'SHORT_INT')} + +
+

Bugs

+

+ Bugs track code that is demonstrably wrong or highly likely to be yielding unexpected behavior. +

+
+
+
+ + {formatMeasure(this.props.vulnerabilities, 'SHORT_INT')} + +
+

Vulnerabilities

+

+ Vulnerabilities are raised on code that potentially vulnerable to exploitation by hackers. +

+
+
+
+ + {formatMeasure(this.props.codeSmells, 'SHORT_INT')} + +
+

Code Smells

+

+ Code Smells will confuse maintainers or give them pause. They are measured primarily in terms of + the time they will take to fix. +

+
+
+
+
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js new file mode 100644 index 00000000000..47d4a029604 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js @@ -0,0 +1,47 @@ +/* + * 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. + */ +import React from 'react'; + +const link = 'http://docs.sonarqube.org/display/HOME/Fixing+the+Water+Leak'; + +export default class AboutLeakPeriod extends React.Component { + render () { + return ( +
+
+ Understanding the Leak Period +

Understanding the Leak Period

+

+ The leak metaphor and the default Quality Gate are based on the leak period - the recent period against + which you're tracking issues. For some previous_version makes the most sense, for others + the last 30 days is a good option. +

+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js new file mode 100644 index 00000000000..d79982b5c8a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js @@ -0,0 +1,43 @@ +/* + * 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. + */ +import React from 'react'; +import { Link } from 'react-router'; +import { formatMeasure } from '../../../helpers/measures'; + +export default class AboutProjects extends React.Component { + static propTypes = { + count: React.PropTypes.number.isRequired + }; + + render () { + const { count } = this.props; + const label = count > 1 ? `${formatMeasure(count, 'INT')} projects` : '1 project'; + + return ( +
+ {count > 0 ? ( + {label} + ) : 'Put your projects'} + {' '} + under continuous
code quality management +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js new file mode 100644 index 00000000000..843403b049d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js @@ -0,0 +1,47 @@ +/* + * 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. + */ +import React from 'react'; + +const link = 'http://docs.sonarqube.org/display/SONAR/Quality+Gates'; + +export default class AboutQualityGates extends React.Component { + render () { + return ( +
+
+ Understanding Quality Gates +

Understanding Quality Gates

+

+ Your project's quality gate is the set of conditions the project must meet before it can be released + into production. The quality gate is designed to ensure that the next version's quality will be better + than the last. +

+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js new file mode 100644 index 00000000000..2ae938b32ca --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js @@ -0,0 +1,135 @@ +/* + * 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. + */ +import React from 'react'; + +const links = { + sonarqube: 'http://redirect.sonarsource.com/doc/install-configure-scanner.html', + msbuild: 'http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html', + maven: 'http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html', + gradle: 'http://redirect.sonarsource.com/doc/gradle.html', + jenkins: 'http://redirect.sonarsource.com/plugins/jenkins.html', + ant: 'http://redirect.sonarsource.com/doc/install-configure-scanner-ant.html' +}; + +export default class AboutScanners extends React.Component { + render () { + return ( +
+
+

Start analyzing your projects with a SonarQube Scanner

+
+
+
+ SonarQube Scanner +
+

+ This Java-based command-line tool can analyze any languages SonarQube supports. +

+ +
+
+
+ SonarQube Scanner for MSBuild +
+

+ Built in collaboration with Microsoft this is the recommended way to launch a SonarQube analysis on + MSBuild projects and solutions. +

+ +
+
+
+ SonarQube Scanner for Maven +
+

+ Using the SonarQube Scanner for Maven is as simple as running mvn sonar:sonar on your + Maven project. +

+ +
+
+
+ SonarQube Scanner for Gradle +
+

+ The SonarQube Scanner for Gradle provides an easy way to start analysis of a Gradle project. +

+ +
+
+
+ SonarQube Scanner for Jenkins +
+

+ The SonarQube Scanner for Jenkins lets you integrate analysis seamlessly into a job or a pipeline. +

+ +
+
+
+ SonarQube Scanner for Ant +
+

+ The SonarQube Scanner for Ant lets you start an analysis directly from an Apache Ant script. +

+ +
+
+
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js new file mode 100644 index 00000000000..874ee4ee671 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js @@ -0,0 +1,46 @@ +/* + * 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. + */ +import React from 'react'; + +const link = 'http://docs.sonarqube.org/display/SONAR/Rules'; + +export default class AboutStandards extends React.Component { + render () { + return ( +
+
+ Conform to recognized standards +

Conform to recognized standards

+

+ SonarAnalyzers offer rules that support industry standards: MISRA, CERT, CWE, OWASP Top 10 and SANS Top + 25. Configure your Quality Profile with standard-related rules to ensure adherence. +

+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/DropImage.js b/server/sonar-web/src/main/js/apps/about/components/DropImage.js new file mode 100644 index 00000000000..63ef476e87b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/DropImage.js @@ -0,0 +1,36 @@ +/* + * 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. + */ +import React from 'react'; + +export default function () { + /* eslint-disable max-len */ + return ( + + + + + + + + + + + ); +} diff --git a/server/sonar-web/src/main/js/apps/about/components/IconLock.js b/server/sonar-web/src/main/js/apps/about/components/IconLock.js new file mode 100644 index 00000000000..fbdc836fad9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/IconLock.js @@ -0,0 +1,29 @@ +/* + * 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. + */ +import React from 'react'; + +export default function () { + /* eslint-disable max-len */ + return ( + + + + ); +} diff --git a/server/sonar-web/src/main/js/apps/about/components/LoginForm.js b/server/sonar-web/src/main/js/apps/about/components/LoginForm.js new file mode 100644 index 00000000000..631959f8ec0 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/LoginForm.js @@ -0,0 +1,81 @@ +/* + * 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. + */ +import React from 'react'; +import { Link } from 'react-router'; +import { translate } from '../../../helpers/l10n'; +import { login } from '../../../api/auth'; + +export default class LoginForm extends React.Component { + state = { + login: '', + password: '', + error: false + }; + + handleLogin = () => { + this.setState({ error: false }); + window.location = window.baseUrl + '/projects/favorite'; + }; + + handleFailedLogin = () => { + this.setState({ error: true }); + }; + + handleSubmit = e => { + e.preventDefault(); + login(this.state.login, this.state.password) + .then(this.handleLogin, this.handleFailedLogin); + }; + + render () { + return ( +
+

Log In to SonarQube

+ + {this.state.error && ( +
+ {translate('session.flash_notice.authentication_failed')} +
+ )} + +
+ + this.setState({ login: e.target.value })}/> +
+ +
+ + this.setState({ password: e.target.value })}/> +
+ +
+ + Cancel +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/LoginSection.js b/server/sonar-web/src/main/js/apps/about/components/LoginSection.js new file mode 100644 index 00000000000..43942c7cb09 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/LoginSection.js @@ -0,0 +1,47 @@ +/* + * 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. + */ +import React from 'react'; +import { Link } from 'react-router'; +import OAuthProvider from './OAuthProvider'; +import IconLock from './IconLock'; + +export default class LoginSection extends React.Component { + render () { + const { authProviders } = window.sonarqube; + + const loginWithSonarQubeLabel = authProviders.length ? 'Log in with SonarQube' : 'Log in'; + + return ( +
+
+ {authProviders.map(provider => ( + + ))} + + + + {loginWithSonarQubeLabel} + +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.css b/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.css new file mode 100644 index 00000000000..5bd25619460 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.css @@ -0,0 +1,28 @@ +.oauth-provider { + display: block; + width: 180px; + line-height: 22px; + padding: 8px 12px; + border: none; + border-radius: 2px; + box-sizing: border-box; + background-color: #236a97; + color: #fff; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.oauth-provider:hover, +.oauth-provider:focus { + color: #fff; + box-shadow: inset 0 0 16px rgba(0, 0, 0, 0.3); +} + +.oauth-provider > span { + padding-left: 6px; +} + +.oauth-provider-sonarqube { + background-color: #4b9fd5; +} diff --git a/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.js b/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.js new file mode 100644 index 00000000000..1ae53658a2b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/OAuthProvider.js @@ -0,0 +1,46 @@ +/* + * 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. + */ +import React from 'react'; +import './OAuthProvider.css'; + +export default class OAuthProvider extends React.Component { + static propTypes = { + provider: React.PropTypes.shape({ + key: React.PropTypes.string.isRequired, + name: React.PropTypes.string.isRequired, + iconPath: React.PropTypes.string.isRequired, + backgroundColor: React.PropTypes.string.isRequired + }).isRequired + }; + + render () { + const { key, name, iconPath, backgroundColor } = this.props.provider; + + const url = window.baseUrl + '/sessions/init/' + key; + const label = 'Log in with ' + name; + + return ( + + {name} + {label} + + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/routes.js b/server/sonar-web/src/main/js/apps/about/routes.js new file mode 100644 index 00000000000..e59902394ab --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/routes.js @@ -0,0 +1,26 @@ +/* + * 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. + */ +import React from 'react'; +import { IndexRoute } from 'react-router'; +import AboutApp from './components/AboutApp'; + +export default ( + +); diff --git a/server/sonar-web/src/main/js/apps/about/styles.css b/server/sonar-web/src/main/js/apps/about/styles.css new file mode 100644 index 00000000000..cd6953ee9c5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/styles.css @@ -0,0 +1,179 @@ +.about-page { +} + +.about-page-container { + position: relative; + width: 1080px; + margin-left: auto; + margin-right: auto; +} + +.about-page-center-container { + position: relative; + width: 640px; + margin: 0 auto; + text-align: center; +} + +.about-page-container .pull-left { + margin-right: 40px; +} + +.about-page-container .pull-right { + margin-left: 40px; +} + +.about-page-logo { + margin-bottom: 30px; +} + +.about-page-entry { + padding: 75px 0; + background-color: #363636; + text-align: center; +} + +.about-page-entry .alert { + font-size: 13px; +} + +.about-page-entry-box { + width: 320px; + margin-left: auto; + margin-right: auto; + padding: 40px 30px; + box-sizing: border-box; + border-radius: 2px; + background-color: #fff; +} + +.about-login-form-header { + margin-bottom: 30px; + font-size: 18px; + font-weight: bold; +} + +.about-page-sign-up { + margin-top: 20px; + color: rgba(255, 255, 255, 0.7); +} + +.about-page-sign-up a { + color: #4b9fd5; + border-color: #4b9fd5; +} + +.about-page-auth-providers { +} + +.about-page-auth-providers .oauth-provider { + width: 100%; + margin-top: 20px; +} + +.about-page-section { + padding-top: 80px; + padding-bottom: 80px; +} + +.about-page-section-gray { + border-top: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + background-color: #f3f3f3; +} + +.about-page-section-image { + position: absolute; + z-index: 5; + top: -80px; + right: 100%; +} + +.about-page-center-container .about-page-section-image { + right: auto; + left: -210px; +} + +.about-page-header { + line-height: 1; + margin-bottom: 30px; + font-size: 28px; + font-weight: bold; +} + +.about-page-text { + line-height: 1.5; + font-size: 15px; +} + +.about-page-link-more { + border: none; +} + +.about-page-link-more > span { + border-bottom: 1px solid #cae3f2; +} + +.about-page-issues { + display: flex; + justify-content: space-around; + margin-top: 80px; +} + +.about-page-issues-box { + width: 280px; + text-align: center; +} + +.about-page-issues-number { + display: block; + border: none; + padding: 20px 0; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + background-color: #4b9fd5; + color: #fff; + font-size: 50px; + font-weight: bold; +} + +.about-page-issues-number:hover { + background-color: #236a97; + color: #fff; +} + +.about-page-issues-number:focus { + color: #fff; +} + +.about-page-issues-description { + min-height: 120px; + padding: 25px 20px 25px; + border: 1px solid #e6e6e6; + border-top: none; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + background-color: #fff; +} + +.about-page-issues-header { + margin-bottom: 20px; + font-size: 21px; + text-transform: uppercase; +} + +.about-page-issues-text { + line-height: 1.3; + font-size: 14px; +} + +.about-page-analyzers { + display: flex; + justify-content: space-around; + flex-wrap: wrap; +} + +.about-page-analyzer-box { + width: 280px; + margin-top: 80px; +} diff --git a/server/sonar-web/src/main/js/helpers/urls.js b/server/sonar-web/src/main/js/helpers/urls.js index 894d9e1e257..16da020a96b 100644 --- a/server/sonar-web/src/main/js/helpers/urls.js +++ b/server/sonar-web/src/main/js/helpers/urls.js @@ -35,7 +35,7 @@ export function getIssuesUrl (query) { const serializedQuery = Object.keys(query).map(criterion => ( `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}` )).join('|'); - return window.baseUrl + '/issues/search#' + serializedQuery; + return window.baseUrl + '/issues#' + serializedQuery; } /** diff --git a/server/sonar-web/src/main/js/main/app.js b/server/sonar-web/src/main/js/main/app.js index fecb0b26e47..0fe3aa0765b 100644 --- a/server/sonar-web/src/main/js/main/app.js +++ b/server/sonar-web/src/main/js/main/app.js @@ -54,6 +54,8 @@ function prepareAppOptions (navResponse) { const appOptions = { el: '#content' }; if (navResponse) { appOptions.rootQualifiers = navResponse.global.qualifiers; + appOptions.logoUrl = navResponse.global.logoUrl; + appOptions.logoWidth = navResponse.global.logoWidth; if (navResponse.component) { appOptions.component = { id: navResponse.component.uuid, diff --git a/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js index 2c33fea9724..88a8b038bb7 100644 --- a/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js @@ -34,7 +34,7 @@ export default React.createClass({ }, render() { - const homeController = window.SS.user ? '/projects/favorite' : '/projects'; + const homeController = window.SS.user ? '/projects/favorite' : '/about'; const homeUrl = window.baseUrl + homeController; const homeLinkClassName = 'navbar-brand' + (this.props.logoUrl ? ' navbar-brand-custom' : ''); return ( diff --git a/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs b/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs index 22356c886e4..bb29bf9597b 100644 --- a/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs +++ b/server/sonar-web/src/main/js/main/nav/templates/nav-shortcuts-help.hbs @@ -8,6 +8,7 @@ Documentation - Get Support - Plugins - + About - Web API diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/about_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/about_controller.rb new file mode 100644 index 00000000000..5fcb51d0469 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/about_controller.rb @@ -0,0 +1,27 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# SonarQube is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +class AboutController < ApplicationController + + def index + + end + +end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb index 4538745baea..de4577c9110 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb @@ -23,40 +23,32 @@ class DashboardController < ApplicationController SECTION=Navigation::SECTION_RESOURCE def index - if params[:id] - @resource = Project.by_key(params[:id]) - return project_not_found unless @resource - @resource = @resource.permanent_resource + @resource = Project.by_key(params[:id]) + return project_not_found unless @resource + @resource = @resource.permanent_resource - access_denied unless has_role?(:user, @resource) + access_denied unless has_role?(:user, @resource) - # for backward compatibility with old widgets - @project = @resource + # for backward compatibility with old widgets + @project = @resource - # if file - if !@resource.display_dashboard? - @snapshot = @resource.last_snapshot - return project_not_analyzed unless @snapshot - @hide_sidebar = true - @file = @resource - @project = @resource.root_project - @metric=params[:metric] - render :action => 'no_dashboard' - else - # it is a project dashboard - # if governance plugin is installed and we are opening a view - if Project.root_qualifiers.include?('VW') && (@resource.qualifier == 'VW' || @resource.qualifier == 'SVW') - return redirect_to(url_for({:controller => 'governance'}) + '?id=' + url_encode(params[:id])) - else - @snapshot = @resource.last_snapshot - render :action => 'overview' - end - end + # if file + if !@resource.display_dashboard? + @snapshot = @resource.last_snapshot + return project_not_analyzed unless @snapshot + @hide_sidebar = true + @file = @resource + @project = @resource.root_project + @metric=params[:metric] + render :action => 'no_dashboard' else - if logged_in? - return redirect_to :controller => 'projects', :action => 'favorite' + # it is a project dashboard + # if governance plugin is installed and we are opening a view + if Project.root_qualifiers.include?('VW') && (@resource.qualifier == 'VW' || @resource.qualifier == 'SVW') + return redirect_to(url_for({:controller => 'governance'}) + '?id=' + url_encode(params[:id])) else - return redirect_to :controller => 'projects' + @snapshot = @resource.last_snapshot + render :action => 'overview' end end end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/landing_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/landing_controller.rb new file mode 100644 index 00000000000..878e8669742 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/landing_controller.rb @@ -0,0 +1,31 @@ +# +# SonarQube, open source software quality management tool. +# Copyright (C) 2008-2014 SonarSource +# mailto:contact AT sonarsource DOT com +# +# SonarQube is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# SonarQube is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +class LandingController < ApplicationController + + def index + if logged_in? + return redirect_to :controller => 'projects', :action => 'favorite' + else + return redirect_to :controller => 'about' + end + end + +end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/about/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/about/index.html.erb new file mode 100644 index 00000000000..5a7fb782123 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/about/index.html.erb @@ -0,0 +1,18 @@ +<% content_for :extra_script do %> + + +<% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 1a2672d9fec..15022ecb49e 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -56,6 +56,7 @@ Documentation - Get Support - Plugins - + About - Web API diff --git a/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb b/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb index 1af5e16edac..a62b6c7af3c 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb @@ -14,8 +14,8 @@ ActionController::Routing::Routes.draw do |map| map.resources 'properties', :path_prefix => 'api', :controller => 'api/properties', :requirements => { :id => /.*/ } # home page - map.home '', :controller => :dashboard, :action => :index - map.root :controller => :dashboard, :action => :index + map.home '', :controller => :landing, :action => :index + map.root :controller => :landing, :action => :index # page plugins map.connect 'plugins/configuration/:page', :controller => 'plugins/configuration', :action => 'index', :requirements => { :page => /.*/ } diff --git a/server/sonar-web/src/main/webapp/images/recognized-standards.svg b/server/sonar-web/src/main/webapp/images/recognized-standards.svg new file mode 100644 index 00000000000..c1908368144 --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/recognized-standards.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/ant.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/ant.svg new file mode 100644 index 00000000000..697ae4dc56a --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/ant.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/gradle.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/gradle.svg new file mode 100644 index 00000000000..0d178e1acc3 --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/gradle.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/jenkins.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/jenkins.svg new file mode 100644 index 00000000000..284455cf12a --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/jenkins.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jenkins + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/maven.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/maven.svg new file mode 100644 index 00000000000..9f7fcaa9f76 --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/maven.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/msbuild.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/msbuild.svg new file mode 100644 index 00000000000..a48d84f7c6a --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/msbuild.svg @@ -0,0 +1,3 @@ + + + diff --git a/server/sonar-web/src/main/webapp/images/scanner-logos/sonarqube.svg b/server/sonar-web/src/main/webapp/images/scanner-logos/sonarqube.svg new file mode 100644 index 00000000000..f0650ba552f --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/scanner-logos/sonarqube.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/understanding-leak-period.svg b/server/sonar-web/src/main/webapp/images/understanding-leak-period.svg new file mode 100644 index 00000000000..69b9ff076d7 --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/understanding-leak-period.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/server/sonar-web/src/main/webapp/images/understanding-quality-gates.svg b/server/sonar-web/src/main/webapp/images/understanding-quality-gates.svg new file mode 100644 index 00000000000..2b8322ba7a4 --- /dev/null +++ b/server/sonar-web/src/main/webapp/images/understanding-quality-gates.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + -- 2.39.5