]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10284 Retreive onSonarCloud param in SimpleContainer
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Fri, 12 Jan 2018 16:50:03 +0000 (17:50 +0100)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Mon, 15 Jan 2018 10:40:43 +0000 (11:40 +0100)
server/sonar-web/src/main/js/app/components/App.tsx
server/sonar-web/src/main/js/app/components/GlobalFooter.tsx
server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx
server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx
server/sonar-web/src/main/js/app/components/SimpleContainer.tsx
server/sonar-web/src/main/js/app/components/__tests__/GlobalFooter-test.tsx
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalFooterSonarCloud-test.tsx.snap
server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.tsx

index b23af2a3dcab4c617f419620ce9275df628572f7..2b83e2a64689db2b9259082993aeeb3963a7fb41 100644 (file)
@@ -91,9 +91,9 @@ class App extends React.PureComponent<Props, State> {
         this.setState({
           branchesEnabled: appState.branchesEnabled,
           canAdmin: appState.canAdmin,
-          onSonarCloud:
-            appState.settings !== undefined &&
-            appState.settings['sonar.sonarcloud.enabled'] === 'true'
+          onSonarCloud: Boolean(
+            appState.settings && appState.settings['sonar.sonarcloud.enabled'] === 'true'
+          )
         });
       }
       return appState;
index 4f5488484529cd5ee9f3429f841b46164b438b3d..eacbe1883b092b10e4ab5076937f725e80d89414 100644 (file)
@@ -18,6 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import * as PropTypes from 'prop-types';
 import { Link } from 'react-router';
 import GlobalFooterSonarCloud from './GlobalFooterSonarCloud';
 import GlobalFooterBranding from './GlobalFooterBranding';
@@ -26,72 +27,73 @@ import { translate, translateWithParameters } from '../../helpers/l10n';
 interface Props {
   hideLoggedInInfo?: boolean;
   productionDatabase: boolean;
-  onSonarCloud?: { value: string };
   sonarqubeVersion?: string;
 }
 
