From: Stas Vilchik Date: Tue, 1 Dec 2015 14:13:20 +0000 (+0100) Subject: improve display of project navigation X-Git-Tag: 5.3-RC1~116 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b59ee573dfcd5cf19ef6c517e1b7a9ad30bbffcc;p=sonarqube.git improve display of project navigation --- 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
  • - {name} -
  • ; - }); - }, - - 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
  • - {name} -
  • ; - }, - - 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
  • - - More  - - -
      {dashboards}
    -
  • ; - }, - - 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
  • - {name} -
  • ; - }, - - render() { - return ; - } -}); 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(, 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(, 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
  • + {name} +
  • ; }); }, + 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
  • + {name} +
  • ; + }, + + 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
  • + + More  + + +
      {dashboards}
    +
  • ; + }, + + 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
  • + {name} +
  • ; + }, + 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 (
      - {this.renderDashboardLink()} + {this.renderFixedDashboards()} {this.renderComponentsLink()} {this.renderComponentIssuesLink()} {this.renderAdministration()} {this.renderTools()} + {this.renderCustomDashboards()} + {this.renderMoreCustomDashboards()}
    ); } 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 @@