]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8300 change layout
authorStas Vilchik <vilchiks@gmail.com>
Thu, 3 Nov 2016 10:02:59 +0000 (11:02 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Fri, 4 Nov 2016 08:08:46 +0000 (09:08 +0100)
server/sonar-web/src/main/js/apps/projects/components/App.js
server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js
server/sonar-web/src/main/js/apps/projects/components/FavoriteProjects.js
server/sonar-web/src/main/js/apps/projects/components/PageHeader.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsList.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeader.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeaderContainer.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/styles.css

index a651366211222dbb258da376f69f9c01b3efd87e..c4ca1fbf0f6ea64eced98385d782b2a7631994bd 100644 (file)
@@ -23,7 +23,7 @@ import PageHeaderContainer from './PageHeaderContainer';
 import ProjectsListContainer from './ProjectsListContainer';
 import ProjectsListFooterContainer from './ProjectsListFooterContainer';
 import PageSidebarContainer from './PageSidebarContainer';
-import FavoriteFilterContainer from './FavoriteFilterContainer';
+import ProjectsListHeaderContainer from './ProjectsListHeaderContainer';
 import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
 import { parseUrlQuery } from '../store/utils';
 import { translate } from '../../../helpers/l10n';
@@ -69,17 +69,18 @@ export default class App extends React.Component {
         <div id="projects-page" className="page page-limited">
           <Helmet title={translate('projects.page')} titleTemplate="SonarQube - %s"/>
 
-          <PageHeaderContainer/>
-
           <GlobalMessagesContainer/>
 
           <div className="page-with-sidebar page-with-left-sidebar">
             <div className="page-main">
-              <ProjectsListContainer/>
-              <ProjectsListFooterContainer query={this.state.query}/>
+              <div className="projects-list-container">
+                <ProjectsListHeaderContainer/>
+                <ProjectsListContainer/>
+                <ProjectsListFooterContainer query={this.state.query}/>
+              </div>
             </div>
             <aside className="page-sidebar-fixed projects-sidebar">
-              <FavoriteFilterContainer/>
+              <PageHeaderContainer/>
               <PageSidebarContainer query={this.state.query}/>
             </aside>
           </div>
index 2ef4f12053ebcf989b6d0b46a8c66e46da7114a0..d13afa6e872a4a42ba6c0221fa11dc8f03be9071 100644 (file)
@@ -27,7 +27,7 @@ export default class FavoriteFilter extends React.Component {
     }
 
     return (
-      <div className="button-group projects-favorite-filter">
+      <div className="button-group">
         <IndexLink to="/projects" className="button" activeClassName="button-active">All</IndexLink>
         <Link to="/projects/favorite" className="button" activeClassName="button-active">Favorite</Link>
       </div>
index a6a04e47390ede6b794394e51fe3a095bd9dfc22..8e82cefd4c5684dfa9b89d1769e044ddb4b52d3f 100644 (file)
@@ -21,7 +21,7 @@ import React from 'react';
 import Helmet from 'react-helmet';
 import PageHeaderContainer from './PageHeaderContainer';
 import ProjectsListContainer from './ProjectsListContainer';
-import FavoriteFilterContainer from './FavoriteFilterContainer';
+import ProjectsListHeaderContainer from './ProjectsListHeaderContainer';
 import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
 import { translate } from '../../../helpers/l10n';
 import '../styles.css';
@@ -50,17 +50,17 @@ export default class FavoriteProjects extends React.Component {
         <div id="projects-page" className="page page-limited">
           <Helmet title={translate('projects.page')} titleTemplate="SonarQube - %s"/>
 
-          <PageHeaderContainer/>
-
           <GlobalMessagesContainer/>
 
           <div className="page-with-sidebar page-with-left-sidebar">
             <div className="page-main">
-              <ProjectsListContainer/>
+              <div className="projects-list-container">
+                <ProjectsListHeaderContainer/>
+                <ProjectsListContainer/>
+              </div>
             </div>
             <aside className="page-sidebar-fixed projects-sidebar">
-              <FavoriteFilterContainer/>
-
+              <PageHeaderContainer/>
               <p className="note text-center">Filters are not available.</p>
             </aside>
           </div>
index 4043e0176f9c62af3204ca210807c2592965b5ab..9ffdb687169fcc2b7d756e1dc1b186a3b9253aa5 100644 (file)
@@ -22,12 +22,11 @@ import { translate } from '../../../helpers/l10n';
 
 export default class PageHeader extends React.Component {
   static propTypes = {
-    total: React.PropTypes.number,
     loading: React.PropTypes.bool
   };
 
   render () {
-    const { total, loading } = this.props;
+    const { loading } = this.props;
 
     return (
         <header className="page-header">
@@ -36,16 +35,6 @@ export default class PageHeader extends React.Component {
           {!!loading && (
               <i className="spinner"/>
           )}
-
-          <div className="page-actions">
-            {total != null && (
-                <span><strong>{total}</strong> {translate('projects._projects')}</span>
-            )}
-          </div>
-
-          <div className="page-description">
-            {translate('projects.page.description')}
-          </div>
         </header>
     );
   }
index 9a7d69d9855e5dd5c273a1d76cfd96194b584912..859b4980200e512213f32f8b4ec14d4e42a632fc 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import React from 'react';
-import { List, AutoSizer, WindowScroller } from 'react-virtualized';
 import ProjectCardContainer from './ProjectCardContainer';
 import { translate } from '../../../helpers/l10n';
 
 export default class ProjectsList extends React.Component {
   static propTypes = {
-    projects: React.PropTypes.arrayOf(React.PropTypes.string)
+    projects: React.PropTypes.arrayOf(React.PropTypes.string),
   };
 
   render () {
@@ -34,43 +33,19 @@ export default class ProjectsList extends React.Component {
       return null;
     }
 
-    if (projects.length === 0) {
-      return (
-          <div className="projects-empty-list">
-            <h3>{translate('projects.no_projects.1')}</h3>
-            <p className="big-spacer-top">{translate('projects.no_projects.2')}</p>
-          </div>
-      );
-    }
-
-    const rowRenderer = ({ key, index, style }) => {
-      const projectKey = projects[index];
-      return (
-          <div key={key} style={style}>
-            <ProjectCardContainer projectKey={projectKey}/>
-          </div>
-      );
-    };
-
     return (
-        <WindowScroller>
-          {({ height, scrollTop }) => (
-              <AutoSizer disableHeight>
-                {({ width }) => (
-                    <List
-                        className="projects-list"
-                        autoHeight
-                        width={width}
-                        height={height}
-                        rowCount={projects.length}
-                        rowHeight={135}
-                        rowRenderer={rowRenderer}
-                        scrollTop={scrollTop}
-                        overscanRowCount={100}/>
-                )}
-              </AutoSizer>
+        <div className="projects-list">
+          {projects.length > 0 ? (
+              projects.map(projectKey => (
+                  <ProjectCardContainer key={projectKey} projectKey={projectKey}/>
+              ))
+          ) : (
+              <div className="projects-empty-list">
+                <h3>{translate('projects.no_projects.1')}</h3>
+                <p className="big-spacer-top">{translate('projects.no_projects.2')}</p>
+              </div>
           )}
-        </WindowScroller>
+        </div>
     );
   }
 }
index bdeb573a65a4a364c103816e11e26bc254dbef0e..3bbd31c328042542ab6330e665ccfe016488cb98 100644 (file)
  */
 import { connect } from 'react-redux';
 import ProjectsList from './ProjectsList';
-import { getProjects } from '../../../app/store/rootReducer';
+import { getProjects, getProjectsAppState } from '../../../app/store/rootReducer';
 
 export default connect(
     state => ({
-      projects: getProjects(state)
+      projects: getProjects(state),
+      total: getProjectsAppState(state).total
     })
 )(ProjectsList);
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeader.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeader.js
new file mode 100644 (file)
index 0000000..518bcb0
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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 FavoriteFilterContainer from './FavoriteFilterContainer';
+import { translate } from '../../../helpers/l10n';
+
+export default class ProjectsListHeader extends React.Component {
+  static propTypes = {
+    total: React.PropTypes.number
+  };
+
+  render () {
+    return (
+        <header className="page-header">
+          <div className="page-actions">
+            {this.props.total != null && (
+              <span>
+                <strong>{this.props.total}</strong> {translate('projects._projects')}
+              </span>
+            )}
+          </div>
+          <FavoriteFilterContainer/>
+        </header>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeaderContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeaderContainer.js
new file mode 100644 (file)
index 0000000..f21a819
--- /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.
+ */
+import { connect } from 'react-redux';
+import ProjectsListHeader from './ProjectsListHeader';
+import { getProjectsAppState } from '../../../app/store/rootReducer';
+
+const mapStateToProps = state => (
+    getProjectsAppState(state)
+);
+
+export default connect(
+    mapStateToProps
+)(ProjectsListHeader);
index ac52d3a74d11ef4902d88d90761dc0b556871637..38a02765bc2835bdc66ebb04a42efb22c163a7e6 100644 (file)
@@ -2,8 +2,12 @@
   width: 260px;
 }
 
-.projects-list {
-  outline: none;
+.projects-list-container {
+  width: 740px;
+}
+
+.projects-list .page-actions {
+  margin-bottom: 0;
 }
 
 .projects-empty-list {
 .projects-facets-reset .button {
 
 }
-
-.projects-favorite-filter {
-  width: 100%;
-  margin-bottom: 30px;
-  padding-left: 10px;
-  padding-right: 10px;
-  box-sizing: border-box;
-}
-
-.projects-favorite-filter > a {
-  width: 50%;
-}