diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2017-02-07 16:19:54 +0100 |
---|---|---|
committer | Stas Vilchik <stas-vilchik@users.noreply.github.com> | 2017-02-08 16:25:16 +0100 |
commit | 6d40de520d8927f6d2b9da67b427e8b589075fe4 (patch) | |
tree | 064fd6e81877fe17efa31c05b1f516e0e9c6bdb0 /server/sonar-web/src/main/js | |
parent | 21a188aad134c69739b5f9dce43f0981580721ac (diff) | |
download | sonarqube-6d40de520d8927f6d2b9da67b427e8b589075fe4.tar.gz sonarqube-6d40de520d8927f6d2b9da67b427e8b589075fe4.zip |
SONAR-8749 Update landing page
Diffstat (limited to 'server/sonar-web/src/main/js')
10 files changed, 268 insertions, 148 deletions
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 index 542056a1329..21db6186dee 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js @@ -17,42 +17,55 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +// @flow import React from 'react'; import { connect } from 'react-redux'; import keyBy from 'lodash/keyBy'; +import { Link } from 'react-router'; import AboutProjects from './AboutProjects'; import EntryIssueTypes from './EntryIssueTypes'; +import AboutLanguages from './AboutLanguages'; import AboutCleanCode from './AboutCleanCode'; -import AboutIssues from './AboutIssues'; +import AboutQualityModel from './AboutQualityModel'; import AboutQualityGates from './AboutQualityGates'; import AboutLeakPeriod from './AboutLeakPeriod'; import AboutStandards from './AboutStandards'; import AboutScanners from './AboutScanners'; -import { translate } from '../../../helpers/l10n'; import { searchProjects } from '../../../api/components'; import { getFacet } from '../../../api/issues'; -import { getSettingValue } from '../../../store/rootReducer'; import * as settingsAPI from '../../../api/settings'; +import { getCurrentUser } from '../../../store/rootReducer'; import '../styles.css'; +import { translate } from '../../../helpers/l10n'; + +type State = { + loading: boolean, + projectsCount?: number, + issueTypes?: { + [key: string]: { + count: number + } + }, + customText?: string +}; class AboutApp extends React.Component { - static propTypes = { - customLogoUrl: React.PropTypes.string, - customLogoWidth: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) + mounted: boolean; + + props: { + currentUser: { isLoggedIn: boolean } }; - state = { + state: State = { loading: true }; componentDidMount () { this.mounted = true; - document.querySelector('html').classList.add('dashboard-page'); this.loadData(); } componentWillUnmount () { - document.querySelector('html').classList.remove('dashboard-page'); this.mounted = false; } @@ -94,47 +107,51 @@ class AboutApp extends React.Component { const { customText } = this.state; - const logoUrl = this.props.customLogoUrl || `${window.baseUrl}/images/logo.svg`; - const logoWidth = Number(this.props.customLogoWidth || 100); - const logoHeight = 30; - const logoTitle = this.props.customLogoUrl ? '' : translate('layout.sonar.slogan'); + // $FlowFixMe + const bugs = this.state.issueTypes['BUG'].count; + // $FlowFixMe + const vulnerabilities = this.state.issueTypes['VULNERABILITY'].count; + // $FlowFixMe + const codeSmells = this.state.issueTypes['CODE_SMELL'].count; return ( <div id="about-page" className="about-page"> - <div className="about-page-entry"> - <div className="about-page-container clearfix"> - <div className="pull-left"> - <div className="about-page-logo"> - <img src={logoUrl} width={2 * logoWidth} height={2 * logoHeight} alt={logoTitle}/> - </div> - </div> - - <div className="about-page-entry-column"> - <EntryIssueTypes - bugs={this.state.issueTypes['BUG'].count} - vulnerabilities={this.state.issueTypes['VULNERABILITY'].count} - codeSmells={this.state.issueTypes['CODE_SMELL'].count}/> + <div className="about-page-container"> + <div className="about-page-entry"> + <div className="about-page-intro"> + <h1 className="big-spacer-bottom"> + {translate('layout.sonar.slogan')} + </h1> + {!this.props.currentUser.isLoggedIn && ( + <Link to="/sessions/new" className="button button-active big-spacer-right"> + {translate('layout.login')} + </Link> + )} + <a className="button" href="https://redirect.sonarsource.com/doc/home.html"> + {translate('about_page.read_documentation')} + </a> </div> - <div className="about-page-entry-column"> + <div className="about-page-instance"> <AboutProjects count={this.state.projectsCount}/> + <EntryIssueTypes bugs={bugs} vulnerabilities={vulnerabilities} codeSmells={codeSmells}/> </div> </div> - </div> - - <div className="about-page-container"> {customText != null && customText.length > 0 && ( <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText }}/> )} + <AboutLanguages/> + + <AboutQualityModel/> + <div className="flex-columns"> - <div className="flex-column flex-column-two-thirds about-page-group-boxes"> + <div className="flex-column flex-column-half about-page-group-boxes"> <AboutCleanCode/> - <AboutLeakPeriod/> </div> - <div className="flex-column flex-column-third about-page-group-boxes"> - <AboutIssues/> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutLeakPeriod/> </div> </div> @@ -155,8 +172,7 @@ class AboutApp extends React.Component { } const mapStateToProps = state => ({ - customLogoUrl: (getSettingValue(state, 'sonar.lf.logoUrl') || {}).value, - customLogoWidth: (getSettingValue(state, 'sonar.lf.logoWidthPx') || {}).value + currentUser: getCurrentUser(state) }); export default connect(mapStateToProps)(AboutApp); diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js index 9c3c57c5e0a..d5531859fc2 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js @@ -18,8 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import ReadMore from './ReadMore'; import { translate } from '../../../helpers/l10n'; +const link = 'https://redirect.sonarsource.com/doc/issues.html'; + export default class AboutCleanCode extends React.Component { render () { return ( @@ -27,6 +30,7 @@ export default class AboutCleanCode extends React.Component { <h2>{translate('about_page.clean_code')}</h2> <div className="boxed-group-inner"> <p className="about-page-text">{translate('about_page.clean_code.text')}</p> + <ReadMore link={link}/> </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js b/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js deleted file mode 100644 index 8213bf6316c..00000000000 --- a/server/sonar-web/src/main/js/apps/about/components/AboutIssues.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 { translate } from '../../../helpers/l10n'; -import BugIcon from '../../../components/ui/BugIcon'; -import VulnerabilityIcon from '../../../components/ui/VulnerabilityIcon'; -import CodeSmellIcon from '../../../components/ui/CodeSmellIcon'; - -export default class AboutIssues extends React.Component { - render () { - return ( - <div className="boxed-group"> - <h2>{translate('about_page.quality_model')}</h2> - - <div className="boxed-group-inner clearfix"> - <h3 className="spacer-bottom"> - <span className="little-spacer-right"><BugIcon/></span> - {translate('issue.type.BUG.plural')} - </h3> - <p className="about-page-text"> - {translate('about_page.quality_model.bugs')} - </p> - - <h3 className="big-spacer-top spacer-bottom"> - <span className="little-spacer-right"><VulnerabilityIcon/></span> - {translate('issue.type.VULNERABILITY.plural')} - </h3> - <p className="about-page-text"> - {translate('about_page.quality_model.vulnerabilities')} - </p> - - <h3 className="big-spacer-top spacer-bottom"> - <span className="little-spacer-right"><CodeSmellIcon/></span> - {translate('issue.type.CODE_SMELL.plural')} - </h3> - <p className="about-page-text"> - {translate('about_page.quality_model.code_smells')} - </p> - </div> - </div> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js new file mode 100644 index 00000000000..824e10cb33d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js @@ -0,0 +1,70 @@ +/* + * 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. + */ +// @flow +import React from 'react'; +import { translate } from '../../../helpers/l10n'; + +const languages = [ + { name: 'Java', url: 'https://redirect.sonarsource.com/plugins/java.html' }, + { name: 'C/C++', url: 'https://redirect.sonarsource.com/plugins/cpp.html' }, + { name: 'C#', url: 'https://redirect.sonarsource.com/plugins/csharp.html' }, + { name: 'COBOL', url: 'https://redirect.sonarsource.com/plugins/cobol.html' }, + { name: 'ABAP', url: 'https://redirect.sonarsource.com/plugins/abap.html' }, + { name: 'HTML', url: 'https://redirect.sonarsource.com/plugins/web.html' }, + { name: 'RPG', url: 'https://redirect.sonarsource.com/plugins/rpg.html' }, + { name: 'JavaScript', url: 'https://redirect.sonarsource.com/plugins/javascript.html' }, + { name: 'Objective C', url: 'https://redirect.sonarsource.com/plugins/objectivec.html' }, + { name: 'XML', url: 'https://redirect.sonarsource.com/plugins/xml.html' }, + { name: 'VB.NET', url: 'https://redirect.sonarsource.com/plugins/vbnet.html' }, + { name: 'PL/SQL', url: 'https://redirect.sonarsource.com/plugins/plsql.html' }, + { name: 'Flex', url: 'https://redirect.sonarsource.com/plugins/flex.html' }, + { name: 'Python', url: 'https://redirect.sonarsource.com/plugins/python.html' }, + { name: 'Groovy', url: 'https://redirect.sonarsource.com/plugins/groovy.html' }, + { name: 'PHP', url: 'https://redirect.sonarsource.com/plugins/php.html' }, + { name: 'Swift', url: 'https://redirect.sonarsource.com/plugins/swift.html' }, + { name: 'Visual Basic', url: 'https://redirect.sonarsource.com/plugins/vb.html' }, + { name: 'PL/I', url: 'https://redirect.sonarsource.com/plugins/pli.html' } +]; + +const half = (languages.length + 1) / 2; + +export default class AboutLanguages extends React.Component { + render () { + return ( + <div className="boxed-group"> + <h2>{translate('about_page.languages')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.languages.text')}</p> + <ul className="about-page-languages"> + {languages.slice(0, half).map((language, index) => ( + <li key={index}> + <a href={languages[index].url}>{languages[index].name}</a> + <br/> + {index + half < languages.length && ( + <a href={languages[index + half].url}>{languages[index + half].name}</a> + )} + </li> + ))} + </ul> + </div> + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js index 1755b96e69a..feb094aa5c9 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js @@ -27,9 +27,9 @@ export default class AboutLeakPeriod extends React.Component { render () { return ( <div className="boxed-group"> - <h2>{translate('about_page.leak_period')}</h2> + <h2>{translate('about_page.fix_the_leak')}</h2> <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.leak_period.text')}</p> + <p className="about-page-text">{translate('about_page.fix_the_leak.text')}</p> <ReadMore link={link}/> </div> </div> diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js index 190f41f6704..ecaf724f924 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js @@ -30,7 +30,7 @@ export default class AboutProjects extends React.Component { render () { return ( <div className="about-page-projects"> - <div className="big-spacer-bottom"> + <div> <Link to="/projects" className="about-page-projects-link"> {formatMeasure(this.props.count, 'INT')} </Link> diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js new file mode 100644 index 00000000000..fc036f18c95 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js @@ -0,0 +1,65 @@ +/* + * 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 { translate } from '../../../helpers/l10n'; +import BugIcon from '../../../components/ui/BugIcon'; +import VulnerabilityIcon from '../../../components/ui/VulnerabilityIcon'; +import CodeSmellIcon from '../../../components/ui/CodeSmellIcon'; + +export default class AboutQualityModel extends React.Component { + render () { + return ( + <div className="boxed-group about-quality-model"> + <h2>{translate('about_page.quality_model')}</h2> + + <div className="boxed-group-inner clearfix"> + <div className="flex-columns"> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><BugIcon/></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.BUG.plural')}</strong> + {' '} + {translate('about_page.quality_model.bugs')} + </p> + </div> + + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><VulnerabilityIcon/></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.VULNERABILITY.plural')}</strong> + {' '} + {translate('about_page.quality_model.vulnerabilities')} + </p> + </div> + + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><CodeSmellIcon/></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.CODE_SMELL.plural')}</strong> + {' '} + {translate('about_page.quality_model.code_smells')} + </p> + </div> + </div> + </div> + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js index 627996d1945..42b0e5328a9 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import ReadMore from './ReadMore'; import { translate } from '../../../helpers/l10n'; const scanners = [ @@ -49,16 +48,13 @@ export default class AboutScanners extends React.Component { <div className="boxed-group"> <h2>{translate('about_page.scanners')}</h2> <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.scanners.text')}</p> <div className="about-page-analyzers"> {scanners.map(scanner => ( - <div key={scanner.key} className="about-page-analyzer-box"> - <div className="big-spacer-bottom"> - <img src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`} height={80} - alt={translate('about_page.scanners', scanner.key)}/> - </div> - <p className="about-page-text">{translate('about_page.scanners', scanner.key, 'text')}</p> - <ReadMore link={scanner.link}/> - </div> + <a key={scanner.key} className="about-page-analyzer-box" href={scanner.link}> + <img src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`} height={60} + alt={translate('about_page.scanners', scanner.key)}/> + </a> ))} </div> </div> diff --git a/server/sonar-web/src/main/js/apps/about/components/ReadMore.js b/server/sonar-web/src/main/js/apps/about/components/ReadMore.js index 2199979f1ca..8ba0ea98a22 100644 --- a/server/sonar-web/src/main/js/apps/about/components/ReadMore.js +++ b/server/sonar-web/src/main/js/apps/about/components/ReadMore.js @@ -30,7 +30,6 @@ export default class ReadMore extends React.Component { <div className="big-spacer-top"> <a className="about-page-link-more" href={this.props.link} target="_blank"> <span>{translate('about_page.read_more')}</span> - <i className="icon-detach spacer-left"/> </a> </div> ); diff --git a/server/sonar-web/src/main/js/apps/about/styles.css b/server/sonar-web/src/main/js/apps/about/styles.css index 98840ab8fcd..d09ede5c5f7 100644 --- a/server/sonar-web/src/main/js/apps/about/styles.css +++ b/server/sonar-web/src/main/js/apps/about/styles.css @@ -1,10 +1,21 @@ .about-page { + font-size: 14px; +} + +.about-page .boxed-group { + border: none; } .about-page .boxed-group h2 { font-size: 18px; - font-weight: bold; - text-align: center; +} + +.about-page .boxed-group > h2 { + padding-top: 25px; +} + +.about-page .boxed-group-inner { + padding-bottom: 25px; } .about-page-container { @@ -17,61 +28,63 @@ box-sizing: border-box; } -.about-page-center-container { - position: relative; - width: 640px; - margin: 0 auto; - text-align: center; -} - -.about-page-logo { - padding: 20px 0; -} - .about-page-entry { - margin-bottom: 50px; - padding: 40px 0 50px; - background-color: #363636; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 45px; + padding: 65px 0 65px; + border-bottom: 1px solid #e6e6e6; } -.about-page-entry .about-page-header { - color: rgba(255, 255, 255, 0.9); +.about-page-intro { + padding-right: 65px; + border-right: 1px solid #e6e6e6; } -.about-page-entry-column { - float: right; - text-align: center; - box-sizing: border-box; +.about-page-intro > h1 { + line-height: 40px; + font-size: 26px; + font-weight: 300; } -.about-page-entry-column + .about-page-entry-column { - margin-right: 60px; - padding-right: 60px; - border-right: 1px solid rgba(75, 159, 213, 0.2); +.about-page-intro > .button { + height: 32px; + line-height: 30px; + padding-left: 15px; + padding-right: 15px; + border-radius: 3px; + font-size: 13px; + font-weight: 400; } -.about-page-entry .alert { - font-size: 13px; +.about-page-instance { + display: flex; + align-items: center; } .about-page-projects { + margin-left: 65px; line-height: 1.4; - color: rgba(255, 255, 255, 0.9); font-size: 16px; text-align: center; } .about-page-projects-link { - border-bottom-color: rgba(75, 159, 213, 0.2); - color: rgb(75, 159, 213); - font-size: 44px; - font-weight: bold; + display: inline-block; + line-height: 1; + margin-bottom: 12px; + font-size: 32px; } .about-page-issue-types { text-align: left; } +.about-page-issue-types > li + li { + margin-top: 12px; +} + .about-page-issue-types svg { vertical-align: middle; transform: translateY(-1px); @@ -85,9 +98,7 @@ } .about-page-issue-type-link { - border-bottom-color: rgba(75, 159, 213, 0.2); - color: rgb(75, 159, 213); - font-size: 24px; + font-size: 16px; font-weight: bold; } @@ -194,15 +205,34 @@ text-transform: uppercase; } +.about-page-languages { + display: flex; + justify-content: space-between; + margin-top: 10px; +} + +.about-page-languages > li { + line-height: 2; +} + +.about-quality-model .flex-column + .flex-column{ + margin-left: 30px; + padding-left: 30px; + border-left: 1px solid #e6e6e6; +} + +.about-quality-model svg { + transform: translateY(2px); +} + .about-page-analyzers { display: flex; justify-content: space-between; - flex-wrap: wrap; + margin-top: 15px; } .about-page-analyzer-box { - width: 310px; - margin-top: 40px; + border: none; } .about-page-group-boxes { |