+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-define([
- './state',
- './global-navbar-view',
- './context-navbar-view',
- './settings-navbar-view',
- 'components/workspace/main'
-], function (State, GlobalNavbarView, ContextNavbarView, SettingsNavbarView) {
-
- var $ = jQuery,
- App = new Marionette.Application(),
- init = function (options) {
- var state = new State(options);
- state.fetchGlobal();
-
- this.navbarView = new GlobalNavbarView({
- app: App,
- el: $('.navbar-global'),
- model: state
- });
- this.navbarView.render();
-
- if (state.get('space') === 'component') {
- state.fetchComponent();
- this.contextNavbarView = new ContextNavbarView({
- app: App,
- el: $('.navbar-context'),
- model: state
- });
- this.contextNavbarView.render();
- }
-
- if (state.get('space') === 'settings') {
- state.fetchSettings();
- this.settingsNavbarView = new SettingsNavbarView({
- app: App,
- el: $('.navbar-context'),
- model: state
- });
- this.settingsNavbarView.render();
- }
-
- $(window).on('keypress', function (e) {
- var tagName = e.target.tagName;
- if (tagName !== 'INPUT' && tagName !== 'SELECT' && tagName !== 'TEXTAREA') {
- var code = e.keyCode || e.which;
- if (code === 63) {
- App.navbarView.showShortcutsHelp();
- }
- }
- });
- };
-
- App.on('start', function (options) {
- $.when(window.requestMessages()).done(function () {
- init.call(App, options);
- });
- });
-
- return App;
-
-});
--- /dev/null
+import React from 'react';
+import GlobalNav from './global-nav';
+
+export default {
+ start(options) {
+ window.requestMessages().done(() => {
+ this.renderGlobalNav(options);
+ });
+ },
+
+ renderGlobalNav(options) {
+ const el = document.getElementById('global-navigation');
+ React.render(<GlobalNav {...options}/>, el);
+ }
+};
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-define([
- './templates'
-], function () {
-
- var $ = jQuery,
- MORE_URLS = [
- '/dashboards', '/dashboard', '/plugins/resource'
- ],
- SETTINGS_URLS = [
- '/project/settings', '/project/profile', '/project/qualitygate', '/manual_measures/index',
- '/action_plans/index', '/project/links', '/project_roles/index', '/project/history', '/project/key',
- '/project/deletion'
- ];
-
- return Marionette.ItemView.extend({
- template: Templates['nav-context-navbar'],
-
- modelEvents: {
- 'change:component': 'render'
- },
-
- events: {
- 'click .js-favorite': 'onFavoriteClick'
- },
-
- onRender: function () {
- this.$('[data-toggle="tooltip"]').tooltip({
- container: 'body'
- });
- },
-
- onFavoriteClick: function () {
- var that = this;
- var component = this.model.get('component'),
- isFavorite = component.isFavorite,
- urlSuffix = (isFavorite ? '/' : '?key=') + encodeURIComponent(component.key),
- opts = {
- url: baseUrl + '/api/favourites' + urlSuffix,
- success: function () {
- component.isFavorite = !isFavorite;
- that.model.trigger('change:component');
- }
- };
- opts.type = isFavorite ? 'DELETE': 'POST';
- return $.ajax(opts);
- },
-
- serializeData: function () {
- var href = window.location.href,
- search = window.location.search,
- isMoreActive = _.some(MORE_URLS, function (url) {
- return href.indexOf(url) !== -1;
- }) || (href.indexOf('/dashboard') !== -1 && search.indexOf('did=') !== -1),
- isSettingsActive = _.some(SETTINGS_URLS, function (url) {
- return href.indexOf(url) !== -1;
- });
- return _.extend(Marionette.LayoutView.prototype.serializeData.apply(this, arguments), {
- canManageContextDashboards: !!window.SS.user,
- contextKeyEncoded: encodeURIComponent(this.model.get('componentKey')),
-
- isSettingsActive: isSettingsActive,
- isMoreActive: isMoreActive
- });
- }
- });
-
-});
--- /dev/null
+import React from 'react';
+
+export default React.createClass({
+ renderLogo() {
+ const url = this.props.logoUrl || `${window.baseUrl}/images/logo.svg`;
+ const width = this.props.logoWidth || 30;
+ const title = window.t('layout.sonar.slogan');
+ return <img src={url} width={width} height="30" alt={title} title={title}/>
+ },
+
+ render() {
+ const homeUrl = window.baseUrl + '/';
+ const homeLinkClassName = 'navbar-brand' + (this.props.logoUrl ? ' navbar-brand-custom' : '');
+ return (
+ <div className="navbar-header">
+ <a className={homeLinkClassName} href={homeUrl}>{this.renderLogo()}</a>
+ </div>
+ );
+ }
+});
--- /dev/null
+import React from 'react';
+
+export default React.createClass({
+ getDefaultProps: function () {
+ return { globalDashboards: [], globalPages: [] };
+ },
+
+ activeLink(url) {
+ return window.location.pathname.indexOf(window.baseUrl + url) === 0 ? 'active' : null;
+ },
+
+ getLocalizedDashboardName(baseName) {
+ var l10nKey = 'dashboard.' + baseName + '.name';
+ var l10nLabel = window.t(l10nKey);
+ if (l10nLabel !== l10nKey) {
+ return l10nLabel;
+ } else {
+ return baseName;
+ }
+ },
+
+ renderDashboardLink(dashboard) {
+ const url = `${window.baseUrl}/dashboard/index?did=${encodeURIComponent(dashboard.key)}`;
+ const name = this.getLocalizedDashboardName(dashboard.name);
+ return (
+ <li key={dashboard.name}>
+ <a href={url}>{name}</a>
+ </li>
+ );
+ },
+
+ renderDashboardsManagementLink() {
+ const url = `${window.baseUrl}/dashboards`;
+ return (
+ <li>
+ <a href={url}>{window.t('dashboard.manage_dashboards')}</a>
+ </li>
+ );
+ },
+
+ renderDashboards() {
+ const dashboards = this.props.globalDashboards.map(this.renderDashboardLink);
+ const canManageDashboards = !!window.SS.user;
+ return (
+ <li className="dropdown">
+ <a className="dropdown-toggle" data-toggle="dropdown" href="#">
+ {window.t('layout.dashboards')} <span className="icon-dropdown"/>
+ </a>
+ <ul className="dropdown-menu">
+ {dashboards}
+ {canManageDashboards ? <li className="divider"/> : null}
+ {canManageDashboards ? this.renderDashboardsManagementLink() : null}
+ </ul>
+ </li>
+ );
+ },
+
+ renderIssuesLink() {
+ const url = `${window.baseUrl}/issues/search`;
+ return (
+ <li className={this.activeLink('/issues')}>
+ <a href={url}>{window.t('issues.page')}</a>
+ </li>
+ );
+ },
+
+ renderMeasuresLink() {
+ const url = `${window.baseUrl}/measures/search?qualifiers[]=TRK`;
+ return (
+ <li className={this.activeLink('/measures')}>
+ <a href={url}>{window.t('layout.measures')}</a>
+ </li>
+ );
+ },
+
+ renderRulesLink() {
+ const url = `${window.baseUrl}/coding_rules`;
+ return (
+ <li className={this.activeLink('/coding_rules')}>
+ <a href={url}>{window.t('coding_rules.page')}</a>
+ </li>
+ );
+ },
+
+ renderProfilesLink() {
+ const url = `${window.baseUrl}/profiles`;
+ return (
+ <li className={this.activeLink('/profiles')}>
+ <a href={url}>{window.t('quality_profiles.page')}</a>
+ </li>
+ );
+ },
+
+ renderQualityGatesLink() {
+ const url = `${window.baseUrl}/quality_gates`;
+ return (
+ <li className={this.activeLink('/quality_gates')}>
+ <a href={url}>{window.t('quality_gates.page')}</a>
+ </li>
+ );
+ },
+
+ renderAdministrationLink() {
+ if (!window.SS.isUserAdmin) {
+ return null;
+ }
+ const url = `${window.baseUrl}/settings`;
+ return (
+ <li className={this.activeLink('/settings')}>
+ <a className="navbar-admin-link" href={url}>{window.t('layout.settings')}</a>
+ </li>
+ );
+ },
+
+ renderComparisonLink() {
+ const url = `${window.baseUrl}/comparison`;
+ return (
+ <li className={this.activeLink('/comparison')}>
+ <a href={url}>{window.t('comparison_global.page')}</a>
+ </li>
+ );
+ },
+
+ renderGlobalPageLink(globalPage, index) {
+ const url = window.baseUrl + globalPage.url;
+ return (
+ <li key={index}>
+ <a href={url}>{globalPage.name}</a>
+ </li>
+ );
+ },
+
+ renderMore() {
+ const globalPages = this.props.globalPages.map(this.renderGlobalPageLink);
+ return (
+ <li className="dropdown">
+ <a className="dropdown-toggle" data-toggle="dropdown" href="#">
+ {window.t('more')} <span className="icon-dropdown"/>
+ </a>
+ <ul className="dropdown-menu">
+ {this.renderComparisonLink()}
+ {globalPages}
+ </ul>
+ </li>
+ );
+ },
+
+ render() {
+ return (
+ <ul className="nav navbar-nav">
+ {this.renderDashboards()}
+ {this.renderIssuesLink()}
+ {this.renderMeasuresLink()}
+ {this.renderRulesLink()}
+ {this.renderProfilesLink()}
+ {this.renderQualityGatesLink()}
+ {this.renderAdministrationLink()}
+ {this.renderMore()}
+ </ul>
+ );
+ }
+});
--- /dev/null
+import React from 'react';
+import SearchView from './search-view';
+
+let $ = jQuery;
+
+function contains (root, node) {
+ while (node) {
+ if (node === root) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+}
+
+export default React.createClass({
+ getInitialState() {
+ return { open: false };
+ },
+
+ componentDidMount() {
+ key('s', () => {
+ this.openSearch();
+ return false;
+ });
+ },
+
+ componentWillUnmount() {
+ this.closeSearch();
+ key.unbind('s');
+ },
+
+ openSearch() {
+ window.addEventListener('click', this.onClickOutside);
+ this.setState({ open: true }, this.renderSearchView);
+ },
+
+ closeSearch() {
+ window.removeEventListener('click', this.onClickOutside);
+ this.resetSearchView();
+ this.setState({ open: false });
+ },
+
+ renderSearchView() {
+ let searchContainer = React.findDOMNode(this.refs.container);
+ this.searchView = new SearchView({
+ model: new Backbone.Model(this.props),
+ hide: this.closeSearch
+ });
+ this.searchView.render().$el.appendTo(searchContainer);
+ },
+
+ resetSearchView() {
+ this.searchView && this.searchView.destroy();
+ },
+
+ onClick(e) {
+ e.preventDefault();
+ this.state.open ? this.closeSearch() : this.openSearch();
+ },
+
+ onClickOutside(e) {
+ if (!contains(React.findDOMNode(this.refs.dropdown), e.target)) {
+ this.closeSearch();
+ }
+ },
+
+ render() {
+ const dropdownClassName = 'dropdown' + (this.state.open ? ' open' : '');
+ return (
+ <li ref="dropdown" className={dropdownClassName}>
+ <a className="navbar-search-dropdown" href="#" onClick={this.onClick}>
+ <i className="icon-search navbar-icon"/> <i className="icon-dropdown"/>
+ </a>
+ <div ref="container" className="dropdown-menu dropdown-menu-right"></div>
+ </li>
+ );
+ }
+});
--- /dev/null
+import React from 'react';
+import Avatar from 'components/shared/avatar';
+
+export default React.createClass({
+ renderAuthenticated() {
+ return (
+ <li className="dropdown">
+ <a className="dropdown-toggle" data-toggle="dropdown" href="#">
+ <Avatar email={window.SS.userEmail} size={20}/>
+ {window.SS.userName} <i className="icon-dropdown"/>
+ </a>
+ <ul className="dropdown-menu dropdown-menu-right">
+ <li>
+ <a href={`${window.baseUrl}/account/index`}>{window.t('layout.user_panel.my_profile')}</a>
+ </li>
+ <li>
+ <a onClick={this.handleLogout} href="#">{window.t('layout.logout')}</a>
+ </li>
+ </ul>
+ </li>
+ );
+ },
+
+ renderAnonymous() {
+ return (
+ <li>
+ <a onClick={this.handleLogin}>{window.t('layout.login')}</a>
+ </li>
+ );
+ },
+
+ handleLogin(e) {
+ e.preventDefault();
+ const returnTo = window.location.pathname + window.location.search;
+ const loginUrl = `${window.baseUrl}/sessions/new?return_to=${encodeURIComponent(returnTo)}${window.location.hash}`;
+ window.location = loginUrl;
+ },
+
+ handleLogout(e) {
+ e.preventDefault();
+ if (window.sonarRecentHistory) {
+ window.sonarRecentHistory.clear();
+ }
+ const logoutUrl = `${window.baseUrl}/sessions/logout`;
+ window.location = logoutUrl;
+ },
+
+ render() {
+ const isUserAuthenticated = !!window.SS.user;
+ return isUserAuthenticated ? this.renderAuthenticated() : this.renderAnonymous();
+ }
+});
--- /dev/null
+import React from 'react';
+import GlobalNavBranding from './global-nav-branding';
+import GlobalNavMenu from './global-nav-menu';
+import GlobalNavUser from './global-nav-user';
+import GlobalNavSearch from './global-nav-search';
+import ShortcutsHelpView from './shortcuts-help-view';
+
+let $ = jQuery;
+
+export default React.createClass({
+ getInitialState() {
+ return this.props;
+ },
+
+ componentDidMount() {
+ this.loadGlobalNavDetails();
+ },
+
+ loadGlobalNavDetails() {
+ $.get(`${window.baseUrl}/api/navigation/global`).done(r => {
+ this.setState(r);
+ });
+ },
+
+ openHelp(e) {
+ e.preventDefault();
+ new ShortcutsHelpView().render();
+ },
+
+ render() {
+ return (
+ <div className="container">
+ <GlobalNavBranding {...this.state}/>
+
+ <GlobalNavMenu {...this.state}/>
+
+ <ul className="nav navbar-nav navbar-right">
+ <GlobalNavUser {...this.state}/>
+ <GlobalNavSearch {...this.state}/>
+ <li>
+ <a onClick={this.openHelp} href="#">
+ <i className="icon-help navbar-icon"/>
+ </a>
+ </li>
+ </ul>
+ </div>
+ );
+ }
+});
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-define([
- './search-view',
- './shortcuts-help-view',
- './templates'
-], function (SearchView, ShortcutsHelpView) {
-
- return Marionette.LayoutView.extend({
- template: Templates['nav-global-navbar'],
-
- modelEvents: {
- 'change': 'render'
- },
-
- regions: {
- searchRegion: '.js-search-region'
- },
-
- events: {
- 'click .js-login': 'onLoginClick',
- 'click .js-favorite': 'onFavoriteClick',
- 'show.bs.dropdown .js-search-dropdown': 'onSearchDropdownShow',
- 'hidden.bs.dropdown .js-search-dropdown': 'onSearchDropdownHidden',
- 'click .js-shortcuts': 'onShortcutsClick'
- },
-
- onRender: function () {
- var that = this;
- if (this.model.has('space')) {
- this.$el.addClass('navbar-' + this.model.get('space'));
- }
- this.$el.addClass('navbar-fade');
- setTimeout(function () {
- that.$el.addClass('in');
- }, 0);
- },
-
- onLoginClick: function () {
- var returnTo = window.location.pathname + window.location.search;
- window.location = baseUrl + '/sessions/new?return_to=' + encodeURIComponent(returnTo) + window.location.hash;
- return false;
- },
-
- onSearchDropdownShow: function () {
- var that = this;
- this.searchRegion.show(new SearchView({
- model: this.model,
- hide: function () {
- that.$('.js-search-dropdown-toggle').dropdown('toggle');
- }
- }));
- },
-
- onSearchDropdownHidden: function () {
- this.searchRegion.reset();
- },
-
- onShortcutsClick: function () {
- this.showShortcutsHelp();
- },
-
- showShortcutsHelp: function () {
- new ShortcutsHelpView({ shortcuts: this.model.get('shortcuts') }).render();
- },
-
- serializeData: function () {
- return _.extend(Marionette.LayoutView.prototype.serializeData.apply(this, arguments), {
- user: window.SS.user,
- userName: window.SS.userName,
- userEmail: window.SS.userEmail,
- isUserAdmin: window.SS.isUserAdmin,
-
- canManageGlobalDashboards: !!window.SS.user,
- canManageIssueFilters: !!window.SS.user,
- canManageMeasureFilters: !!window.SS.user
- });
- }
- });
-
-});
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
define([
'components/common/selectable-collection-view',
'./templates'
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-define([
- './templates'
-], function () {
-
- return Marionette.ItemView.extend({
- template: Templates['nav-settings-navbar'],
-
- modelEvents: {
- 'change:settings': 'render'
- }
- });
-
-});
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
define([
'components/common/modals',
'./templates'
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.
- */
-define(function () {
-
- var $ = jQuery;
-
- return Backbone.Model.extend({
-
- fetchGlobal: function () {
- var that = this;
- return $.get(baseUrl + '/api/navigation/global').done(function (r) {
- that.set(r);
- });
- },
-
- fetchComponent: function () {
- var that = this,
- url = baseUrl + '/api/navigation/component',
- data = { componentKey: this.get('componentKey') };
- return $.get(url, data).done(function (r) {
- that.set({ component: r });
- });
- },
-
- fetchSettings: function () {
- var that = this;
- return $.get(baseUrl + '/api/navigation/settings').done(function (r) {
- that.set({ settings: r });
- });
- }
-
- });
-
-});
+++ /dev/null
-<img src="{{link '/images/logo.svg'}}" alt="{{t 'layout.sonar.slogan'}}" title="{{t 'layout.sonar.slogan'}}">
+++ /dev/null
-{{#if labelLocalized}}{{labelLocalized}}{{else}}{{t label}}{{/if}}
+++ /dev/null
-<div class="container">
- {{#if component.canBeFavorite}}
- <div class="navbar-context-favorite">
- <a class="js-favorite {{#if component.isFavorite}}icon-favorite{{else}}icon-not-favorite{{/if}}"></a>
- </div>
- {{/if}}
- <ul class="nav navbar-nav nav-crumbs">
- {{#each component.breadcrumbs}}
- <li>
- <a href="{{componentPermalink key}}">
- {{qualifierIcon qualifier}} {{name}}
- </a>
- </li>
- {{/each}}
- </ul>
-
- <div class="navbar-right navbar-context-meta">
- {{#if component.version}}Version {{component.version}}{{/if}}
- {{#all component.version component.snapshotDate}}/{{/all}}
- {{#if component.snapshotDate}}{{dt component.snapshotDate}}{{/if}}
- </div>
-
- <ul class="nav navbar-nav nav-tabs">
- <li {{#isActiveLink '/overview'}}class="active"{{/isActiveLink}}>
- <a href="{{componentOverviewPermalink component.key}}">{{t 'overview.page'}}</a>
- </li>
- <li {{#isActiveLink '/components'}}class="active"{{/isActiveLink}}>
- <a href="{{componentBrowsePermalink component.key}}">{{t 'components.page'}}</a>
- </li>
- <li {{#isActiveLink '/component_issues'}}class="active"{{/isActiveLink}}>
- <a href="{{componentIssuesPermalink component.key}}">{{t 'issues.page'}}</a>
- </li>
- {{#if component.configuration.showSettings}}
- <li class="dropdown {{#if isSettingsActive}}active{{/if}}">
- <a class="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#">{{t 'layout.settings'}} <i
- class="icon-dropdown"></i></a>
- <ul class="dropdown-menu">
- <li>
- <a href="{{link '/project/settings?id=' contextKeyEncoded}}">{{t 'project_settings.page'}}</a>
- </li>
- {{#if component.configuration.showQualityProfiles}}
- <li>
- <a href="{{link '/project/profile?id=' contextKeyEncoded}}">{{t 'project_quality_profiles.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showQualityGates}}
- <li>
- <a href="{{link '/project/qualitygate?id=' contextKeyEncoded}}">{{t 'project_quality_gate.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showManualMeasures}}
- <li>
- <a href="{{link '/custom_measures/index?id=' contextKeyEncoded}}">{{t 'custom_measures.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showActionPlans}}
- <li>
- <a href="{{link '/action_plans/index?id=' contextKeyEncoded}}">{{t 'action_plans.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showLinks}}
- <li>
- <a href="{{link '/project/links?id=' contextKeyEncoded}}">{{t 'project_links.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showPermissions}}
- <li>
- <a href="{{link '/project_roles/index?id=' contextKeyEncoded}}">{{t 'permissions.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showHistory}}
- <li>
- <a href="{{link '/project/history?id=' contextKeyEncoded}}">{{t 'project_history.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showUpdateKey}}
- <li>
- <a href="{{link '/project/key?id=' contextKeyEncoded}}">{{t 'update_key.page'}}</a>
- </li>
- {{/if}}
- {{#if component.configuration.showDeletion}}
- <li>
- <a href="{{link '/project/deletion?id=' contextKeyEncoded}}">{{t 'deletion.page'}}</a>
- </li>
- {{/if}}
- {{#each component.configuration.extensions}}
- <li>
- <a href="{{link url}}">{{name}}</a>
- </li>
- {{/each}}
- </ul>
- </li>
- {{/if}}
- <li class="dropdown {{#if isMoreActive}}active{{/if}}">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">{{t 'more'}} <i class="icon-dropdown"></i></a>
- <ul class="dropdown-menu">
- <li class="dropdown-header">{{t 'layout.dashboards'}}</li>
- {{#each component.dashboards}}
- <li>
- <a href="{{componentDashboardPermalink ../component.key key}}">{{dashboardL10n name}}</a>
- </li>
- {{/each}}
- {{#if canManageContextDashboards}}
- <li class="small-divider"></li>
- <li>
- <a href="{{link '/dashboards?resource=' contextKeyEncoded}}">{{t 'dashboard.manage_dashboards'}}</a>
- </li>
- {{/if}}
- <li class="divider"></li>
- <li class="dropdown-header">Tools</li>
- {{#if component.isComparable}}
- <li>
- <a href="{{link '/comparison/index?resource=' contextKeyEncoded}}">{{t 'comparison.page'}}</a>
- </li>
- {{/if}}
- {{#each component.extensions}}
- <li>
- <a href="{{link url}}">{{name}}</a>
- </li>
- {{/each}}
- </ul>
- </li>
- </ul>
-</div>
+++ /dev/null
-<div class="container">
- <div class="navbar-header">
- <a class="navbar-brand {{#if logoUrl}}navbar-brand-custom{{/if}}" href="{{link '/'}}">
- {{#if logoUrl}}
- <img src="{{logoUrl}}" {{#if logoWidth}}width="{{logoWidth}}"{{/if}} height="30"
- alt="{{t 'layout.sonar.slogan'}}" title="{{t 'layout.sonar.slogan'}}">
- {{else}}
- {{> '_nav-logo'}}
- {{/if}}
- </a>
- </div>
-
- <ul class="nav navbar-nav">
- <li class="dropdown t-dashboards">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{t 'layout.dashboards'}} <span class="icon-dropdown"></span>
- </a>
- <ul class="dropdown-menu">
- {{#each globalDashboards}}
- <li>
- <a href="{{link '/dashboard/index?did=' key}}">{{dashboardL10n name}}</a>
- </li>
- {{/each}}
- {{#if canManageGlobalDashboards}}
- <li class="divider"></li>
- <li>
- <a href="{{link '/dashboards'}}">{{t 'dashboard.manage_dashboards'}}</a>
- </li>
- {{/if}}
- </ul>
- </li>
- <li {{#isActiveLink '/issues'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/issues/search'}}">{{t 'issues.page'}}</a>
- </li>
- <li {{#isActiveLink '/measures'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/measures/search?qualifiers[]=TRK'}}">{{t 'layout.measures'}}</a>
- </li>
- <li {{#isActiveLink '/coding_rules'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/coding_rules'}}">{{t 'coding_rules.page'}}</a>
- </li>
- <li {{#isActiveLink '/profiles'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/profiles'}}">{{t 'quality_profiles.page'}}</a>
- </li>
- <li {{#isActiveLink '/quality_gates'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/quality_gates'}}">{{t 'quality_gates.page'}}</a>
- </li>
- {{#if isUserAdmin}}
- <li {{#isActiveLink '/settings'}}class="active"{{/isActiveLink}}>
- <a class="navbar-admin-link" href="{{link '/settings'}}">{{t 'layout.settings'}}</a>
- </li>
- {{/if}}
- <li class="dropdown t-more">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">{{t 'more'}} <i class="icon-dropdown"></i></a>
- <ul class="dropdown-menu">
- <li>
- <a href="{{link '/comparison'}}">{{t 'comparison_global.page'}}</a>
- </li>
- {{#each globalPages}}
- <li>
- <a href="{{link url}}">{{name}}</a>
- </li>
- {{/each}}
- </ul>
- </li>
- </ul>
-
- <ul class="nav navbar-nav navbar-right">
- {{#if user}}
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{#ifShowAvatars}}<span class="little-spacer-right">{{avatarHelper userEmail 20}} {{/ifShowAvatars}}</span>{{userName}} <span class="icon-dropdown"></span>
- </a>
- <ul class="dropdown-menu dropdown-menu-right">
- <li>
- <a href="{{link '/account/index'}}">{{t 'layout.user_panel.my_profile'}}</a>
- </li>
- <li>
- <a href="{{link '/sessions/logout'}}"
- onclick="if (sonarRecentHistory) { sonarRecentHistory.clear(); }">{{t 'layout.logout'}}</a>
- </li>
- </ul>
- </li>
- {{else}}
- <li>
- <a class="js-login" href="{{link '/sessions/new'}}">{{t 'layout.login'}}</a>
- </li>
- {{/if}}
- <li class="dropdown js-search-dropdown">
- <a class="dropdown-toggle navbar-search-dropdown js-search-dropdown-toggle" data-toggle="dropdown" href="#">
- <i class="icon-search navbar-icon"></i> <span class="icon-dropdown"></span>
- </a>
-
- <div class="js-search-region dropdown-menu dropdown-menu-right"></div>
- </li>
- <li>
- <a class="js-shortcuts" href="#">
- <i class="icon-help navbar-icon"></i>
- </a>
- </li>
- </ul>
-
-</div>
+++ /dev/null
-<div class="container">
- <ul class="nav navbar-nav nav-crumbs">
- <li>
- <a href="{{link '/settings'}}">{{t 'layout.settings'}}</a>
- </li>
- </ul>
-
- <ul class="nav navbar-nav nav-tabs">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{t 'sidebar.project_settings'}} <i class="icon-dropdown"></i>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a href="{{link '/settings/index'}}">{{t 'settings.page'}}</a>
- </li>
- <li>
- <a href="{{link '/metrics/index'}}">Custom Metrics</a>
- </li>
- <li>
- <a href="{{link '/admin_dashboards/index'}}">{{t 'default_dashboards.page'}}</a>
- </li>
- {{#each settings.extensions}}
- <li>
- <a href="{{link url}}">{{name}}</a>
- </li>
- {{/each}}
- </ul>
- </li>
-
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{t 'sidebar.security'}} <i class="icon-dropdown"></i>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a href="{{link '/users'}}">{{t 'users.page'}}</a>
- </li>
- <li>
- <a href="{{link '/groups/index'}}">{{t 'user_groups.page'}}</a>
- </li>
- <li>
- <a href="{{link '/roles/global'}}">{{t 'global_permissions.page'}}</a>
- </li>
- <li>
- <a href="{{link '/roles/projects'}}">{{t 'roles.page'}}</a>
- </li>
- </ul>
- </li>
-
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{t 'sidebar.projects'}} <i class="icon-dropdown"></i>
- </a>
- <ul class="dropdown-menu">
- {{#if settings.showProvisioning}}
- <li>
- <a href="{{link '/provisioning'}}">{{t 'provisioning.page'}}</a>
- </li>
- {{/if}}
- <li>
- <a href="{{link '/bulk_deletion'}}">{{t 'bulk_deletion.page'}}</a>
- </li>
- <li>
- <a href="{{link '/computation'}}">{{t 'analysis_reports.page'}}</a>
- </li>
- </ul>
- </li>
-
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- {{t 'sidebar.system'}} <i class="icon-dropdown"></i>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a href="{{link '/updatecenter'}}">{{t 'update_center.page'}}</a>
- </li>
- <li>
- <a href="{{link '/system'}}">{{t 'system_info.page'}}</a>
- </li>
- </ul>
- </li>
- </ul>
-</div>
}
window.location = href;
});
-
-
- // Define global shortcuts
- key('s', function () {
- jQuery('.js-search-dropdown-toggle').dropdown('toggle');
- return false;
- });
});
})();