-export default function GlobalFooter({
-  hideLoggedInInfo,
-  productionDatabase,
-  onSonarCloud,
-  sonarqubeVersion
-}: Props) {
-  if (onSonarCloud && onSonarCloud.value === 'true') {
-    return <GlobalFooterSonarCloud />;
-  }
+export default class GlobalFooter extends React.PureComponent<Props> {
+  static contextTypes = {
+    onSonarCloud: PropTypes.bool
+  };
 
-  return (
-    <div id="footer" className="page-footer page-container">
-      {productionDatabase === false && (
-        <div className="alert alert-danger">
-          <p className="big" id="evaluation_warning">
-            {translate('footer.production_database_warning')}
-          </p>
-          <p>{translate('footer.production_database_explanation')}</p>
-        </div>
-      )}
+  render() {
+    const { hideLoggedInInfo, productionDatabase, sonarqubeVersion } = this.props;
+    if (this.context.onSonarCloud) {
+      return <GlobalFooterSonarCloud />;
+    }
 
-      <GlobalFooterBranding />
+    return (
+      <div id="footer" className="page-footer page-container">
+        {productionDatabase === false && (
+          <div className="alert alert-danger">
+            <p className="big" id="evaluation_warning">
+              {translate('footer.production_database_warning')}
+            </p>
+            <p>{translate('footer.production_database_explanation')}</p>
+          </div>
+        )}
 
-      <ul className="page-footer-menu">
-        {!hideLoggedInInfo &&
-          sonarqubeVersion && (
-            <li className="page-footer-menu-item">
-              {translateWithParameters('footer.version_x', sonarqubeVersion)}
-            </li>
-          )}
-        <li className="page-footer-menu-item">
-          <a href="http://www.gnu.org/licenses/lgpl-3.0.txt">{translate('footer.license')}</a>
-        </li>
-        <li className="page-footer-menu-item">
-          <a href="http://www.sonarqube.org">{translate('footer.community')}</a>
-        </li>
-        <li className="page-footer-menu-item">
-          <a href="https://redirect.sonarsource.com/doc/home.html">
-            {translate('footer.documentation')}
-          </a>
-        </li>
-        <li className="page-footer-menu-item">
-          <a href="https://redirect.sonarsource.com/doc/community.html">
-            {translate('footer.support')}
-          </a>
-        </li>
-        <li className="page-footer-menu-item">
-          <a href="https://redirect.sonarsource.com/doc/plugin-library.html">
-            {translate('footer.plugins')}
-          </a>
-        </li>
-        {!hideLoggedInInfo && (
+        <GlobalFooterBranding />
+
+        <ul className="page-footer-menu">
+          {!hideLoggedInInfo &&
+            sonarqubeVersion && (
+              <li className="page-footer-menu-item">
+                {translateWithParameters('footer.version_x', sonarqubeVersion)}
+              </li>
+            )}
           <li className="page-footer-menu-item">
-            <Link to="/web_api">{translate('footer.web_api')}</Link>
+            <a href="http://www.gnu.org/licenses/lgpl-3.0.txt">{translate('footer.license')}</a>
           </li>
-        )}
-        {!hideLoggedInInfo && (
           <li className="page-footer-menu-item">
-            <Link to="/about">{translate('footer.about')}</Link>
+            <a href="http://www.sonarqube.org">{translate('footer.community')}</a>
           </li>
-        )}
-      </ul>
-    </div>
-  );
+          <li className="page-footer-menu-item">
+            <a href="https://redirect.sonarsource.com/doc/home.html">
+              {translate('footer.documentation')}
+            </a>
+          </li>
+          <li className="page-footer-menu-item">
+            <a href="https://redirect.sonarsource.com/doc/community.html">
+              {translate('footer.support')}
+            </a>
+          </li>
+          <li className="page-footer-menu-item">
+            <a href="https://redirect.sonarsource.com/doc/plugin-library.html">
+              {translate('footer.plugins')}
+            </a>
+          </li>
+          {!hideLoggedInInfo && (
+            <li className="page-footer-menu-item">
+              <Link to="/web_api">{translate('footer.web_api')}</Link>
+            </li>
+          )}
+          {!hideLoggedInInfo && (
+            <li className="page-footer-menu-item">
+              <Link to="/about">{translate('footer.about')}</Link>
+            </li>
+          )}
+        </ul>
+      </div>
+    );
+  }
 }
index cde158c45fc23b0a58cf3691a79d28d7edd2d070..9524c6de7b69f01cc5ca3e449e16e3e1c58bad3a 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { connect } from 'react-redux';
-import { getAppState, getGlobalSettingValue } from '../../store/rootReducer';
+import { getAppState } from '../../store/rootReducer';
 import GlobalFooter from './GlobalFooter';
 
 interface StateProps {
-  onSonarCloud?: { value: string };
   productionDatabase: boolean;
   sonarqubeVersion?: string;
 }
 
+interface OwnProps {
+  hideLoggedInInfo?: boolean;
+}
+
 const mapStateToProps = (state: any): StateProps => ({
   sonarqubeVersion: getAppState(state).version,
-  productionDatabase: getAppState(state).productionDatabase,
-  onSonarCloud: getGlobalSettingValue(state, 'sonar.sonarcloud.enabled')
+  productionDatabase: getAppState(state).productionDatabase
 });
 
-export default connect(mapStateToProps)(GlobalFooter);
+export default connect<StateProps, {}, OwnProps>(mapStateToProps)(GlobalFooter);
index 875a0aecb511fd3f4cf61d2209167c1fc312ca1f..c98b44150591cdc41bc847d9718773783fa07dcf 100644 (file)
@@ -24,7 +24,7 @@ export default function GlobalFooterSonarCloud() {
   return (
     <div id="footer" className="page-footer page-container">
       <div>
-        © 2008-2018, SonarCloud.io by{' '}
+        © 2008-2018, SonarCloud by{' '}
         <a href="http://www.sonarsource.com" title="SonarSource SA">
           SonarSource SA
         </a>
index 778bec695898bf786c245b3c799b937b05ebf35c..883fdfc3e24bf31527a9a03c9b8f03932a0d6d3e 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import GlobalFooterContainer from './GlobalFooterContainer';
+import * as PropTypes from 'prop-types';
 import * as theme from '../theme';
+import GlobalLoading from './GlobalLoading';
+import GlobalFooterContainer from './GlobalFooterContainer';
+import { tryGetGlobalNavigation } from '../../api/nav';
 import NavBar from '../../components/nav/NavBar';
 
 interface Props {
@@ -27,19 +30,62 @@ interface Props {
   hideLoggedInInfo?: boolean;
 }
 
-export default function SimpleContainer(props: Props) {
-  return (
-    <div className="global-container">
-      <div className="page-wrapper" id="container">
-        <NavBar className="navbar-global" height={theme.globalNavHeightRaw} />
+interface State {
+  loading: boolean;
+  onSonarCloud: boolean;
+}
+
+export default class SimpleContainer extends React.PureComponent<Props, State> {
+  mounted: boolean;
+
+  static childContextTypes = {
+    onSonarCloud: PropTypes.bool
+  };
+
+  state: State = { loading: true, onSonarCloud: false };
+
+  getChildContext() {
+    return { onSonarCloud: this.state.onSonarCloud };
+  }
+
+  componentDidMount() {
+    this.mounted = true;
+    tryGetGlobalNavigation().then(
+      appState => {
+        if (this.mounted) {
+          this.setState({
+            loading: false,
+            onSonarCloud: Boolean(
+              appState.settings && appState.settings['sonar.sonarcloud.enabled'] === 'true'
+            )
+          });
+        }
+      },
+      () => {}
+    );
+  }
+
+  componentWillUnmount() {
+    this.mounted = false;
+  }
+
+  render() {
+    if (this.state.loading) {
+      return <GlobalLoading />;
+    }
+    return (
+      <div className="global-container">
+        <div className="page-wrapper" id="container">
+          <NavBar className="navbar-global" height={theme.globalNavHeightRaw} />
 
-        <div id="bd" className="page-wrapper-simple">
-          <div id="nonav" className="page-simple">
-            {props.children}
+          <div id="bd" className="page-wrapper-simple">
+            <div id="nonav" className="page-simple">
+              {this.props.children}
+            </div>
           </div>
         </div>
+        <GlobalFooterContainer hideLoggedInInfo={this.props.hideLoggedInInfo} />
       </div>
-      <GlobalFooterContainer hideLoggedInInfo={props.hideLoggedInInfo} />
-    </div>
-  );
+    );
+  }
 }
index 5a1ca5ac2dd7f07981a1802379d78184f36fa07b..81bc6f95a7f86202914648f88638cd49af8ccf17 100644 (file)
@@ -22,34 +22,29 @@ import { shallow } from 'enzyme';
 import GlobalFooter from '../GlobalFooter';
 
 it('should render the only logged in information', () => {
-  expect(shallow(<GlobalFooter productionDatabase={true} />)).toMatchSnapshot();
+  expect(getWrapper()).toMatchSnapshot();
 });
 
 it('should not render the only logged in information', () => {
   expect(
-    shallow(
-      <GlobalFooter
-        hideLoggedInInfo={true}
-        productionDatabase={true}
-        onSonarCloud={{ value: 'false' }}
-        sonarqubeVersion="6.4-SNAPSHOT"
-      />
-    )
+    getWrapper({ hideLoggedInInfo: true, sonarqubeVersion: '6.4-SNAPSHOT' })
   ).toMatchSnapshot();
 });
 
 it('should show the db warning message', () => {
-  expect(shallow(<GlobalFooter productionDatabase={false} />).find('.alert')).toMatchSnapshot();
+  expect(getWrapper({ productionDatabase: false }).find('.alert')).toMatchSnapshot();
 });
 
 it('should display the sq version', () => {
-  expect(
-    shallow(<GlobalFooter productionDatabase={true} sonarqubeVersion="6.4-SNAPSHOT" />)
-  ).toMatchSnapshot();
+  expect(getWrapper({ sonarqubeVersion: '6.4-SNAPSHOT' })).toMatchSnapshot();
 });
 
 it('should render SonarCloud footer', () => {
-  expect(
-    shallow(<GlobalFooter productionDatabase={true} onSonarCloud={{ value: 'true' }} />)
-  ).toMatchSnapshot();
+  expect(getWrapper({}, true)).toMatchSnapshot();
 });
+
+function getWrapper(props = {}, onSonarCloud = false) {
+  return shallow(<GlobalFooter productionDatabase={true} {...props} />, {
+    context: { onSonarCloud }
+  });
+}
index f6c798120a54acefd6e00a5822d200d2d3fb08d8..7af6f907dfc2e16fe6770690d13a4bf0e5ebfe04 100644 (file)
@@ -6,7 +6,7 @@ exports[`should render correctly 1`] = `
   id="footer"
 >
   <div>
-    © 2008-2018, SonarCloud.io by
+    © 2008-2018, SonarCloud by
      
     <a
       href="http://www.sonarsource.com"
index 5748b591d542fb40fb3a72f656c3e32599cc5b07..bedb56c1fb69475beefa3de52ddf52678d4b2239 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import * as PropTypes from 'prop-types';
 import { connect } from 'react-redux';
 import LoginForm from './LoginForm';
 import { doLogin } from '../../../store/rootActions';
-import { tryGetGlobalNavigation } from '../../../api/nav';
 import { IdentityProvider, getIdentityProviders } from '../../../api/users';
 import { getBaseUrl } from '../../../helpers/urls';
 
@@ -32,25 +32,28 @@ interface Props {
 
 interface State {
   identityProviders?: IdentityProvider[];
-  onSonarCloud: boolean;
 }
 
 class LoginFormContainer extends React.PureComponent<Props, State> {
   mounted: boolean;
-  state: State = { onSonarCloud: false };
+
+  static contextTypes = {
+    onSonarCloud: PropTypes.bool
+  };
+
+  state: State = {};
 
   componentDidMount() {
     this.mounted = true;
-    Promise.all([getIdentityProviders(), tryGetGlobalNavigation()]).then(
-      ([identityProvidersResponse, appState]) => {
+    getIdentityProviders().then(
+      identityProvidersResponse => {
         if (this.mounted) {
           this.setState({
-            onSonarCloud:
-              appState.settings && appState.settings['sonar.sonarcloud.enabled'] === 'true',
             identityProviders: identityProvidersResponse.identityProviders
           });
         }
-      }
+      },
+      () => {}
     );
   }
 
@@ -73,7 +76,7 @@ class LoginFormContainer extends React.PureComponent<Props, State> {
   };
 
   render() {
-    const { identityProviders, onSonarCloud } = this.state;
+    const { identityProviders } = this.state;
     if (!identityProviders) {
       return null;
     }
@@ -81,7 +84,7 @@ class LoginFormContainer extends React.PureComponent<Props, State> {
     return (
       <LoginForm
         identityProviders={identityProviders}
-        onSonarCloud={onSonarCloud}
+        onSonarCloud={this.context.onSonarCloud}
         onSubmit={this.handleSubmit}
         returnTo={this.getReturnUrl()}
       />