From ece8b13900f69483dc52be0d30bb240aacc0756f Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 13 Jun 2018 16:06:41 +0200 Subject: [PATCH] SONARCLOUD-62 move sonarcloud home page (#362) --- server/sonar-web/public/images/sc-icon.svg | 1 - .../public/images/sonarcloud-logo.svg | 1 + ...sc-icon.svg => sonarcloud-square-logo.svg} | 0 .../js/app/components/GlobalContainer.tsx | 4 +- .../src/main/js/app/components/Landing.tsx | 14 +- .../embed-docs-modal/EmbedDocsPopup.tsx | 18 +- .../EmbedDocsPopup-test.tsx.snap | 2 +- server/sonar-web/src/main/js/app/theme.js | 11 +- .../src/main/js/app/utils/startReactApp.js | 2 +- .../main/js/apps/about/components/AboutApp.js | 110 ++++---- .../src/main/js/apps/about/routes.ts | 8 +- .../main/js/apps/about/sonarcloud/Footer.tsx | 171 +++++++++++ .../main/js/apps/about/sonarcloud/Home.tsx | 182 ++++++++++++ .../apps/about/sonarcloud/HomeContainer.tsx | 28 ++ .../sonarcloud/__tests__/Footer-test.tsx | 26 ++ .../about/sonarcloud/__tests__/Home-test.tsx | 38 +++ .../main/js/apps/about/sonarcloud/style.css | 266 ++++++++++++++++++ .../sessions/components/LoginSonarCloud.tsx | 4 +- .../LoginSonarCloud-test.tsx.snap | 6 +- 19 files changed, 817 insertions(+), 75 deletions(-) delete mode 100644 server/sonar-web/public/images/sc-icon.svg create mode 100644 server/sonar-web/public/images/sonarcloud-logo.svg rename server/sonar-web/public/images/{embed-doc/sc-icon.svg => sonarcloud-square-logo.svg} (100%) create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Home-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/about/sonarcloud/style.css diff --git a/server/sonar-web/public/images/sc-icon.svg b/server/sonar-web/public/images/sc-icon.svg deleted file mode 100644 index bc3d84e95d0..00000000000 --- a/server/sonar-web/public/images/sc-icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/server/sonar-web/public/images/sonarcloud-logo.svg b/server/sonar-web/public/images/sonarcloud-logo.svg new file mode 100644 index 00000000000..afbef3e9dfc --- /dev/null +++ b/server/sonar-web/public/images/sonarcloud-logo.svg @@ -0,0 +1 @@ + diff --git a/server/sonar-web/public/images/embed-doc/sc-icon.svg b/server/sonar-web/public/images/sonarcloud-square-logo.svg similarity index 100% rename from server/sonar-web/public/images/embed-doc/sc-icon.svg rename to server/sonar-web/public/images/sonarcloud-square-logo.svg diff --git a/server/sonar-web/src/main/js/app/components/GlobalContainer.tsx b/server/sonar-web/src/main/js/app/components/GlobalContainer.tsx index c8b7167640e..d924a697abf 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalContainer.tsx @@ -27,11 +27,13 @@ import Workspace from '../../components/workspace/Workspace'; interface Props { children: React.ReactNode; + footer?: React.ReactNode; location: { pathname: string }; } export default function GlobalContainer(props: Props) { // it is important to pass `location` down to `GlobalNav` to trigger render on url change + const { footer = } = props; return ( {({ suggestions }) => ( @@ -46,7 +48,7 @@ export default function GlobalContainer(props: Props) { - + {footer} )} diff --git a/server/sonar-web/src/main/js/app/components/Landing.tsx b/server/sonar-web/src/main/js/app/components/Landing.tsx index 55f14b6056d..d4f80be9ab8 100644 --- a/server/sonar-web/src/main/js/app/components/Landing.tsx +++ b/server/sonar-web/src/main/js/app/components/Landing.tsx @@ -20,16 +20,20 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { Location } from 'history'; import { CurrentUser, isLoggedIn } from '../types'; import { getCurrentUser } from '../../store/rootReducer'; import { getHomePageUrl } from '../../helpers/urls'; -import { isSonarCloud } from '../../helpers/system'; -interface Props { +interface StateProps { currentUser: CurrentUser | undefined; } -class Landing extends React.PureComponent { +interface OwnProps { + location: Location; +} + +class Landing extends React.PureComponent { static contextTypes = { router: PropTypes.object.isRequired }; @@ -43,8 +47,6 @@ class Landing extends React.PureComponent { } else { this.context.router.replace('/projects'); } - } else if (isSonarCloud()) { - window.location.href = 'https://about.sonarcloud.io'; } else { this.context.router.replace('/about'); } @@ -59,4 +61,4 @@ const mapStateToProps = (state: any) => ({ currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(Landing); +export default connect(mapStateToProps)(Landing); diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx index cbaea65d18c..061a3af556b 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx @@ -75,7 +75,7 @@ export default class EmbedDocsPopup extends React.PureComponent { alt={text} className="spacer-right" height="18" - src={`${getBaseUrl()}/images/embed-doc/${icon}`} + src={`${getBaseUrl()}/images/${icon}`} width="18" /> {text} @@ -98,12 +98,16 @@ export default class EmbedDocsPopup extends React.PureComponent {
  • {this.renderTitle(translate('embed_docs.stay_connected'))}
  • - {this.renderIconLink('https://twitter.com/sonarcloud', 'twitter-icon.svg', 'Twitter')} + {this.renderIconLink( + 'https://twitter.com/sonarcloud', + 'embed-doc/twitter-icon.svg', + 'Twitter' + )}
  • {this.renderIconLink( 'https://blog.sonarsource.com/product/SonarCloud', - 'sc-icon.svg', + 'sonarcloud-square-logo.svg', translate('embed_docs.news') )}
  • @@ -135,12 +139,16 @@ export default class EmbedDocsPopup extends React.PureComponent {
  • {this.renderIconLink( 'https://www.sonarsource.com/resources/product-news/', - 'sq-icon.svg', + 'embed-doc/sq-icon.svg', translate('embed_docs.news') )}
  • - {this.renderIconLink('https://twitter.com/SonarQube', 'twitter-icon.svg', 'Twitter')} + {this.renderIconLink( + 'https://twitter.com/SonarQube', + 'embed-doc/twitter-icon.svg', + 'Twitter' + )}
  • ); diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap b/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap index 3fc1cca678d..c324ca11c23 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap @@ -106,7 +106,7 @@ exports[`should display correct links for SonarCloud 1`] = ` alt="embed_docs.news" className="spacer-right" height="18" - src="/images/embed-doc/sc-icon.svg" + src="/images/sonarcloud-square-logo.svg" width="18" /> embed_docs.news diff --git a/server/sonar-web/src/main/js/app/theme.js b/server/sonar-web/src/main/js/app/theme.js index e57fc075f6c..76560dcf985 100644 --- a/server/sonar-web/src/main/js/app/theme.js +++ b/server/sonar-web/src/main/js/app/theme.js @@ -106,5 +106,14 @@ module.exports = { modalZIndex: '6001', modalOverlayZIndex: '6000', - popupZIndex: '5000' + popupZIndex: '5000', + + // sonarcloud + sonarcloudOrange: '#f60', + sonarcloudOrangeDark: '#e65c00', + sonarcloudFontFamily: + "Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif", + sonarcloudBlack300: '#cfd3d7', + sonarcloudBlack700: '#434447', + sonarcloudBlack800: '#2d3032' }; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index 611b8a238d1..b4b79feec06 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -153,9 +153,9 @@ const startReactApp = () => { import('../components/Landing'))} /> + - 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 9074488497c..5221f845d5d 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 @@ -33,6 +33,7 @@ import AboutStandards from './AboutStandards'; import AboutScanners from './AboutScanners'; import { searchProjects } from '../../../api/components'; import { getFacet } from '../../../api/issues'; +import GlobalContainer from '../../../app/components/GlobalContainer'; import { getAppState, getCurrentUser, getGlobalSettingValue } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; import { fetchAboutPageSettings } from '../actions'; @@ -61,7 +62,8 @@ class AboutApp extends React.PureComponent { }, currentUser: { isLoggedIn: boolean }, customText?: string, - fetchAboutPageSettings: () => Promise<*> + fetchAboutPageSettings: () => Promise<*>, + location: { pathname: string } }; */ @@ -142,67 +144,69 @@ class AboutApp extends React.PureComponent { } return ( -
    -
    -
    -

    {translate('layout.sonar.slogan')}

    - {!this.props.currentUser.isLoggedIn && ( - - {translate('layout.login')} - - )} - - {translate('about_page.read_documentation')} - + +
    +
    +
    +

    {translate('layout.sonar.slogan')}

    + {!this.props.currentUser.isLoggedIn && ( + + {translate('layout.login')} + + )} + + {translate('about_page.read_documentation')} + +
    + +
    + + +
    -
    - - -
    -
    - - {customText != null && - customText.value && ( -
    - )} + {customText != null && + customText.value && ( +
    + )} - + - + -
    -
    - +
    +
    + +
    +
    + +
    -
    - -
    -
    -
    -
    - -
    -
    - +
    +
    + +
    +
    + +
    -
    - -
    + +
    + ); } } diff --git a/server/sonar-web/src/main/js/apps/about/routes.ts b/server/sonar-web/src/main/js/apps/about/routes.ts index 6d586df600f..ad8591fc26a 100644 --- a/server/sonar-web/src/main/js/apps/about/routes.ts +++ b/server/sonar-web/src/main/js/apps/about/routes.ts @@ -18,10 +18,16 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { lazyLoad } from '../../components/lazyLoad'; +import { isSonarCloud } from '../../helpers/system'; const routes = [ { - indexRoute: { component: lazyLoad(() => import('./components/AboutApp')) } + indexRoute: { + component: lazyLoad( + () => + isSonarCloud() ? import('./sonarcloud/HomeContainer') : import('./components/AboutApp') + ) + } } ]; diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx new file mode 100644 index 00000000000..48cd48d5cc8 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/sonarcloud/Footer.tsx @@ -0,0 +1,171 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { Link } from 'react-router'; +import { getBaseUrl } from '../../../helpers/urls'; + +export default function Footer() { + return ( + + ); +} diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx new file mode 100644 index 00000000000..5118ad30058 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/sonarcloud/Home.tsx @@ -0,0 +1,182 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { Link } from 'react-router'; +import Footer from './Footer'; +import GlobalContainer from '../../../app/components/GlobalContainer'; +import { CurrentUser, isLoggedIn } from '../../../app/types'; +import ChevronRightIcon from '../../../components/icons-components/ChevronRightcon'; +import './style.css'; + +interface Props { + currentUser: CurrentUser; + location: { pathname: string }; +} + +export default class Home extends React.PureComponent { + componentDidMount() { + document.documentElement.classList.add('white-page'); + document.body.classList.add('white-page'); + } + + componentWillUnmount() { + document.documentElement.classList.remove('white-page'); + document.body.classList.remove('white-page'); + } + + render() { + return ( + } location={this.props.location}> +
    +

    Continuous Code Quality Online

    +

    + Analyze the quality of your source code to detect bugs, vulnerabilities
    and code + smells throughout the development process. +

    + +
      +
    • +

      Built on SonarQube

      +

      + The broadly used code review tool to detect bugs, code smells and vulnerability + issues. +

      +
    • + +
    • +

      17 languages

      +

      + Java, JS, C#, C/C++, Objective-C, TypeScript, Python, Go, ABAP, PL/SQL, T-SQL and + more. +

      +
    • + +
    • +

      Thousands of rules

      +

      + Track down hard-to-find bugs and quality issues thanks to powerful static code + analyzers. +

      +
    • + +
    • +

      Cloud CI Integrations

      +

      + Schedule the execution of an analysis from Cloud CI engines: Travis, VSTS, AppVeyor + and more. +

      +
    • + +
    • +

      Deep code analysis

      +

      + Explore all your source files, whether in branches or pull requests, to reach a + green quality gate and promote the build. +

      +
    • + +
    • +

      Fast and Scalable

      +

      Scale on-demand as your projects grow.

      +
    • +
    + +
    +
    +

    Open Source Projects

    +   + Free +
    + +
    +

    Private Projects

    + 14 days free trial + + From 10€/mo + + + see prices + +
    +
    + + {!isLoggedIn(this.props.currentUser) && ( +
    + + Start using SonarCloud + + +
    + )} + +
    +

    Explore open source projects on SonarCloud

    +

    + SonarCloud offers free analysis for open source projects.
    It is public and open + to anyone who wants to browse the service. +

    +
    + +
    + + Browse + +
    + + +
    +
    + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx new file mode 100644 index 00000000000..3fc215348bb --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/sonarcloud/HomeContainer.tsx @@ -0,0 +1,28 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { connect } from 'react-redux'; +import Home from './Home'; +import { getCurrentUser } from '../../../store/rootReducer'; + +const mapStateToProps = (state: any) => ({ + currentUser: getCurrentUser(state) +}); + +export default connect(mapStateToProps)(Home); diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx new file mode 100644 index 00000000000..0d1eb668efa --- /dev/null +++ b/server/sonar-web/src/main/js/apps/about/sonarcloud/__tests__/Footer-test.tsx @@ -0,0 +1,26 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import Footer from '../Footer'; + +it('should render', () => { + expect(shallow(