]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8750 Display a branding landing page
authorStas Vilchik <vilchiks@gmail.com>
Tue, 7 Feb 2017 15:31:36 +0000 (16:31 +0100)
committerStas Vilchik <stas-vilchik@users.noreply.github.com>
Wed, 8 Feb 2017 15:25:16 +0000 (16:25 +0100)
17 files changed:
server/sonar-web/src/main/js/api/settings.js
server/sonar-web/src/main/js/apps/about/actions.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutApp.js
server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutProjects.js
server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js
server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/components/IconLock.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/OAuthProvider.css [deleted file]
server/sonar-web/src/main/js/apps/about/components/OAuthProvider.js [deleted file]
server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/sonarqube-dot-com-styles.css [new file with mode: 0644]
server/sonar-web/src/main/js/apps/about/styles.css

index 2e5ce2b4bfa419155c2c109e18eb8b2d4e7ec835..0276d4cd8bf6b53b6ae3876461e61fe1db1e521c 100644 (file)
@@ -96,8 +96,3 @@ export function getServerId () {
 export function generateServerId (organization, ip) {
   return postJSON('/api/server_id/generate', { organization, ip });
 }
-
-// TODO replace with /api/settings
-export const getSettingValue = key => (
-    getJSON(`/api/properties/${key}`).then(r => r[0] ? r[0].value : null)
-);
diff --git a/server/sonar-web/src/main/js/apps/about/actions.js b/server/sonar-web/src/main/js/apps/about/actions.js
new file mode 100644 (file)
index 0000000..e07cd9d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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 { getValues } from '../../api/settings';
+import { receiveValues } from '../settings/store/values/actions';
+
+export const fetchAboutPageSettings = (): Function => (dispatch: Function): Promise<*> => {
+  const keys = ['sonar.lf.aboutText'];
+
+  return getValues(keys.join()).then(values => {
+    dispatch(receiveValues(values));
+  });
+};
index 21db6186dee6cdd68133dfc3231c9d9c4eb8dcac..fbc571db81eb74e3eeff6987f091c66c9b7dabb9 100644 (file)
@@ -33,10 +33,11 @@ import AboutStandards from './AboutStandards';
 import AboutScanners from './AboutScanners';
 import { searchProjects } from '../../../api/components';
 import { getFacet } from '../../../api/issues';
-import * as settingsAPI from '../../../api/settings';
-import { getCurrentUser } from '../../../store/rootReducer';
-import '../styles.css';
+import { getCurrentUser, getSettingValue } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
+import { fetchAboutPageSettings } from '../actions';
+import AboutAppForSonarQubeDotCom from './AboutAppForSonarQubeDotCom';
+import '../styles.css';
 
 type State = {
   loading: boolean,
@@ -45,15 +46,17 @@ type State = {
     [key: string]: {
       count: number
     }
-  },
-  customText?: string
+  }
 };
 
 class AboutApp extends React.Component {
   mounted: boolean;
 
   props: {
-    currentUser: { isLoggedIn: boolean }
+    currentUser: { isLoggedIn: boolean },
+    customText?: string,
+    fetchAboutPageSettings: () => Promise<*>,
+    sonarqubeDotCom?: { value: string }
   };
 
   state: State = {
@@ -78,7 +81,7 @@ class AboutApp extends React.Component {
   }
 
   loadCustomText () {
-    return settingsAPI.getSettingValue('sonar.lf.aboutText');
+    return this.props.fetchAboutPageSettings();
   }
 
   loadData () {
@@ -88,12 +91,11 @@ class AboutApp extends React.Component {
       this.loadCustomText()
     ]).then(responses => {
       if (this.mounted) {
-        const [projectsCount, issues, customText] = responses;
+        const [projectsCount, issues] = responses;
         const issueTypes = keyBy(issues.facet, 'val');
         this.setState({
           projectsCount,
           issueTypes,
-          customText,
           loading: false
         });
       }
@@ -105,7 +107,7 @@ class AboutApp extends React.Component {
       return null;
     }
 
-    const { customText } = this.state;
+    const { customText, sonarqubeDotCom } = this.props;
 
     // $FlowFixMe
     const bugs = this.state.issueTypes['BUG'].count;
@@ -114,6 +116,18 @@ class AboutApp extends React.Component {
     // $FlowFixMe
     const codeSmells = this.state.issueTypes['CODE_SMELL'].count;
 
+    if (sonarqubeDotCom && sonarqubeDotCom.value === 'true') {
+      return (
+          <AboutAppForSonarQubeDotCom
+              bugs={bugs}
+              codeSmells={codeSmells}
+              currentUser={this.props.currentUser}
+              customText={customText}
+              projectsCount={this.state.projectsCount}
+              vulnerabilities={vulnerabilities}/>
+      );
+    }
+
     return (
         <div id="about-page" className="about-page">
           <div className="about-page-container">
@@ -138,8 +152,8 @@ class AboutApp extends React.Component {
               </div>
             </div>
 
-            {customText != null && customText.length > 0 && (
-                <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText }}/>
+            {customText != null && customText.value && (
+                <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText.value }}/>
             )}
 
             <AboutLanguages/>
@@ -172,7 +186,11 @@ class AboutApp extends React.Component {
 }
 
 const mapStateToProps = state => ({
-  currentUser: getCurrentUser(state)
+  currentUser: getCurrentUser(state),
+  customText: getSettingValue(state, 'sonar.lf.aboutText'),
+  sonarqubeDotCom: getSettingValue(state, 'sonar.lf.sonarqube.com.enabled')
 });
 
-export default connect(mapStateToProps)(AboutApp);
+const mapDispatchToProps = { fetchAboutPageSettings };
+
+export default connect(mapStateToProps, mapDispatchToProps)(AboutApp);
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..2c58a9d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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 { Link } from 'react-router';
+import AboutProjects from './AboutProjects';
+import EntryIssueTypesForSonarQubeDotCom from './EntryIssueTypesForSonarQubeDotCom';
+import AboutRulesForSonarQubeDotCom from './AboutRulesForSonarQubeDotCom';
+import AboutLanguages from './AboutLanguages';
+import AboutCleanCode from './AboutCleanCode';
+import AboutQualityModelForSonarQubeDotCom from './AboutQualityModelForSonarQubeDotCom';
+import AboutQualityGates from './AboutQualityGates';
+import AboutLeakPeriod from './AboutLeakPeriod';
+import AboutStandards from './AboutStandards';
+import AboutScanners from './AboutScanners';
+import { translate } from '../../../helpers/l10n';
+import '../sonarqube-dot-com-styles.css';
+
+export default class AboutAppForSonarQubeDotCom extends React.Component {
+  props: {
+    bugs: number,
+    codeSmells: number,
+    currentUser: { isLoggedIn: boolean },
+    customText?: string,
+    projectsCount: number,
+    vulnerabilities: number,
+  };
+
+  render () {
+    const { customText } = this.props;
+
+
+    return (
+        <div id="about-page" className="about-page sqcom-about-page">
+          <div className="sqcom-about-page-entry">
+            <div className="about-page-container">
+              <div className="sqcom-about-page-intro">
+                <h1 className="big-spacer-bottom">
+                  Continuous Code Quality<br/>as a Service
+                </h1>
+                <a className="button button-active" href="https://about.sonarqube.com/get-started/">
+                  Get Started
+                </a>
+                {!this.props.currentUser.isLoggedIn && (
+                    <Link to="/sessions/new" className="button big-spacer-left">
+                      {translate('layout.login')}
+                    </Link>
+                )}
+              </div>
+
+              <div className="sqcom-about-page-instance">
+                <AboutProjects count={this.props.projectsCount}/>
+                <EntryIssueTypesForSonarQubeDotCom
+                    bugs={this.props.bugs}
+                    vulnerabilities={this.props.vulnerabilities}
+                    codeSmells={this.props.codeSmells}/>
+              </div>
+            </div>
+          </div>
+
+          <AboutRulesForSonarQubeDotCom/>
+
+          <div className="about-page-container">
+            {customText != null && customText.value && (
+                <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText.value }}/>
+            )}
+
+            <AboutLanguages/>
+
+            <AboutQualityModelForSonarQubeDotCom/>
+
+            <div className="flex-columns">
+              <div className="flex-column flex-column-half about-page-group-boxes">
+                <AboutCleanCode/>
+              </div>
+              <div className="flex-column flex-column-half about-page-group-boxes">
+                <AboutLeakPeriod/>
+              </div>
+            </div>
+
+            <div className="flex-columns">
+              <div className="flex-column flex-column-half about-page-group-boxes">
+                <AboutQualityGates/>
+              </div>
+              <div className="flex-column flex-column-half about-page-group-boxes">
+                <AboutStandards/>
+              </div>
+            </div>
+
+            <AboutScanners/>
+          </div>
+        </div>
+    );
+  }
+}
index ecaf724f924b0ee7402ad0869c5f03864cf930ed..0fd88aa97f21afafdb46598b62f4af9c7758dbee 100644 (file)
@@ -31,12 +31,14 @@ export default class AboutProjects extends React.Component {
     return (
         <div className="about-page-projects">
           <div>
-            <Link to="/projects" className="about-page-projects-link">
-              {formatMeasure(this.props.count, 'INT')}
-            </Link>
-          </div>
-          <div>
-            {translate('about_page.projects_analyzed')}
+            <div>
+              <Link to="/projects" className="about-page-projects-link">
+                {formatMeasure(this.props.count, 'INT')}
+              </Link>
+            </div>
+            <div>
+              {translate('about_page.projects_analyzed')}
+            </div>
           </div>
         </div>
     );
diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..86cfdb0
--- /dev/null
@@ -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 BugIconForSonarQubeDotCom from './BugIconForSonarQubeDotCom';
+import VulnerabilityIconForSonarQubeDotCom from './VulnerabilityIconForSonarQubeDotCom';
+import CodeSmellIconForSonarQubeDotCom from './CodeSmellIconForSonarQubeDotCom';
+
+export default class AboutQualityModelForSonarQubeDotCom extends React.Component {
+  render () {
+    return (
+        <div className="boxed-group about-quality-model sqcom-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"><BugIconForSonarQubeDotCom/></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"><VulnerabilityIconForSonarQubeDotCom/></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"><CodeSmellIconForSonarQubeDotCom/></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/AboutRulesForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..d16567b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 { Link } from 'react-router';
+import { getRulesUrl } from '../../../helpers/urls';
+
+export default class AboutRulesForSonarQubeDotCom extends React.Component {
+  render () {
+    return (
+        <div className="sqcom-about-rules">
+          <div className="about-page-container">
+            <Link to={getRulesUrl()} className="sqcom-about-rules-link">
+              +2000 rules
+              <span className="spacer-left">
+                <svg width="15" height="36" viewBox="0 0 15 36">
+                  <g transform="matrix(1,0,0,1,-267,-362)">
+                    <path d="M268,363L281,380L269,397" style={{ fill: 'none', stroke: '#c1d9ea', strokeWidth: 1 }}/>
+                  </g>
+                </svg>
+              </span>
+            </Link>
+            <Link to={getRulesUrl({ languages: 'js' })} className="sqcom-about-rules-link">JavaScript</Link>
+            <Link to={getRulesUrl({ languages: 'java' })} className="sqcom-about-rules-link">Java</Link>
+            <Link to={getRulesUrl({ languages: 'c,cpp' })} className="sqcom-about-rules-link">C/C++</Link>
+            <Link to={getRulesUrl({ languages: 'cs' })} className="sqcom-about-rules-link">C#</Link>
+            <Link to={getRulesUrl()} className="button">And More</Link>
+          </div>
+        </div>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..858fffc
--- /dev/null
@@ -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.
+ */
+// @flow
+import React from 'react';
+
+export default class BugIconForSonarQubeDotCom extends React.Component {
+  render () {
+    /* eslint-disable max-len */
+    return (
+        <svg viewBox="0 0 26 26" width="26" height="26">
+          <path style={{ fill: 'currentcolor' }} d="M23.737 15.91l-2.298-2.297a.797.797 0 0 0-.542-.232h-2.18v-1.588l2.722-2.723a.773.773 0 0 0 .233-.542V4.243a.777.777 0 0 0-.775-.775.777.777 0 0 0-.774.775v3.962l-1.407 1.407v-.633a.777.777 0 0 0-.774-.774h-.517a4.51 4.51 0 0 0-2.852-3.446l2.698-2.698a.787.787 0 0 0 0-1.097.787.787 0 0 0-1.098 0L12.985 4.14 9.823.99a.787.787 0 0 0-1.097 0 .787.787 0 0 0 0 1.097l2.672 2.672a4.51 4.51 0 0 0-2.853 3.446H7.99a.777.777 0 0 0-.774.774v.633L5.81 8.192v-3.95a.777.777 0 0 0-.774-.774.777.777 0 0 0-.775.775v4.272c0 .206.078.4.233.542l2.723 2.723v1.6H5.035c-.207 0-.4.078-.542.233L2.195 15.91a.787.787 0 0 0 0 1.098.764.764 0 0 0 .542.232c.194 0 .4-.078.542-.232l2.078-2.078h1.86v.761l-2.789 3.64a.783.783 0 0 0-.155.477v4.505c0 .426.349.774.775.774a.777.777 0 0 0 .774-.774v-4.247l1.433-1.884a5.77 5.77 0 0 0 2.788 4.298l.077.039c.84.49 1.82.761 2.853.761a5.825 5.825 0 0 0 2.865-.761c.013-.013.039-.013.051-.026a5.75 5.75 0 0 0 2.801-4.31l1.446 1.883v4.247c0 .426.348.774.774.774a.777.777 0 0 0 .775-.774v-4.505a.811.811 0 0 0-.155-.477l-2.788-3.64v-.761H20.6l2.078 2.078a.764.764 0 0 0 .542.232c.193 0 .4-.078.542-.232a.787.787 0 0 0-.026-1.098zm-10.752-9.9c1.369 0 2.517.93 2.853 2.182h-5.705a2.954 2.954 0 0 1 2.852-2.181zm-4.22 11.527V9.754h3.433v9.254l-1.82 1.82a4.172 4.172 0 0 1-1.613-3.291zm3.046 4.04l1.149-1.15 1.148 1.15a4.188 4.188 0 0 1-1.148.167c-.388 0-.775-.064-1.15-.167zm5.356-4.04c0 1.342-.632 2.53-1.6 3.304l-1.82-1.82V9.754h3.433v7.783h-.013z"/>
+        </svg>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..1e7887c
--- /dev/null
@@ -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.
+ */
+// @flow
+import React from 'react';
+
+export default class CodeSmellIconForSonarQubeDotCom extends React.Component {
+  render () {
+    /* eslint-disable max-len */
+    return (
+        <svg viewBox="0 0 26 26" width="26" height="26">
+          <path style={{ fill: 'currentcolor' }} d="M19.957 5.099a10.455 10.455 0 0 0-7.424-3.077c-1.42 0-2.792.278-4.087.825a10.426 10.426 0 0 0-3.338 2.249 10.462 10.462 0 0 0-3.076 7.427c0 1.418.279 2.791.826 4.087a10.497 10.497 0 0 0 2.25 3.338 10.426 10.426 0 0 0 3.338 2.25c1.295.546 2.67.825 4.086.825 1.419 0 2.791-.279 4.087-.826a10.426 10.426 0 0 0 3.338-2.249 10.465 10.465 0 0 0 3.075-7.425c0-1.417-.278-2.793-.823-4.086a10.396 10.396 0 0 0-2.252-3.338zm.393 10.725a8.436 8.436 0 0 1-1.818 2.695 8.452 8.452 0 0 1-5.996 2.486 8.442 8.442 0 0 1-5.997-2.486 8.455 8.455 0 0 1-2.486-5.996 8.43 8.43 0 0 1 2.486-5.995 8.452 8.452 0 0 1 5.996-2.486 8.445 8.445 0 0 1 5.997 2.486 8.452 8.452 0 0 1 2.485 5.995 8.35 8.35 0 0 1-.667 3.3zm-7.794 4.202h-.037a7.767 7.767 0 0 1-3.426-.835.317.317 0 0 1-.13-.44l2.25-3.923a.32.32 0 0 1 .403-.132c.284.119.595.189.92.189.326 0 .639-.067.92-.19a.32.32 0 0 1 .404.133l2.255 3.922c.09.157.03.36-.133.441a7.896 7.896 0 0 1-3.426.835zm-1.58-7.457c0-.003 0-.009-.003-.013a1.56 1.56 0 0 1 2.337-1.35c.468.269.781.77.781 1.35v.013a1.557 1.557 0 0 1-3.115 0zm-1.068.015H5.384a.318.318 0 0 1-.32-.334c.03-.614.19-1.992.981-3.391l.008-.016.007-.016a7.806 7.806 0 0 1 2.428-2.554.317.317 0 0 1 .448.106l2.282 3.903a.316.316 0 0 1-.082.414 2.371 2.371 0 0 0-.914 1.605.325.325 0 0 1-.314.283zm9.776-.007h-4.526a.32.32 0 0 1-.316-.282 2.371 2.371 0 0 0-.913-1.604.322.322 0 0 1-.082-.414l2.284-3.904a.317.317 0 0 1 .449-.106 7.787 7.787 0 0 1 2.426 2.554l.016.033a7.74 7.74 0 0 1 .98 3.387.319.319 0 0 1-.318.336z"/>
+        </svg>
+    );
+  }
+}
index d55a975fd69e895d904ae456bd0f2c627d8b9347..9b4816a6d241a0076758e38d1c433ac81e504303 100644 (file)
@@ -38,38 +38,46 @@ export default class EntryIssueTypes extends React.Component {
 
     return (
         <div className="about-page-projects">
-          <ul className="about-page-issue-types">
-            <li>
-              <div className="about-page-issue-type-number">
-                <Link to={getIssuesUrl({ resolved: false, types: 'BUG' })}
-                      className="about-page-issue-type-link">
-                  {formatMeasure(bugs, 'SHORT_INT')}
-                </Link>
-              </div>
-              <span className="little-spacer-right"><BugIcon/></span>
-              {translate('issue.type.BUG.plural')}
-            </li>
-            <li>
-              <div className="about-page-issue-type-number">
-                <Link to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })}
-                      className="about-page-issue-type-link">
-                  {formatMeasure(vulnerabilities, 'SHORT_INT')}
-                </Link>
-              </div>
-              <span className="little-spacer-right"><VulnerabilityIcon/></span>
-              {translate('issue.type.VULNERABILITY.plural')}
-            </li>
-            <li>
-              <div className="about-page-issue-type-number">
-                <Link to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })}
-                      className="about-page-issue-type-link">
-                  {formatMeasure(codeSmells, 'SHORT_INT')}
-                </Link>
-              </div>
-              <span className="little-spacer-right"><CodeSmellIcon/></span>
-              {translate('issue.type.CODE_SMELL.plural')}
-            </li>
-          </ul>
+          <table className="about-page-issue-types">
+            <tbody>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'BUG' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(bugs, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><BugIcon/></span>
+                  {translate('issue.type.BUG.plural')}
+                </td>
+              </tr>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(vulnerabilities, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><VulnerabilityIcon/></span>
+                  {translate('issue.type.VULNERABILITY.plural')}
+                </td>
+              </tr>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(codeSmells, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><CodeSmellIcon/></span>
+                  {translate('issue.type.CODE_SMELL.plural')}
+                </td>
+              </tr>
+            </tbody>
+          </table>
         </div>
     );
   }
diff --git a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..ba63443
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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';
+import { translate } from '../../../helpers/l10n';
+import { getIssuesUrl } from '../../../helpers/urls';
+import BugIconForSonarQubeDotCom from './BugIconForSonarQubeDotCom';
+import VulnerabilityIconForSonarQubeDotCom from './VulnerabilityIconForSonarQubeDotCom';
+import CodeSmellIconForSonarQubeDotCom from './CodeSmellIconForSonarQubeDotCom';
+
+export default class EntryIssueTypesForSonarQubeDotCom extends React.Component {
+  static propTypes = {
+    bugs: React.PropTypes.number.isRequired,
+    vulnerabilities: React.PropTypes.number.isRequired,
+    codeSmells: React.PropTypes.number.isRequired
+  };
+
+  render () {
+    const { bugs, vulnerabilities, codeSmells } = this.props;
+
+    return (
+        <div className="about-page-projects">
+          <table className="about-page-issue-types">
+            <tbody>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'BUG' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(bugs, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><BugIconForSonarQubeDotCom/></span>
+                  {translate('issue.type.BUG.plural')}
+                </td>
+              </tr>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(vulnerabilities, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><VulnerabilityIconForSonarQubeDotCom/></span>
+                  {translate('issue.type.VULNERABILITY.plural')}
+                </td>
+              </tr>
+              <tr>
+                <td className="about-page-issue-type-number">
+                  <Link to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })}
+                        className="about-page-issue-type-link">
+                    {formatMeasure(codeSmells, 'SHORT_INT')}
+                  </Link>
+                </td>
+                <td>
+                  <span className="little-spacer-right"><CodeSmellIconForSonarQubeDotCom/></span>
+                  {translate('issue.type.CODE_SMELL.plural')}
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+    );
+  }
+}
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
deleted file mode 100644 (file)
index fbdc836..0000000
+++ /dev/null
@@ -1,29 +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';
-
-export default function () {
-  /* eslint-disable max-len */
-  return (
-      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 288 448" width="20" height="20">
-        <path fill="#fff" d="M264 192q10 0 17 7t7 17v144q0 10-7 17t-17 7H24q-10 0-17-7t-7-17V216q0-10 7-17t17-7h8v-80q0-46.25 32.875-79.125T144 0t79.125 32.875T256 112q0 6.5-4.75 11.25T240 128h-16q-6.5 0-11.25-4.75T208 112q0-26.5-18.75-45.25T144 48 98.75 66.75 80 112v80h184z"/>
-      </svg>
-  );
-}
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
deleted file mode 100644 (file)
index 0718acd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-.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;
-  text-align: center;
-  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
deleted file mode 100644 (file)
index 1ae5365..0000000
+++ /dev/null
@@ -1,46 +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 './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 (
-        <a className="oauth-provider" href={url} style={{ backgroundColor }} title={label}>
-          <img alt={name} width="20" height="20" src={window.baseUrl + iconPath}/>
-          <span>{label}</span>
-        </a>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js
new file mode 100644 (file)
index 0000000..41ca97c
--- /dev/null
@@ -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.
+ */
+// @flow
+import React from 'react';
+
+export default class VulnerabilityIconForSonarQubeDotCom extends React.Component {
+  render () {
+    /* eslint-disable max-len */
+    return (
+        <svg viewBox="0 0 26 26" width="26" height="26">
+          <path style={{ fill: 'currentcolor' }} d="M7.688 9.224V5.818c0-2.622 2.16-4.756 4.813-4.756 2.654 0 4.802 2.134 4.813 4.756v.931c0 .5-.413.909-.919.909a.916.916 0 0 1-.919-.909v-.93c0-1.624-1.332-2.94-2.975-2.94s-2.975 1.316-2.975 2.94v3.405h7.892c1.401 0 2.539 1.124 2.539 2.509v9.706c0 1.442-1.195 2.623-2.654 2.623H7.688c-1.46 0-2.654-1.18-2.654-2.623v-9.706c0-1.385 1.137-2.509 2.539-2.509h.115zm9.615 13.033a.814.814 0 0 0 .816-.806v-9.718a.692.692 0 0 0-.701-.692H7.573c-.39 0-.7.306-.7.692v9.718c0 .442.367.806.815.806h9.615zm-4.802-8.98c-1.045 0-1.907.84-1.907 1.884 0 .704.402 1.329.988 1.647v2.304c0 .5.414.908.92.908a.916.916 0 0 0 .918-.908v-2.316c.586-.318.988-.942.988-1.646a1.904 1.904 0 0 0-1.907-1.873zM22.99 8.804l-1.7-.681c-.47-.182-1.01.034-1.194.5a.904.904 0 0 0 .505 1.18l1.712.681c.115.046.23.068.344.068a.908.908 0 0 0 .85-.567.91.91 0 0 0-.517-1.18zm-2.837-1.703a.939.939 0 0 0 1.206.488l1.689-.715a.9.9 0 0 0 .482-1.192c-.195-.465-.735-.67-1.206-.477l-1.689.716a.876.876 0 0 0-.482 1.18zm-1.068-1.124c-.471-.181-.69-.715-.506-1.192l.69-1.68c.183-.465.723-.681 1.194-.5.471.182.69.716.506 1.181l-.69 1.692a.908.908 0 0 1-.85.567.932.932 0 0 1-.344-.068z"/>
+        </svg>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/about/sonarqube-dot-com-styles.css b/server/sonar-web/src/main/js/apps/about/sonarqube-dot-com-styles.css
new file mode 100644 (file)
index 0000000..0607c3d
--- /dev/null
@@ -0,0 +1,146 @@
+@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700');
+
+.sqcom-about-page {
+  font-family: 'Roboto', sans-serif;
+  font-size: 15px !important;
+  font-weight: 300;
+}
+
+.sqcom-about-page-entry {
+  padding-top: 65px;
+  padding-bottom: 65px;
+  background-color: #4b9fd5;
+}
+
+.sqcom-about-page-entry a {
+  color: #4b9fd5;
+}
+
+.sqcom-about-page-entry .about-page-container {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.sqcom-about-page-intro {
+
+}
+
+.sqcom-about-page-intro > h1 {
+  line-height: 56px;
+  color: #fff;
+  font-size: 44px;
+  font-weight: 300;
+}
+
+.sqcom-about-page-intro > .button {
+  height: 44px;
+  line-height: 42px;
+  padding-left: 20px;
+  padding-right: 20px;
+  border-color: #fff;
+  border-radius: 3px;
+  color: #fff;
+  font-size: 16px;
+  font-weight: 500;
+  text-transform: uppercase;
+  transition: none;
+}
+
+.sqcom-about-page-intro > .button:hover {
+  background-color: #fff;
+  color: #4b9fd5;
+}
+
+.sqcom-about-page-intro > .button-active {
+  border-color: #b0eb41;
+  background-color: #b0eb41;
+  color: #225463;
+}
+
+.sqcom-about-page-intro > .button-active:hover {
+  border-color: #91d315;
+  background-color: #91d315;
+  color: #225463;
+}
+
+.sqcom-about-page-instance {
+  display: flex;
+  align-items: stretch;
+}
+
+.sqcom-about-page-instance .about-page-projects {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-width: 190px;
+  margin-left: 15px;
+  padding: 25px;
+  background-color: #fff;
+  color: #686868;
+  font-size: 18px;
+  font-weight: 300;
+}
+
+.sqcom-about-page-instance .about-page-projects-link {
+  font-weight: 400;
+}
+
+.sqcom-about-page-instance .about-page-issue-types > li + li {
+  margin-top: 20px;
+}
+
+.sqcom-about-rules {
+  margin-bottom: 45px;
+  background-color: #3988bc;
+}
+
+.sqcom-about-rules .about-page-container {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.sqcom-about-rules .button {
+  height: 33px;
+  line-height: 30px;
+  padding-left: 15px;
+  padding-right: 15px;
+  border-color: #fff;
+  border-radius: 3px;
+  color: #fff;
+  font-size: 14px;
+  font-weight: bold;
+  text-transform: uppercase;
+}
+
+.sqcom-about-rules .button:hover {
+  background-color: #fff;
+  color: #4b9fd5;
+}
+
+.sqcom-about-rules-link {
+  line-height: 36px;
+  padding: 24px 40px;
+  border: none;
+  color: #c1d9ea;
+  font-size: 20px;
+}
+
+.sqcom-about-rules-link:first-child {
+  margin-left: -40px;
+}
+
+.sqcom-about-rules-link:hover {
+  background-color: #398cc8;
+  color: #fff;
+}
+
+.sqcom-about-rules-link:hover path {
+  fill: #fff;
+}
+
+.sqcom-about-quality-model svg {
+  transform: translateY(-3px) !important;
+}
+
index d09ede5c5f73e866e7cb57f113c762db3898ffae..7d06cd0caf98c28b3d2120d67a81a05e2c09f6e1 100644 (file)
@@ -7,6 +7,8 @@
 }
 
 .about-page .boxed-group h2 {
+  padding-left: 0;
+  padding-right: 0;
   font-size: 18px;
 }
 
@@ -15,6 +17,8 @@
 }
 
 .about-page .boxed-group-inner {
+  padding-left: 0;
+  padding-right: 0;
   padding-bottom: 25px;
 }
 
@@ -81,8 +85,8 @@
   text-align: left;
 }
 
-.about-page-issue-types > li + li {
-  margin-top: 12px;
+.about-page-issue-types tr + tr td {
+  padding-top: 12px;
 }
 
 .about-page-issue-types svg {
@@ -91,9 +95,7 @@
 }
 
 .about-page-issue-type-number {
-  display: inline-block;
-  min-width: 60px;
-  margin-right: 16px;
+  padding-right: 16px;
   text-align: right;
 }
 
   font-weight: bold;
 }
 
-.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 {
-  width: 200px;
-}
-
-.about-page-auth-providers .oauth-provider {
-  width: 100%;
-}
-
-.about-page-auth-providers .oauth-provider + .oauth-provider {
-  margin-top: 20px;
-}
-
 .about-page-section {
-  padding-bottom: 40px;
-}
-
-.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;
+  padding-top: 20px;
+  padding-bottom: 10px;
 }
 
 .about-page-text {
   border-bottom: 1px solid #cae3f2;
 }
 
-.about-page-issues {
-  margin-top: 80px;
-}
-
-.about-page-issues-box {
-  float: left;
-  width: 33%;
-  text-align: center;
-}
-
-.about-page-issues-number {
-  display: inline-block;
-  font-size: 32px;
-  font-weight: bold;
-}
-
-.about-page-issues-description {
-  margin-top: 12px;
-  padding: 0 15px;
-  line-height: 1.4;
-}
-
-.about-page-issues-number + .about-page-issues-description {
-  border-top: none;
-  border-top-left-radius: 0;
-  border-top-right-radius: 0;
-}
-
-.about-page-issues-header {
-  margin-bottom: 20px;
-  font-size: 21px;
-  text-transform: uppercase;
-}
-
 .about-page-languages {
   display: flex;
   justify-content: space-between;