]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9245 Prevent the projects page topbar to keep open when switching app in org...
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 7 Jun 2017 14:55:24 +0000 (16:55 +0200)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Fri, 9 Jun 2017 06:26:48 +0000 (08:26 +0200)
server/sonar-web/src/main/js/apps/organizations/components/OrganizationFavoriteProjects.js
server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js
server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.js
server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsContainer.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationPage-test.js.snap
server/sonar-web/src/main/js/apps/organizations/routes.js
server/sonar-web/src/main/js/apps/projects/components/AllProjects.js
server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.js
server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsOptionBar.js
server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectOptionBar-test.js

index 9c3edfce2aa8988e240bc37b27b0ea2080b2a187..39bcb30a75ac1b1bc6ab2e5657affddcbd9625ab 100644 (file)
  */
 // @flow
 import React from 'react';
-import { connect } from 'react-redux';
 import FavoriteProjectsContainer from '../../projects/components/FavoriteProjectsContainer';
-import { getOrganizationByKey } from '../../../store/rootReducer';
-import { updateOrganization } from '../actions';
 
-class OrganizationFavoriteProjects extends React.PureComponent {
+export default class OrganizationFavoriteProjects extends React.PureComponent {
   props: {
     children?: React.Element<*>,
+    currentUser: { isLoggedIn: boolean },
     location: Object,
     optionBarOpen: boolean,
     optionBarToggle: (open: boolean) => void,
@@ -53,6 +51,7 @@ class OrganizationFavoriteProjects extends React.PureComponent {
     return (
       <div id="projects-page">
         <FavoriteProjectsContainer
+          currentUser={this.props.currentUser}
           location={this.props.location}
           optionBarOpen={this.props.optionBarOpen}
           optionBarToggle={this.props.optionBarToggle}
@@ -62,11 +61,3 @@ class OrganizationFavoriteProjects extends React.PureComponent {
     );
   }
 }
-
-const mapStateToProps = (state, ownProps) => ({
-  organization: getOrganizationByKey(state, ownProps.params.organizationKey)
-});
-
-const mapDispatchToProps = { updateOrganization };
-
-export default connect(mapStateToProps, mapDispatchToProps)(OrganizationFavoriteProjects);
index 55f9cd009025c657b337d01d998853356758c7bb..d08cfabf5d4b7308c78b31535b6f456914c28672 100644 (file)
@@ -40,14 +40,13 @@ type Props = {
 };
 
 type State = {
-  loading: boolean,
-  optionBarOpen: boolean
+  loading: boolean
 };
 
 class OrganizationPage extends React.PureComponent {
   mounted: boolean;
   props: Props;
-  state: State = { loading: true, optionBarOpen: false };
+  state: State = { loading: true };
 
   componentDidMount() {
     this.mounted = true;
@@ -75,8 +74,6 @@ class OrganizationPage extends React.PureComponent {
     });
   };
 
-  handleOptionBarToggle = (open: boolean) => this.setState({ optionBarOpen: open });
-
   render() {
     const { organization } = this.props;
 
@@ -92,11 +89,7 @@ class OrganizationPage extends React.PureComponent {
       <div>
         <Helmet defaultTitle={organization.name} titleTemplate={'%s - ' + organization.name} />
         <OrganizationNavigation organization={organization} location={this.props.location} />
-        {this.props.children &&
-          React.cloneElement(this.props.children, {
-            optionBarOpen: this.state.optionBarOpen,
-            optionBarToggle: this.handleOptionBarToggle
-          })}
+        {this.props.children}
       </div>
     );
   }
index f3286b2ab822bfecb3141ef52ce6b567518706aa..39d5c76ce76b6e5f20341f39f92481d58b758a62 100644 (file)
  */
 // @flow
 import React from 'react';
-import { connect } from 'react-redux';
 import AllProjectsContainer from '../../projects/components/AllProjectsContainer';
-import { getOrganizationByKey } from '../../../store/rootReducer';
-import { updateOrganization } from '../actions';
 
-class OrganizationProjects extends React.PureComponent {
+export default class OrganizationProjects extends React.PureComponent {
   props: {
     children?: React.Element<*>,
+    currentUser: { isLoggedIn: boolean },
     location: Object,
     optionBarOpen: boolean,
     optionBarToggle: (open: boolean) => void,
@@ -53,6 +51,7 @@ class OrganizationProjects extends React.PureComponent {
     return (
       <div id="projects-page">
         <AllProjectsContainer
+          currentUser={this.props.currentUser}
           isFavorite={false}
           location={this.props.location}
           optionBarOpen={this.props.optionBarOpen}
@@ -63,11 +62,3 @@ class OrganizationProjects extends React.PureComponent {
     );
   }
 }
-
-const mapStateToProps = (state, ownProps) => ({
-  organization: getOrganizationByKey(state, ownProps.params.organizationKey)
-});
-
-const mapDispatchToProps = { updateOrganization };
-
-export default connect(mapStateToProps, mapDispatchToProps)(OrganizationProjects);
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsContainer.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsContainer.js
new file mode 100644 (file)
index 0000000..faa2bf8
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+//@flow
+import React from 'react';
+import { connect } from 'react-redux';
+import { getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer';
+import { updateOrganization } from '../actions';
+
+type State = {
+  optionBarOpen: boolean
+};
+
+class OrganizationProjectsContainer extends React.PureComponent {
+  state: State = { optionBarOpen: false };
+
+  handleOptionBarToggle = (open: boolean) => this.setState({ optionBarOpen: open });
+
+  render() {
+    return React.cloneElement(this.props.children, {
+      currentUser: this.props.currentUser,
+      optionBarOpen: this.state.optionBarOpen,
+      optionBarToggle: this.handleOptionBarToggle,
+      organization: this.props.organization
+    });
+  }
+}
+
+const mapStateToProps = (state, ownProps) => ({
+  organization: getOrganizationByKey(state, ownProps.params.organizationKey),
+  currentUser: getCurrentUser(state)
+});
+
+const mapDispatchToProps = { updateOrganization };
+
+export default connect(mapStateToProps, mapDispatchToProps)(OrganizationProjectsContainer);
index 91b20a05ca191745b6cd4d70520e8fba6caab51a..d9579e1bf4a3dbbed550893b1b83a4f699c7fd68 100644 (file)
@@ -28,10 +28,7 @@ exports[`smoke test 2`] = `
       }
     }
   />
-  <div
-    optionBarOpen={false}
-    optionBarToggle={[Function]}
-  >
+  <div>
     hello
   </div>
 </div>
index c01ca215da06276519a9faee737e2963d288c7c3..f58806084563f36dd4afb84e8f0fc355ad86af9f 100644 (file)
@@ -20,6 +20,7 @@
 import OrganizationPage from './components/OrganizationPage';
 import OrganizationPageExtension from '../../app/components/extensions/OrganizationPageExtension';
 import OrganizationProjects from './components/OrganizationProjects';
+import OrganizationProjectsContainer from './components/OrganizationProjectsContainer';
 import OrganizationFavoriteProjects from './components/OrganizationFavoriteProjects';
 import OrganizationRules from './components/OrganizationRules';
 import OrganizationAdmin from './components/OrganizationAdmin';
@@ -47,11 +48,18 @@ const routes = [
       },
       {
         path: 'projects',
-        component: OrganizationProjects
-      },
-      {
-        path: 'projects/favorite',
-        component: OrganizationFavoriteProjects
+        component: OrganizationProjectsContainer,
+        childRoutes: [
+          {
+            indexRoute: {
+              component: OrganizationProjects
+            }
+          },
+          {
+            path: 'favorite',
+            component: OrganizationFavoriteProjects
+          }
+        ]
       },
       {
         path: 'members',
index dd440f839273ec3ff4f8c0769ac31a87fcbe4374..9720d56560bae5f82719f1aebe6f86715d78fd24 100644 (file)
@@ -39,7 +39,7 @@ type Props = {
   optionBarToggle: (open: boolean) => void,
   organization?: { key: string },
   router: { push: ({ pathname: string, query?: {} }) => void },
-  user?: { isLoggedIn: boolean }
+  currentUser?: { isLoggedIn: boolean }
 };
 
 type State = {
@@ -133,7 +133,7 @@ export default class AllProjects extends React.PureComponent {
           onToggleOptionBar={this.props.optionBarToggle}
           open={optionBarOpen}
           selectedSort={selectedSort}
-          user={this.props.user}
+          currentUser={this.props.currentUser}
           view={view}
           visualization={visualization}
         />
index 0a163363c4634f08805a7fb195a496d3add11b49..988891c41d3b52d921f422bc578a5cf174f7e930 100644 (file)
@@ -109,7 +109,7 @@ class DefaultPageSelector extends React.PureComponent {
           location={this.props.location}
           optionBarOpen={this.props.optionBarOpen}
           optionBarToggle={this.props.optionBarToggle}
-          user={this.props.currentUser}
+          currentUser={this.props.currentUser}
         />
       );
     }
index ffad9d0b8d50638894a3402184f917a1ccc8a6b5..bf2a030408bf7e384ba7e7d751c46358c2104fcd 100644 (file)
 import { connect } from 'react-redux';
 import { withRouter } from 'react-router';
 import AllProjects from './AllProjects';
-import { fetchProjects } from '../store/actions';
 import { getCurrentUser } from '../../../store/rootReducer';
+import { fetchProjects } from '../store/actions';
 
 const mapStateToProps = state => ({
-  user: getCurrentUser(state),
-  isFavorite: true
+  isFavorite: true,
+  currentUser: getCurrentUser(state)
 });
 
 export default connect(mapStateToProps, { fetchProjects })(withRouter(AllProjects));
index b076abcb98dbc126db2ec990f9d969939db745ef..98537d80eba118e6fc10dae8d3bdd6a34e163a31 100644 (file)
@@ -33,7 +33,7 @@ type Props = {
   projects: Array<*>,
   projectsAppState: { loading: boolean, total?: number },
   selectedSort: string,
-  user?: { isLoggedIn: boolean },
+  currentUser?: { isLoggedIn: boolean },
   view: string,
   visualization?: string
 };
@@ -48,12 +48,12 @@ export default class ProjectsOptionBar extends React.PureComponent {
   };
 
   renderSortingSelect() {
-    const { projectsAppState, projects, user, view } = this.props;
+    const { projectsAppState, projects, currentUser, view } = this.props;
     const limitReached =
       projects != null &&
       projectsAppState.total != null &&
       projects.length < projectsAppState.total;
-    const defaultOption = user && user.isLoggedIn ? 'name' : 'analysis_date';
+    const defaultOption = currentUser && currentUser.isLoggedIn ? 'name' : 'analysis_date';
     if (view === 'visualizations' && !limitReached) {
       return (
         <Tooltip overlay={translate('projects.sort.disabled')}>
index 14d16176c639e0fe7d5d418f46b3ad30cd707c27..c496b37c7d7b66782c0c14c1c9b74caf9b6cd133 100644 (file)
@@ -35,7 +35,7 @@ it('should render option bar open', () => {
         visualization="risk"
         projects={[1, 2, 3]}
         projectsAppState={{ total: 3 }}
-        user={{ isLoggedIn: true }}
+        currentUser={{ isLoggedIn: true }}
       />
     )
   ).toMatchSnapshot();
@@ -61,7 +61,7 @@ it('should render switch the default sorting option for anonymous users', () =>
         open={true}
         view="overall"
         visualization="risk"
-        user={{ isLoggedIn: true }}
+        currentUser={{ isLoggedIn: true }}
       />
     ).find('ProjectsSortingSelect')
   ).toMatchSnapshot();
@@ -71,7 +71,7 @@ it('should render switch the default sorting option for anonymous users', () =>
         open={true}
         view="leak"
         visualization="risk"
-        user={{ isLoggedIn: false }}
+        currentUser={{ isLoggedIn: false }}
       />
     ).find('ProjectsSortingSelect')
   ).toMatchSnapshot();