aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-12-01 15:13:20 +0100
committerStas Vilchik <vilchiks@gmail.com>2015-12-01 15:13:20 +0100
commitb59ee573dfcd5cf19ef6c517e1b7a9ad30bbffcc (patch)
treee7dc716aa5c4391fb0d55810d47cf0e0b1973a4f /server
parent7a5770ca5de434a1ab75a22fc4ad3e3943f83808 (diff)
downloadsonarqube-b59ee573dfcd5cf19ef6c517e1b7a9ad30bbffcc.tar.gz
sonarqube-b59ee573dfcd5cf19ef6c517e1b7a9ad30bbffcc.zip
improve display of project navigation
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/dashboard/app.js15
-rw-r--r--server/sonar-web/src/main/js/components/dashboards/dashboard-sidebar.js124
-rw-r--r--server/sonar-web/src/main/js/main/nav/app.js12
-rw-r--r--server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js116
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb1
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb1
6 files changed, 105 insertions, 164 deletions
diff --git a/server/sonar-web/src/main/js/apps/dashboard/app.js b/server/sonar-web/src/main/js/apps/dashboard/app.js
index 4b700eb26c9..9f045a948b2 100644
--- a/server/sonar-web/src/main/js/apps/dashboard/app.js
+++ b/server/sonar-web/src/main/js/apps/dashboard/app.js
@@ -136,18 +136,3 @@ window.autoResize = function (everyMs, callback) {
var debounce = _.debounce(callback, everyMs);
$(window).on('resize', debounce);
};
-
-
-$(function () {
- var $sidebar = $('#sidebar');
- if ($sidebar.length > 0) {
- var $window = $(window),
- topOffset = $sidebar.offset().top;
- $window.on('scroll', function () {
- var scrollTop = $window.scrollTop(),
- scrollLeft = $window.scrollLeft();
- $sidebar.toggleClass('sticky', scrollTop > topOffset);
- $sidebar.css('left', -scrollLeft + 10);
- });
- }
-});
diff --git a/server/sonar-web/src/main/js/components/dashboards/dashboard-sidebar.js b/server/sonar-web/src/main/js/components/dashboards/dashboard-sidebar.js
deleted file mode 100644
index f68aa7b9c89..00000000000
--- a/server/sonar-web/src/main/js/components/dashboards/dashboard-sidebar.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import qs from 'querystring';
-import _ from 'underscore';
-import classNames from 'classnames';
-import React from 'react';
-
-import { getLocalizedDashboardName } from '../../helpers/l10n';
-import { getComponentDashboardUrl, getComponentFixedDashboardUrl, getComponentDashboardManagementUrl } from '../../helpers/urls';
-
-
-const FIXED_DASHBOARDS = [
- { link: '', name: 'overview.page' },
- { link: '/issues', name: 'overview.domain.debt' },
- { link: '/tests', name: 'overview.domain.coverage' },
- { link: '/duplications', name: 'overview.domain.duplications' },
- { link: '/size', name: 'overview.domain.size' }
-];
-
-const CUSTOM_DASHBOARDS_LIMIT = 1;
-
-
-export const DashboardSidebar = React.createClass({
- propTypes: {
- component: React.PropTypes.object.isRequired,
- customDashboards: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
- },
-
- periodParameter() {
- let params = qs.parse(window.location.search.substr(1));
- return params.period ? `&period=${params.period}` : '';
- },
-
- getPeriod() {
- let params = qs.parse(window.location.search.substr(1));
- return params.period;
- },
-
- isFixedDashboardActive(fixedDashboard) {
- let path = window.location.pathname;
- return path === `${window.baseUrl}/overview${fixedDashboard.link}`;
- },
-
- isCustomDashboardActive(customDashboard) {
- let path = window.location.pathname,
- params = qs.parse(window.location.search.substr(1));
- return path.indexOf(`${window.baseUrl}/dashboard`) === 0 && params['did'] === `${customDashboard.key}`;
- },
-
- isMoreCustomDashboardsActive () {
- let dashboards = _.rest(this.props.customDashboards, CUSTOM_DASHBOARDS_LIMIT);
- return _.any(dashboards, this.isCustomDashboardActive);
- },
-
- isDashboardManagementActive () {
- let path = window.location.pathname;
- return path.indexOf(`${window.baseUrl}/dashboards`) === 0;
- },
-
- renderFixedDashboards() {
- return FIXED_DASHBOARDS.map(fixedDashboard => {
- let key = 'fixed-dashboard-' + fixedDashboard.link.substr(1);
- let url = getComponentFixedDashboardUrl(this.props.component.key, fixedDashboard.link);
- let name = window.t(fixedDashboard.name);
- let className = classNames({ active: this.isFixedDashboardActive(fixedDashboard) });
- return <li key={key} className={className}>
- <a href={url}>{name}</a>
- </li>;
- });
- },
-
- renderCustomDashboards() {
- let dashboards = _.first(this.props.customDashboards, CUSTOM_DASHBOARDS_LIMIT);
- return dashboards.map(this.renderCustomDashboard);
- },
-
- renderCustomDashboard(customDashboard) {
- let key = 'custom-dashboard-' + customDashboard.key;
- let url = getComponentDashboardUrl(this.props.component.key, customDashboard.key, this.getPeriod());
- let name = getLocalizedDashboardName(customDashboard.name);
- let className = classNames({ active: this.isCustomDashboardActive(customDashboard) });
- return <li key={key} className={className}>
- <a href={url}>{name}</a>
- </li>;
- },
-
- renderMoreCustomDashboards() {
- if (this.props.customDashboards.length <= CUSTOM_DASHBOARDS_LIMIT) {
- return null;
- }
- let dashboards = _.rest(this.props.customDashboards, CUSTOM_DASHBOARDS_LIMIT)
- .map(this.renderCustomDashboard);
- let className = classNames('dropdown', { active: this.isMoreCustomDashboardsActive() });
- return <li className={className}>
- <a className="dropdown-toggle" data-toggle="dropdown" href="#">
- More&nbsp;
- <i className="icon-dropdown"/>
- </a>
- <ul className="dropdown-menu">{dashboards}</ul>
- </li>;
- },
-
- renderDashboardsManagementLink() {
- if (!window.SS.user) {
- return null;
- }
- let key = 'dashboard-management';
- let url = getComponentDashboardManagementUrl(this.props.component.key);
- let name = window.t('dashboard.manage_dashboards');
- let className = classNames('pill-right', { active: this.isDashboardManagementActive() });
- return <li key={key} className={className}>
- <a className="note" href={url}>{name}</a>
- </li>;
- },
-
- render() {
- return <nav className="navbar-side">
- <ul className="pills">
- {this.renderFixedDashboards()}
- {this.renderCustomDashboards()}
- {this.renderMoreCustomDashboards()}
- {this.renderDashboardsManagementLink()}
- </ul>
- </nav>;
- }
-});
diff --git a/server/sonar-web/src/main/js/main/nav/app.js b/server/sonar-web/src/main/js/main/nav/app.js
index f4f9644be13..424294553bf 100644
--- a/server/sonar-web/src/main/js/main/nav/app.js
+++ b/server/sonar-web/src/main/js/main/nav/app.js
@@ -5,7 +5,6 @@ import GlobalNav from './global/global-nav';
import ComponentNav from './component/component-nav';
import SettingsNav from './settings/settings-nav';
import { getGlobalNavigation, getComponentNavigation, getSettingsNavigation } from '../../api/nav';
-import { DashboardSidebar } from '../../components/dashboards/dashboard-sidebar';
import '../../components/workspace/main';
import '../../helpers/handlebars-helpers';
@@ -51,21 +50,10 @@ export default class App {
if (el) {
ReactDOM.render(<ComponentNav component={component} conf={component.configuration || {}}/>, el);
}
- this.renderSidebarNav(component);
return component;
});
}
- static renderSidebarNav (component) {
- let shouldRender =
- window.location.pathname.indexOf(window.baseUrl + '/overview') === 0 ||
- window.location.pathname.indexOf(window.baseUrl + '/dashboard') === 0;
- let el = document.getElementById('sidebar');
- if (shouldRender && el) {
- ReactDOM.render(<DashboardSidebar component={component} customDashboards={component.dashboards}/>, el);
- }
- }
-
static renderSettingsNav (options) {
return getSettingsNavigation().then(r => {
let el = document.getElementById('context-navigation');
diff --git a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
index 2293fa124d3..6c8b143ba69 100644
--- a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
+++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js
@@ -1,7 +1,26 @@
+import qs from 'querystring';
import _ from 'underscore';
+import classNames from 'classnames';
import React from 'react';
-import DashboardNameMixin from '../dashboard-name-mixin';
+
import LinksMixin from '../links-mixin';
+import { getLocalizedDashboardName } from '../../../helpers/l10n';
+import {
+ getComponentDashboardUrl,
+ getComponentFixedDashboardUrl,
+ getComponentDashboardManagementUrl
+} from '../../../helpers/urls';
+
+
+const FIXED_DASHBOARDS = [
+ { link: '', name: 'overview.page' },
+ { link: '/issues', name: 'overview.domain.debt' },
+ { link: '/tests', name: 'overview.domain.coverage' },
+ { link: '/duplications', name: 'overview.domain.duplications' },
+ { link: '/size', name: 'overview.domain.size' }
+];
+
+const CUSTOM_DASHBOARDS_LIMIT = 1;
const SETTINGS_URLS = [
'/project/settings', '/project/profile', '/project/qualitygate', '/manual_measures/index',
@@ -9,24 +28,97 @@ const SETTINGS_URLS = [
'/project/deletion'
];
+
export default React.createClass({
- mixins: [DashboardNameMixin, LinksMixin],
+ mixins: [LinksMixin],
periodParameter() {
- let params = window.getQueryParams();
+ let params = qs.parse(window.location.search.substr(1));
return params.period ? `&period=${params.period}` : '';
},
- renderDashboardLink() {
- let url = `/overview?id=${encodeURIComponent(this.props.component.key)}`;
- return this.renderLink(url, window.t('layout.dashboards'), () => {
- let cond =
- window.location.pathname.indexOf(window.baseUrl + '/overview') === 0 ||
- window.location.pathname.indexOf(window.baseUrl + '/dashboard') === 0;
- return cond ? 'active' : null;
+ getPeriod() {
+ let params = qs.parse(window.location.search.substr(1));
+ return params.period;
+ },
+
+ isFixedDashboardActive(fixedDashboard) {
+ let path = window.location.pathname;
+ return path === `${window.baseUrl}/overview${fixedDashboard.link}`;
+ },
+
+ isCustomDashboardActive(customDashboard) {
+ let path = window.location.pathname,
+ params = qs.parse(window.location.search.substr(1));
+ return path.indexOf(`${window.baseUrl}/dashboard`) === 0 && params['did'] === `${customDashboard.key}`;
+ },
+
+ isMoreCustomDashboardsActive () {
+ let dashboards = _.rest(this.props.component.dashboards, CUSTOM_DASHBOARDS_LIMIT);
+ return _.any(dashboards, this.isCustomDashboardActive);
+ },
+
+ isDashboardManagementActive () {
+ let path = window.location.pathname;
+ return path.indexOf(`${window.baseUrl}/dashboards`) === 0;
+ },
+
+ renderFixedDashboards() {
+ return FIXED_DASHBOARDS.map(fixedDashboard => {
+ let key = 'fixed-dashboard-' + fixedDashboard.link.substr(1);
+ let url = getComponentFixedDashboardUrl(this.props.component.key, fixedDashboard.link);
+ let name = window.t(fixedDashboard.name);
+ let className = classNames({ active: this.isFixedDashboardActive(fixedDashboard) });
+ return <li key={key} className={className}>
+ <a href={url}>{name}</a>
+ </li>;
});
},
+ renderCustomDashboards() {
+ let dashboards = _.first(this.props.component.dashboards, CUSTOM_DASHBOARDS_LIMIT);
+ return dashboards.map(this.renderCustomDashboard);
+ },
+
+ renderCustomDashboard(customDashboard) {
+ let key = 'custom-dashboard-' + customDashboard.key;
+ let url = getComponentDashboardUrl(this.props.component.key, customDashboard.key, this.getPeriod());
+ let name = getLocalizedDashboardName(customDashboard.name);
+ let className = classNames({ active: this.isCustomDashboardActive(customDashboard) });
+ return <li key={key} className={className}>
+ <a href={url}>{name}</a>
+ </li>;
+ },
+
+ renderMoreCustomDashboards() {
+ if (this.props.component.dashboards.length <= CUSTOM_DASHBOARDS_LIMIT) {
+ return null;
+ }
+ let dashboards = _.rest(this.props.component.dashboards, CUSTOM_DASHBOARDS_LIMIT)
+ .map(this.renderCustomDashboard);
+ let className = classNames('dropdown', { active: this.isMoreCustomDashboardsActive() });
+ return <li className={className}>
+ <a className="dropdown-toggle" data-toggle="dropdown" href="#">
+ More&nbsp;
+ <i className="icon-dropdown"/>
+ </a>
+ <ul className="dropdown-menu">{dashboards}</ul>
+ </li>;
+ },
+
+ renderDashboardsManagementLink() {
+ if (!window.SS.user) {
+ return null;
+ }
+ let key = 'dashboard-management';
+ let url = getComponentDashboardManagementUrl(this.props.component.key);
+ let name = window.t('dashboard.manage_dashboards');
+ let className = classNames('pill-right', { active: this.isDashboardManagementActive() });
+ return <li key={key} className={className}>
+ <a className="note" href={url}>{name}</a>
+ </li>;
+ },
+
renderComponentsLink() {
const url = `/components/index?id=${encodeURIComponent(this.props.component.key)}`;
return this.renderLink(url, window.t('components.page'), '/components');
@@ -191,11 +283,13 @@ export default React.createClass({
render() {
return (
<ul className="nav navbar-nav nav-tabs">
- {this.renderDashboardLink()}
+ {this.renderFixedDashboards()}
{this.renderComponentsLink()}
{this.renderComponentIssuesLink()}
{this.renderAdministration()}
{this.renderTools()}
+ {this.renderCustomDashboards()}
+ {this.renderMoreCustomDashboards()}
</ul>
);
}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb
index 74d50a2f7a0..72416ed82eb 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb
@@ -6,7 +6,6 @@
<script>
(function () {
jQuery('.navbar-context').remove();
- jQuery('#sidebar').remove();
jQuery('.page-wrapper-context').addClass('page-wrapper-global').removeClass('page-wrapper-context');
window.sonarqube.el = '#source-viewer';
window.sonarqube.file = {
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
index 2af9eb9a60c..b793d31198e 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
@@ -17,7 +17,6 @@
<%= yield :header -%>
<div id="body" class="page-container">
- <div id="sidebar"></div>
<div id="content">
<div class="panel hidden" id="messages-panel">
<div class="alert alert-danger hidden" id="error">