From c86db4ee3737107b738e2bd83d5cfbad5d3575f2 Mon Sep 17 00:00:00 2001 From: Grégoire Aubert Date: Wed, 19 Jul 2017 15:10:29 +0200 Subject: SONAR-9566 Add Issues link at organization level navbar --- .../src/main/js/apps/issues/components/App.js | 9 +++- .../components/OrganizationContainer.js | 39 +++++++++++++++++ .../organizations/components/OrganizationPage.js | 12 +++-- .../components/OrganizationProjectsContainer.js | 42 ------------------ .../navigation/OrganizationNavigation.js | 17 +++++++- .../__tests__/OrganizationNavigation-test.js | 7 +++ .../OrganizationNavigation-test.js.snap | 51 ++++++++++++++++++++++ .../src/main/js/apps/organizations/routes.js | 10 ++++- 8 files changed, 137 insertions(+), 50 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.js delete mode 100644 server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsContainer.js (limited to 'server') diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.js b/server/sonar-web/src/main/js/apps/issues/components/App.js index 60dd9d43f9f..48b6dbfcb0c 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/App.js +++ b/server/sonar-web/src/main/js/apps/issues/components/App.js @@ -67,6 +67,7 @@ export type Props = { fetchIssues: (query: RawQuery) => Promise<*>, location: { pathname: string, query: RawQuery }, onRequestFail: Error => void, + organization?: { key: string }, router: { push: ({ pathname: string, query?: RawQuery }) => void, replace: ({ pathname: string, query?: RawQuery }) => void @@ -342,7 +343,7 @@ export default class App extends React.PureComponent { }; fetchIssues = (additional?: {}, requestFacets?: boolean = false): Promise<*> => { - const { component } = this.props; + const { component, organization } = this.props; const { myIssues, openFacets, query } = this.state; const facets = requestFacets @@ -358,6 +359,10 @@ export default class App extends React.PureComponent { ...additional }; + if (organization) { + parameters.organization = organization.key; + } + // only sorting by CREATION_DATE is allowed, so let's sort DESC if (query.sort) { Object.assign(parameters, { asc: 'false' }); @@ -730,7 +735,7 @@ export default class App extends React.PureComponent { } renderSide(openIssue: ?Issue) { - const top = this.props.component ? 95 : 30; + const top = this.props.component || this.props.organization ? 95 : 30; return (
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.js new file mode 100644 index 00000000000..a48cf7f5cd6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.js @@ -0,0 +1,39 @@ +/* + * 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'; + +class OrganizationContainer extends React.PureComponent { + render() { + return React.cloneElement(this.props.children, { + currentUser: this.props.currentUser, + organization: this.props.organization + }); + } +} + +const mapStateToProps = (state, ownProps) => ({ + organization: getOrganizationByKey(state, ownProps.params.organizationKey), + currentUser: getCurrentUser(state) +}); + +export default connect(mapStateToProps)(OrganizationContainer); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js index d08cfabf5d4..9111c0c70e2 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js @@ -22,10 +22,10 @@ import React from 'react'; import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import OrganizationNavigation from '../navigation/OrganizationNavigation'; +import NotFound from '../../../app/components/NotFound'; import { fetchOrganization } from '../actions'; -import { getOrganizationByKey } from '../../../store/rootReducer'; +import { getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer'; import type { Organization } from '../../../store/organizations/duck'; -import NotFound from '../../../app/components/NotFound'; type OwnProps = { params: { organizationKey: string } @@ -33,6 +33,7 @@ type OwnProps = { type Props = { children?: React.Element<*>, + currentUser: { isLoggedIn: boolean, showOnboardingTutorial: true }, location: Object, organization: null | Organization, params: { organizationKey: string }, @@ -88,7 +89,11 @@ class OrganizationPage extends React.PureComponent { return (
- + {this.props.children}
); @@ -96,6 +101,7 @@ class OrganizationPage extends React.PureComponent { } const mapStateToProps = (state, ownProps: OwnProps) => ({ + currentUser: getCurrentUser(state), organization: getOrganizationByKey(state, ownProps.params.organizationKey) }); 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 deleted file mode 100644 index a08e864d1b9..00000000000 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsContainer.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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'; - -class OrganizationProjectsContainer extends React.PureComponent { - render() { - return React.cloneElement(this.props.children, { - currentUser: this.props.currentUser, - 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); diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js index e872e6e2ac1..ab54c533014 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js @@ -25,6 +25,7 @@ import { translate } from '../../../helpers/l10n'; import ContextNavBar from '../../../components/nav/ContextNavBar'; import NavBarTabs from '../../../components/nav/NavBarTabs'; import OrganizationIcon from '../../../components/icons-components/OrganizationIcon'; +import { isMySet } from '../../issues/utils'; import type { Organization } from '../../../store/organizations/duck'; const ADMIN_PATHS = [ @@ -38,6 +39,7 @@ const ADMIN_PATHS = [ export default class OrganizationNavigation extends React.PureComponent { props: { + currentUser: { isLoggedIn: boolean, showOnboardingTutorial: true }, location: { pathname: string }, organization: Organization }; @@ -135,7 +137,7 @@ export default class OrganizationNavigation extends React.PureComponent { } render() { - const { organization, location } = this.props; + const { currentUser, organization, location } = this.props; const isHomeActive = location.pathname === `organizations/${organization.key}/projects` || @@ -196,6 +198,19 @@ export default class OrganizationNavigation extends React.PureComponent { {translate('projects.page')} +
  • + + {translate('issues.page')} + +
  • {translate('organization.members.page')} diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js index 09254c5aaf3..f4a2b09a38b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js @@ -21,11 +21,16 @@ import React from 'react'; import { shallow } from 'enzyme'; import OrganizationNavigation from '../OrganizationNavigation'; +jest.mock('../../../issues/utils', () => ({ + isMySet: () => false +})); + it('regular user', () => { const organization = { key: 'foo', name: 'Foo', canAdmin: false, canDelete: false }; expect( shallow( @@ -38,6 +43,7 @@ it('admin', () => { expect( shallow( @@ -50,6 +56,7 @@ it('undeletable org', () => { expect( shallow( diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigation-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigation-test.js.snap index 05104c2e4d8..389fae8e92f 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigation-test.js.snap +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigation-test.js.snap @@ -40,6 +40,23 @@ exports[`admin 1`] = ` projects.page
  • +
  • + + issues.page + +
  • +
  • + + issues.page + +
  • +
  • + + issues.page + +