diff options
Diffstat (limited to 'server')
18 files changed, 165 insertions, 244 deletions
diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js new file mode 100644 index 00000000000..2e492352251 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js @@ -0,0 +1,70 @@ +/* + * 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 ProjectsListContainer from './ProjectsListContainer'; +import ProjectsListFooterContainer from './ProjectsListFooterContainer'; +import PageSidebar from './PageSidebar'; +import { parseUrlQuery } from '../store/utils'; +import '../styles.css'; + +export default class AllProjects extends React.Component { + static propTypes = { + user: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.bool]), + fetchProjects: React.PropTypes.func.isRequired + }; + + state = { + query: {} + }; + + componentDidMount () { + this.handleQueryChange(); + } + + componentDidUpdate (prevProps) { + if (prevProps.location.query !== this.props.location.query) { + this.handleQueryChange(); + } + } + + handleQueryChange () { + const query = parseUrlQuery(this.props.location.query); + this.setState({ query }); + this.props.fetchProjects(query); + } + + render () { + if (this.props.user == null) { + return null; + } + + return ( + <div className="page-with-sidebar projects-page"> + <div className="page-main"> + <ProjectsListContainer/> + <ProjectsListFooterContainer query={this.state.query}/> + </div> + <aside className="page-sidebar-fixed projects-sidebar"> + <PageSidebar query={this.state.query}/> + </aside> + </div> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/projects/components/AppContainer.js b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.js index 12a9cd32bbb..5201152e943 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.js @@ -18,13 +18,15 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { connect } from 'react-redux'; -import App from './App'; +import AllProjects from './AllProjects'; import { fetchProjects } from '../store/actions'; import { getCurrentUser } from '../../../app/store/rootReducer'; +const mapStateToProps = state => ({ + user: getCurrentUser(state) +}); + export default connect( - state => ({ - user: getCurrentUser(state) - }), + mapStateToProps, { fetchProjects } -)(App); +)(AllProjects); diff --git a/server/sonar-web/src/main/js/apps/projects/components/App.js b/server/sonar-web/src/main/js/apps/projects/components/App.js index 665683cd689..3bc99f5782b 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/App.js +++ b/server/sonar-web/src/main/js/apps/projects/components/App.js @@ -20,70 +20,34 @@ import React from 'react'; import Helmet from 'react-helmet'; import PageHeaderContainer from './PageHeaderContainer'; -import ProjectsListContainer from './ProjectsListContainer'; -import ProjectsListFooterContainer from './ProjectsListFooterContainer'; -import PageSidebar from './PageSidebar'; -import ProjectsListHeaderContainer from './ProjectsListHeaderContainer'; import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer'; -import { parseUrlQuery } from '../store/utils'; import { translate } from '../../../helpers/l10n'; import '../styles.css'; export default class App extends React.Component { - static propTypes = { - user: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.bool]), - fetchProjects: React.PropTypes.func.isRequired - }; - - state = { - query: {} - }; - componentDidMount () { document.querySelector('html').classList.add('dashboard-page'); - this.handleQueryChange(); - } - - componentDidUpdate (prevProps) { - if (prevProps.location.query !== this.props.location.query) { - this.handleQueryChange(); - } } componentWillUnmount () { document.querySelector('html').classList.remove('dashboard-page'); } - handleQueryChange () { - const query = parseUrlQuery(this.props.location.query); - this.setState({ query }); - this.props.fetchProjects(query); - } - render () { - if (this.props.user == null) { - return null; - } - return ( <div id="projects-page" className="page page-limited"> - <Helmet title={translate('projects.page')} titleTemplate="SonarQube - %s"/> + <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube"/> <GlobalMessagesContainer/> - <div className="page-with-sidebar page-with-left-sidebar"> + <div className="page-with-sidebar"> <div className="page-main"> - <div className="projects-list-container"> - <ProjectsListHeaderContainer/> - <ProjectsListContainer/> - <ProjectsListFooterContainer query={this.state.query}/> - </div> - </div> - <aside className="page-sidebar-fixed projects-sidebar"> <PageHeaderContainer/> - <PageSidebar query={this.state.query}/> - </aside> + </div> + <aside className="page-sidebar-fixed projects-sidebar"/> </div> + + {this.props.children} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js index a2355a8ef4e..3e665bd47a0 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js @@ -19,6 +19,7 @@ */ import React from 'react'; import { IndexLink, Link } from 'react-router'; +import { translate } from '../../../helpers/l10n'; export default class FavoriteFilter extends React.Component { render () { @@ -27,11 +28,14 @@ export default class FavoriteFilter extends React.Component { } return ( - <div> - <span className="note spacer-right">Quick Filters:</span> + <div className="pull-left big-spacer-left"> <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> + <Link to="/projects/favorite" className="button" activeClassName="button-active"> + {translate('favorite')} + </Link> + <IndexLink to="/projects" className="button" activeClassName="button-active"> + {translate('all')} + </IndexLink> </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjects.js b/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjects.js index 2e1410d8e0c..22fd723958b 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjects.js +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjects.js @@ -18,12 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import Helmet from 'react-helmet'; -import PageHeaderContainer from './PageHeaderContainer'; import ProjectsListContainer from './ProjectsListContainer'; -import ProjectsListHeaderContainer from './ProjectsListHeaderContainer'; -import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer'; -import { translate } from '../../../helpers/l10n'; import '../styles.css'; export default class FavoriteProjects extends React.Component { @@ -33,42 +28,22 @@ export default class FavoriteProjects extends React.Component { }; componentDidMount () { - document.querySelector('html').classList.add('dashboard-page'); this.props.fetchFavoriteProjects(); } - componentWillUnmount () { - document.querySelector('html').classList.remove('dashboard-page'); - } - render () { if (!this.props.user) { return null; } return ( - <div id="projects-page" className="page page-limited"> - <Helmet title={translate('projects.page')} titleTemplate="SonarQube - %s"/> - - <GlobalMessagesContainer/> - - <div className="page-with-sidebar page-with-left-sidebar"> - <div className="page-main"> - <div className="projects-list-container"> - <ProjectsListHeaderContainer/> - <ProjectsListContainer/> - </div> + <div className="page-with-sidebar"> + <div className="page-main"> + <div className="projects-list-container"> + <ProjectsListContainer/> </div> - <aside className="page-sidebar-fixed projects-sidebar"> - <PageHeaderContainer/> - <div className="search-navigator-facets-list"> - <div className="projects-facets-header"> - <h3>Filters</h3> - </div> - <p className="note text-center">Filters are not available.</p> - </div> - </aside> </div> + <aside className="page-sidebar-fixed projects-sidebar"/> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js index 9ffdb687169..346ed06e7e4 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js @@ -18,11 +18,13 @@ * 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 PageHeader extends React.Component { static propTypes = { - loading: React.PropTypes.bool + loading: React.PropTypes.bool, + total: React.PropTypes.number }; render () { @@ -30,11 +32,21 @@ export default class PageHeader extends React.Component { return ( <header className="page-header"> + <div className="page-actions"> + {!!loading && ( + <i className="spinner spacer-right"/> + )} + + {this.props.total != null && ( + <span> + <strong>{this.props.total}</strong> {translate('projects._projects')} + </span> + )} + </div> + <h1 className="page-title">{translate('projects.page')}</h1> - {!!loading && ( - <i className="spinner"/> - )} + <FavoriteFilterContainer/> </header> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js index 087f1cc7904..2f44ca9798e 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js +++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js @@ -26,6 +26,7 @@ import QualityGateFilter from '../filters/QualityGateFilter'; import ReliabilityFilter from '../filters/ReliabilityFilter'; import SecurityFilter from '../filters/SecurityFilter'; import MaintainabilityFilter from '../filters/MaintainabilityFilter'; +import { translate } from '../../../helpers/l10n'; export default class PageSidebar extends React.Component { static propTypes = { @@ -41,12 +42,12 @@ export default class PageSidebar extends React.Component { {isFiltered && ( <div className="projects-facets-reset"> <Link to="/projects" className="button button-red"> - Clear All Filters + {translate('projects.clear_all_filters')} </Link> </div> )} - <h3>Filters</h3> + <h3>{translate('filters')}</h3> </div> <QualityGateFilter query={this.props.query}/> 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 deleted file mode 100644 index 518bcb016b4..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeader.js +++ /dev/null @@ -1,43 +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 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 deleted file mode 100644 index f21a81996eb..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListHeaderContainer.js +++ /dev/null @@ -1,30 +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 { connect } from 'react-redux'; -import ProjectsListHeader from './ProjectsListHeader'; -import { getProjectsAppState } from '../../../app/store/rootReducer'; - -const mapStateToProps = state => ( - getProjectsAppState(state) -); - -export default connect( - mapStateToProps -)(ProjectsListHeader); diff --git a/server/sonar-web/src/main/js/apps/projects/routes.js b/server/sonar-web/src/main/js/apps/projects/routes.js index cc1ecd10506..114e82ca197 100644 --- a/server/sonar-web/src/main/js/apps/projects/routes.js +++ b/server/sonar-web/src/main/js/apps/projects/routes.js @@ -19,12 +19,13 @@ */ import React from 'react'; import { Route, IndexRoute } from 'react-router'; -import AppContainer from './components/AppContainer'; +import App from './components/App'; +import AllProjectsContainer from './components/AllProjectsContainer'; import FavoriteProjectsContainer from './components/FavoriteProjectsContainer'; export default ( - <Route path="projects"> - <IndexRoute component={AppContainer}/> + <Route path="projects" component={App}> + <IndexRoute component={AllProjectsContainer}/> <Route path="favorite" component={FavoriteProjectsContainer}/> </Route> ); diff --git a/server/sonar-web/src/main/js/apps/projects/store/actions.js b/server/sonar-web/src/main/js/apps/projects/store/actions.js index 003cdceba64..561937468f3 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/actions.js +++ b/server/sonar-web/src/main/js/apps/projects/store/actions.js @@ -22,8 +22,8 @@ import { searchProjects } from '../../../api/components'; import { addGlobalErrorMessage } from '../../../components/store/globalMessages'; import { parseError } from '../../code/utils'; import { receiveComponents } from '../../../app/store/components/actions'; -import { receiveProjects, receiveMoreProjects } from './projects/actions'; -import { updateState } from './state/actions'; +import { receiveProjects, receiveMoreProjects } from './projectsDuck'; +import { updateState } from './stateDuck'; import { getProjectsAppState } from '../../../app/store/rootReducer'; import { getMeasuresForProjects } from '../../../api/measures'; import { receiveComponentsMeasures } from '../../../app/store/measures/actions'; diff --git a/server/sonar-web/src/main/js/apps/projects/store/facets/reducer.js b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js index 802e8d36edd..9a12aa620bf 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/facets/reducer.js +++ b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js @@ -19,9 +19,9 @@ */ import flatMap from 'lodash/flatMap'; import sumBy from 'lodash/sumBy'; -import { createMap } from '../../../../components/store/generalReducers'; -import { RECEIVE_PROJECTS } from '../projects/actions'; -import { mapMetricToProperty } from '../utils'; +import { createMap } from '../../../components/store/generalReducers'; +import { actions } from './projectsDuck'; +import { mapMetricToProperty } from './utils'; const CUMULATIVE_FACETS = [ 'reliability', @@ -70,7 +70,7 @@ const getFacetsMap = facets => { }; const reducer = createMap( - (state, action) => action.type === RECEIVE_PROJECTS, + (state, action) => action.type === actions.RECEIVE_PROJECTS, () => false, (state, action) => getFacetsMap(action.facets) ); diff --git a/server/sonar-web/src/main/js/apps/projects/store/projects/actions.js b/server/sonar-web/src/main/js/apps/projects/store/projects/actions.js deleted file mode 100644 index ed411c05a38..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/store/projects/actions.js +++ /dev/null @@ -1,33 +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. - */ -export const RECEIVE_PROJECTS = 'projects/RECEIVE_PROJECTS'; - -export const receiveProjects = (projects, facets) => ({ - type: RECEIVE_PROJECTS, - projects, - facets -}); - -export const RECEIVE_MORE_PROJECTS = 'projects/RECEIVE_MORE_PROJECTS'; - -export const receiveMoreProjects = projects => ({ - type: RECEIVE_MORE_PROJECTS, - projects -}); diff --git a/server/sonar-web/src/main/js/apps/projects/store/projects/reducer.js b/server/sonar-web/src/main/js/apps/projects/store/projectsDuck.js index d5669ada713..a0699c3f6df 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/projects/reducer.js +++ b/server/sonar-web/src/main/js/apps/projects/store/projectsDuck.js @@ -17,14 +17,28 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { RECEIVE_PROJECTS, RECEIVE_MORE_PROJECTS } from './actions'; +export const actions = { + RECEIVE_PROJECTS: 'projects/RECEIVE_PROJECTS', + RECEIVE_MORE_PROJECTS: 'projects/RECEIVE_MORE_PROJECTS' +}; + +export const receiveProjects = (projects, facets) => ({ + type: actions.RECEIVE_PROJECTS, + projects, + facets +}); + +export const receiveMoreProjects = projects => ({ + type: actions.RECEIVE_MORE_PROJECTS, + projects +}); const reducer = (state = null, action = {}) => { - if (action.type === RECEIVE_PROJECTS) { + if (action.type === actions.RECEIVE_PROJECTS) { return action.projects.map(project => project.key); } - if (action.type === RECEIVE_MORE_PROJECTS) { + if (action.type === actions.RECEIVE_MORE_PROJECTS) { const keys = action.projects.map(project => project.key); return state != null ? [...state, ...keys] : keys; } diff --git a/server/sonar-web/src/main/js/apps/projects/store/reducer.js b/server/sonar-web/src/main/js/apps/projects/store/reducer.js index 1e2487aa794..14930279ac1 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/reducer.js +++ b/server/sonar-web/src/main/js/apps/projects/store/reducer.js @@ -18,9 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { combineReducers } from 'redux'; -import projects, * as fromProjects from './projects/reducer'; -import state from './state/reducer'; -import facets, * as fromFacets from './facets/reducer'; +import projects, * as fromProjects from './projectsDuck'; +import state from './stateDuck'; +import facets, * as fromFacets from './facetsDuck'; export default combineReducers({ projects, state, facets }); diff --git a/server/sonar-web/src/main/js/apps/projects/store/state/reducer.js b/server/sonar-web/src/main/js/apps/projects/store/state/reducer.js deleted file mode 100644 index 853accdd5ba..00000000000 --- a/server/sonar-web/src/main/js/apps/projects/store/state/reducer.js +++ /dev/null @@ -1,30 +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 { UPDATE_STATE } from './actions'; - -const reducer = (state = {}, action = {}) => { - if (action.type === UPDATE_STATE) { - return { ...state, ...action.changes }; - } - - return state; -}; - -export default reducer; diff --git a/server/sonar-web/src/main/js/apps/projects/store/state/actions.js b/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js index 7046e08aa62..d74a8f910ff 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/state/actions.js +++ b/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js @@ -17,9 +17,27 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export const UPDATE_STATE = 'projects/UPDATE_STATE'; +import { createValue } from '../../../components/store/generalReducers'; + +export const actions = { + UPDATE_STATE: 'projects/UPDATE_STATE' +}; export const updateState = changes => ({ - type: UPDATE_STATE, + type: actions.UPDATE_STATE, changes }); + +export default createValue( + // should update + (state, action) => action.type === actions.UPDATE_STATE, + + // should reset + () => false, + + // get next value + (state, action) => ({ ...state, ...action.changes }), + + // default value + {} +); diff --git a/server/sonar-web/src/main/js/apps/projects/styles.css b/server/sonar-web/src/main/js/apps/projects/styles.css index 15522753d83..a71aceb70d2 100644 --- a/server/sonar-web/src/main/js/apps/projects/styles.css +++ b/server/sonar-web/src/main/js/apps/projects/styles.css @@ -2,10 +2,6 @@ width: 260px; } -.projects-list-container { - width: 740px; -} - .projects-list .page-actions { margin-bottom: 0; } |