aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2016-12-20 16:28:58 +0100
committerStas Vilchik <vilchiks@gmail.com>2016-12-20 16:35:14 +0100
commit0d37b8a966e1f1ebf6f38524da8ec1e0a0e06813 (patch)
treeafbeabfac1648420922dd28ae4d58cd582222fe7
parent8c9d3d5bb674a0ea9a8dcff2fef5a1eeb70537a8 (diff)
downloadsonarqube-0d37b8a966e1f1ebf6f38524da8ec1e0a0e06813.tar.gz
sonarqube-0d37b8a966e1f1ebf6f38524da8ec1e0a0e06813.zip
SONAR-8552 fix settings navigation
-rw-r--r--server/sonar-web/src/main/js/app/components/AdminContainer.js26
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js17
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js29
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap184
4 files changed, 243 insertions, 13 deletions
diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.js b/server/sonar-web/src/main/js/app/components/AdminContainer.js
index 728118fac90..26da1f1be44 100644
--- a/server/sonar-web/src/main/js/app/components/AdminContainer.js
+++ b/server/sonar-web/src/main/js/app/components/AdminContainer.js
@@ -22,24 +22,46 @@ import { connect } from 'react-redux';
import SettingsNav from './nav/settings/SettingsNav';
import { getCurrentUser } from '../../store/rootReducer';
import { isUserAdmin } from '../../helpers/users';
+import { onFail } from '../../store/rootActions';
+import { getSettingsNavigation } from '../../api/nav';
class AdminContainer extends React.Component {
+ state = {
+ loading: true
+ };
+
componentDidMount () {
if (!isUserAdmin(this.props.currentUser)) {
// workaround cyclic dependencies
const handleRequiredAuthorization = require('../utils/handleRequiredAuthorization').default;
handleRequiredAuthorization();
}
+
+ this.mounted = true;
+ this.loadData();
+ }
+
+ componentWillUnmount () {
+ this.mounted = false;
+ }
+
+ loadData () {
+ getSettingsNavigation().then(
+ r => this.setState({ extensions: r.extensions, loading: false }),
+ onFail(this.props.dispatch)
+ );
}
render () {
- if (!isUserAdmin(this.props.currentUser)) {
+ if (!isUserAdmin(this.props.currentUser) || this.state.loading) {
return null;
}
return (
<div>
- <SettingsNav/>
+ <SettingsNav
+ location={this.props.location}
+ extensions={this.state.extensions}/>
{this.props.children}
</div>
);
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js
index 6560e94f27c..f65a2b8050e 100644
--- a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js
@@ -19,7 +19,7 @@
*/
import React from 'react';
import classNames from 'classnames';
-import { IndexLink } from 'react-router';
+import { IndexLink, Link } from 'react-router';
import { translate } from '../../../../helpers/l10n';
export default class SettingsNav extends React.Component {
@@ -47,18 +47,13 @@ export default class SettingsNav extends React.Component {
return this.isSomethingActive(urls);
}
- renderLink (url, title, highlightUrl = url) {
- const fullUrl = window.baseUrl + url;
- const isActive = typeof highlightUrl === 'string' ?
- window.location.pathname.indexOf(window.baseUrl + highlightUrl) === 0 :
- highlightUrl(fullUrl);
-
+ renderExtension = ({ id, name }) => {
return (
- <li key={url} className={classNames({ 'active': isActive })}>
- <a href={fullUrl}>{title}</a>
+ <li key={id}>
+ <Link to={`/admin/extension/${id}`} activeClassName="active">{name}</Link>
</li>
);
- }
+ };
render () {
const isSecurity = this.isSecurityActive();
@@ -115,7 +110,7 @@ export default class SettingsNav extends React.Component {
Custom Metrics
</IndexLink>
</li>
- {this.props.extensions.map(e => this.renderLink(e.url, e.name))}
+ {this.props.extensions.map(this.renderExtension)}
</ul>
</li>
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js
new file mode 100644
index 00000000000..c00d2b102ce
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js
@@ -0,0 +1,29 @@
+/*
+ * 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 { shallow } from 'enzyme';
+import toJSON from 'enzyme-to-json';
+import SettingsNav from '../SettingsNav';
+
+it('should work with extensions', () => {
+ const extensions = [{ id: 'foo', name: 'Foo' }];
+ const wrapper = shallow(<SettingsNav extensions={extensions}/>);
+ expect(toJSON(wrapper)).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap
new file mode 100644
index 00000000000..2173a8f054f
--- /dev/null
+++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap
@@ -0,0 +1,184 @@
+exports[`test should work with extensions 1`] = `
+<nav
+ className="navbar navbar-context page-container"
+ id="context-navigation">
+ <div
+ className="navbar-context-inner">
+ <div
+ className="container">
+ <ul
+ className="nav navbar-nav nav-crumbs">
+ <li>
+ <IndexLink
+ to="/settings">
+ layout.settings
+ </IndexLink>
+ </li>
+ </ul>
+ <ul
+ className="nav navbar-nav nav-tabs">
+ <li
+ className="dropdown active">
+ <a
+ className="dropdown-toggle"
+ data-toggle="dropdown"
+ href="#">
+ sidebar.project_settings
+
+ <i
+ className="icon-dropdown" />
+ </a>
+ <ul
+ className="dropdown-menu">
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/settings">
+ settings.page
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/settings/licenses">
+ property.category.licenses
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/settings/encryption">
+ property.category.security.encryption
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/settings/server_id">
+ property.category.server_id
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/metrics">
+ Custom Metrics
+ </IndexLink>
+ </li>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/admin/extension/foo">
+ Foo
+ </Link>
+ </li>
+ </ul>
+ </li>
+ <li
+ className="dropdown">
+ <a
+ className="dropdown-toggle"
+ data-toggle="dropdown"
+ href="#">
+ sidebar.security
+
+ <i
+ className="icon-dropdown" />
+ </a>
+ <ul
+ className="dropdown-menu">
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/users">
+ users.page
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/groups">
+ user_groups.page
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/roles/global">
+ global_permissions.page
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/permission_templates">
+ permission_templates
+ </IndexLink>
+ </li>
+ </ul>
+ </li>
+ <li
+ className="dropdown">
+ <a
+ className="dropdown-toggle"
+ data-toggle="dropdown"
+ href="#">
+ sidebar.projects
+
+ <i
+ className="icon-dropdown" />
+ </a>
+ <ul
+ className="dropdown-menu">
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/projects_admin">
+ Management
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/background_tasks">
+ background_tasks.page
+ </IndexLink>
+ </li>
+ </ul>
+ </li>
+ <li
+ className="dropdown">
+ <a
+ className="dropdown-toggle"
+ data-toggle="dropdown"
+ href="#">
+ sidebar.system
+
+ <i
+ className="icon-dropdown" />
+ </a>
+ <ul
+ className="dropdown-menu">
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/updatecenter">
+ update_center.page
+ </IndexLink>
+ </li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/system">
+ system_info.page
+ </IndexLink>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+</nav>
+`;