aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-05-05 15:15:16 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-05-05 15:30:38 +0200
commitcc181b8b100ffe35424217bfcb07f946938d32f0 (patch)
treedd436b931118ab449020690d1c1c86dab8498983 /server/sonar-web/src
parent20395938652f7439f9e5c0f1eb2687800658b42d (diff)
downloadsonarqube-cc181b8b100ffe35424217bfcb07f946938d32f0.tar.gz
sonarqube-cc181b8b100ffe35424217bfcb07f946938d32f0.zip
apply new navigation WS
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/hbs/nav/nav-context-navbar.hbs95
-rw-r--r--server/sonar-web/src/main/hbs/nav/nav-global-navbar.hbs2
-rw-r--r--server/sonar-web/src/main/hbs/nav/nav-settings-navbar.hbs6
-rw-r--r--server/sonar-web/src/main/js/common/handlebars-extensions.js17
-rw-r--r--server/sonar-web/src/main/js/nav/app.js36
-rw-r--r--server/sonar-web/src/main/js/nav/context-navbar-view.js4
-rw-r--r--server/sonar-web/src/main/js/nav/global-navbar-view.js4
-rw-r--r--server/sonar-web/src/main/js/nav/search-view.js2
-rw-r--r--server/sonar-web/src/main/js/nav/settings-navbar-view.js6
-rw-r--r--server/sonar-web/src/main/js/nav/state.js51
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf.html.erb43
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_context.html.erb168
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_global.html.erb44
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_settings.html.erb25
-rw-r--r--server/sonar-web/src/test/js/nav-spec.js80
-rw-r--r--server/sonar-web/src/test/json/nav-spec/component.json37
-rw-r--r--server/sonar-web/src/test/json/nav-spec/global.json39
17 files changed, 293 insertions, 366 deletions
diff --git a/server/sonar-web/src/main/hbs/nav/nav-context-navbar.hbs b/server/sonar-web/src/main/hbs/nav/nav-context-navbar.hbs
index 4d639ec0351..730f20a001c 100644
--- a/server/sonar-web/src/main/hbs/nav/nav-context-navbar.hbs
+++ b/server/sonar-web/src/main/hbs/nav/nav-context-navbar.hbs
@@ -1,40 +1,89 @@
<div class="container">
- {{# if canFavoriteContext}}
+ {{#if component.canBeFavorite}}
<div class="navbar-context-favorite">
- <a class="js-favorite {{#if isContextFavorite}}icon-favorite{{else}}icon-not-favorite{{/if}}"></a>
+ <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 contextBreadcrumbs}}
+ {{#each component.breadcrumbs}}
<li>
- <a href="{{link url}}">
- {{qualifierIcon q}}&nbsp;{{name}}
+ <a href="{{componentPermalink key}}">
+ {{qualifierIcon qualifier}}&nbsp;{{name}}
</a>
</li>
{{/each}}
</ul>
<div class="navbar-right navbar-context-meta">
- {{#if contextVersion}}Version {{contextVersion}}{{/if}}
- {{#all contextVersion contextDate}}/{{/all}}
- {{#if contextDate}}{{dt contextDate}}{{/if}}
+ {{#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 {{#if isOverviewActive}}class="active"{{/if}}>
- <a href="{{link '/dashboard/index?id=' contextKeyEncoded }}">{{t 'overview.page'}}</a>
+ <a href="{{componentPermalink component.key}}">{{t 'overview.page'}}</a>
</li>
<li {{#isActiveLink '/components'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/components/index/' contextId }}">{{t 'components.page'}}</a>
+ <a href="{{componentBrowsePermalink component.key}}">{{t 'components.page'}}</a>
</li>
<li {{#isActiveLink '/component_issues'}}class="active"{{/isActiveLink}}>
- <a href="{{link '/component_issues/index?id=' contextKeyEncoded }}">{{t 'issues.page'}}</a>
+ <a href="{{componentIssuesPermalink component.key}}">{{t 'issues.page'}}</a>
</li>
- {{#if contextConfiguration}}
+ {{#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'}}&nbsp;<i class="icon-dropdown"></i></a>
+ <a class="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#">{{t 'layout.settings'}}&nbsp;<i
+ class="icon-dropdown"></i></a>
<ul class="dropdown-menu">
- {{#each contextConfiguration}}
+ <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 '/manual_measures/index?id=' contextKeyEncoded}}">{{t 'manual_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>
@@ -46,33 +95,33 @@
<a class="dropdown-toggle" data-toggle="dropdown" href="#">{{t 'more'}}&nbsp;<i class="icon-dropdown"></i></a>
<ul class="dropdown-menu">
<li class="dropdown-header">{{t 'layout.dashboards'}}</li>
- {{#withoutFirst contextDashboards}}
+ {{#withoutFirst component.dashboards}}
<li>
- <a href="{{link url}}">{{name}}</a>
+ <a href="{{componentDashboardPermalink ../component.key key}}">{{name}}</a>
</li>
{{/withoutFirst}}
{{#if canManageContextDashboards}}
<li class="small-divider"></li>
<li>
- <a href="{{link '/dashboards?resource=' contextId}}">{{t 'dashboard.manage_dashboards'}}</a>
+ <a href="{{link '/dashboards?resource=' contextKeyEncoded}}">{{t 'dashboard.manage_dashboards'}}</a>
</li>
{{/if}}
<li class="divider"></li>
<li class="dropdown-header">Tools</li>
<li>
- <a href="{{link '/design/index/' contextId }}">{{t 'design.page'}}</a>
+ <a href="{{link '/design/index?id=' contextKeyEncoded}}">{{t 'design.page'}}</a>
</li>
<li>
- <a href="{{link '/libraries/index/' contextId }}">{{t 'libraries.page'}}</a>
+ <a href="{{link '/libraries/index?id=' contextKeyEncoded}}">{{t 'libraries.page'}}</a>
</li>
- {{#if contextComparable}}
+ {{#if component.isComparable}}
<li>
- <a href="{{link '/comparison/index?resource=' contextKey}}">{{t 'comparison.page'}}</a>
+ <a href="{{link '/comparison/index?resource=' contextKeyEncoded}}">{{t 'comparison.page'}}</a>
</li>
{{/if}}
- {{#each contextExtensions}}
+ {{#each component.extensions}}
<li>
- <a href="{{link url}}">{{label}}</a>
+ <a href="{{link url}}">{{name}}</a>
</li>
{{/each}}
</ul>
diff --git a/server/sonar-web/src/main/hbs/nav/nav-global-navbar.hbs b/server/sonar-web/src/main/hbs/nav/nav-global-navbar.hbs
index 6a630910b68..806fceb056b 100644
--- a/server/sonar-web/src/main/hbs/nav/nav-global-navbar.hbs
+++ b/server/sonar-web/src/main/hbs/nav/nav-global-navbar.hbs
@@ -18,7 +18,7 @@
<ul class="dropdown-menu">
{{#each globalDashboards}}
<li>
- <a href="{{link url}}">{{name}}</a>
+ <a href="{{link '/dashboard/index?did=' key}}">{{name}}</a>
</li>
{{/each}}
{{#if canManageGlobalDashboards}}
diff --git a/server/sonar-web/src/main/hbs/nav/nav-settings-navbar.hbs b/server/sonar-web/src/main/hbs/nav/nav-settings-navbar.hbs
index 667dc00b5ad..5cc7dbbc1ed 100644
--- a/server/sonar-web/src/main/hbs/nav/nav-settings-navbar.hbs
+++ b/server/sonar-web/src/main/hbs/nav/nav-settings-navbar.hbs
@@ -20,7 +20,7 @@
<li>
<a href="{{link '/admin_dashboards/index'}}">{{t 'default_dashboards.page'}}</a>
</li>
- {{#each settingsPages}}
+ {{#each settings.extensions}}
<li>
<a href="{{link url}}">{{name}}</a>
</li>
@@ -53,7 +53,7 @@
{{t 'sidebar.projects'}}&nbsp;<i class="icon-dropdown"></i>
</a>
<ul class="dropdown-menu">
- {{#if settingsProvisioning}}
+ {{#if settings.showProvisioning}}
<li>
<a href="{{link '/provisioning'}}">{{t 'provisioning.page'}}</a>
</li>
@@ -72,7 +72,7 @@
{{t 'sidebar.system'}}&nbsp;<i class="icon-dropdown"></i>
</a>
<ul class="dropdown-menu">
- {{#if settingsUpdateCenter}}
+ {{#if settings.showUpdateCenter}}
<li>
<a href="{{link '/updatecenter'}}">{{t 'update_center.page'}}</a>
</li>
diff --git a/server/sonar-web/src/main/js/common/handlebars-extensions.js b/server/sonar-web/src/main/js/common/handlebars-extensions.js
index 2ad4f37af99..f6cb754d666 100644
--- a/server/sonar-web/src/main/js/common/handlebars-extensions.js
+++ b/server/sonar-web/src/main/js/common/handlebars-extensions.js
@@ -30,6 +30,23 @@
return baseUrl + url;
});
+ Handlebars.registerHelper('componentPermalink', function (componentKey) {
+ return baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey);
+ });
+
+ Handlebars.registerHelper('componentDashboardPermalink', function (componentKey, dashboardKey) {
+ return baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey) +
+ '&did=' + encodeURIComponent(dashboardKey);
+ });
+
+ Handlebars.registerHelper('componentBrowsePermalink', function (componentKey) {
+ return baseUrl + '/components/index?id=' + encodeURIComponent(componentKey);
+ });
+
+ Handlebars.registerHelper('componentIssuesPermalink', function (componentKey) {
+ return baseUrl + '/component_issues/index?id=' + encodeURIComponent(componentKey);
+ });
+
Handlebars.registerHelper('rulePermalink', function (ruleKey) {
return baseUrl + '/coding_rules#rule_key=' + encodeURIComponent(ruleKey);
});
diff --git a/server/sonar-web/src/main/js/nav/app.js b/server/sonar-web/src/main/js/nav/app.js
index 9d495f433b1..880e1f549f2 100644
--- a/server/sonar-web/src/main/js/nav/app.js
+++ b/server/sonar-web/src/main/js/nav/app.js
@@ -18,55 +18,55 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'nav/state',
'nav/global-navbar-view',
'nav/context-navbar-view',
'nav/settings-navbar-view',
'workspace/main'
-], function (GlobalNavbarView, ContextNavbarView, SettingsNavbarView) {
+], function (State, GlobalNavbarView, ContextNavbarView, SettingsNavbarView) {
var $ = jQuery,
App = new Marionette.Application(),
- model = window.navbarOptions;
+ state = new State();
+
+ state.set(window.navbarOptions.toJSON());
+
+ App.on('start', function () {
+ state.fetchGlobal();
- App.addInitializer(function () {
this.navbarView = new GlobalNavbarView({
app: App,
el: $('.navbar-global'),
- model: model
+ model: state
});
this.navbarView.render();
- });
- if (model.has('contextBreadcrumbs')) {
- App.addInitializer(function () {
+ if (state.get('space') === 'component') {
+ state.fetchComponent();
this.contextNavbarView = new ContextNavbarView({
app: App,
el: $('.navbar-context'),
- model: model
+ model: state
});
this.contextNavbarView.render();
- });
- }
+ }
- if (model.get('space') === 'settings') {
- App.addInitializer(function () {
+ if (state.get('space') === 'settings') {
+ state.fetchSettings();
this.settingsNavbarView = new SettingsNavbarView({
app: App,
el: $('.navbar-context'),
- model: model
+ model: state
});
this.settingsNavbarView.render();
- });
- }
+ }
- App.addInitializer(function () {
- var that = this;
$(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) {
- that.navbarView.showShortcutsHelp();
+ App.navbarView.showShortcutsHelp();
}
}
});
diff --git a/server/sonar-web/src/main/js/nav/context-navbar-view.js b/server/sonar-web/src/main/js/nav/context-navbar-view.js
index dd31145c4ce..2d13705c406 100644
--- a/server/sonar-web/src/main/js/nav/context-navbar-view.js
+++ b/server/sonar-web/src/main/js/nav/context-navbar-view.js
@@ -35,7 +35,7 @@ define([
template: Templates['nav-context-navbar'],
modelEvents: {
- 'change': 'render'
+ 'change:component': 'render'
},
events: {
@@ -70,7 +70,7 @@ define([
isOverviewActive = !isMoreActive && href.indexOf('/dashboard') !== -1 && search.indexOf('did=') === -1;
return _.extend(Marionette.Layout.prototype.serializeData.apply(this, arguments), {
canManageContextDashboards: !!window.SS.user,
- contextKeyEncoded: encodeURIComponent(this.model.get('contextKey')),
+ contextKeyEncoded: encodeURIComponent(this.model.get('componentKey')),
isOverviewActive: isOverviewActive,
isSettingsActive: isSettingsActive,
diff --git a/server/sonar-web/src/main/js/nav/global-navbar-view.js b/server/sonar-web/src/main/js/nav/global-navbar-view.js
index 64b199752a1..b5435662373 100644
--- a/server/sonar-web/src/main/js/nav/global-navbar-view.js
+++ b/server/sonar-web/src/main/js/nav/global-navbar-view.js
@@ -26,6 +26,10 @@ define([
return Marionette.Layout.extend({
template: Templates['nav-global-navbar'],
+ modelEvents: {
+ 'change': 'render'
+ },
+
regions: {
searchRegion: '.js-search-region'
},
diff --git a/server/sonar-web/src/main/js/nav/search-view.js b/server/sonar-web/src/main/js/nav/search-view.js
index e7e4bc9e370..7736cda0a04 100644
--- a/server/sonar-web/src/main/js/nav/search-view.js
+++ b/server/sonar-web/src/main/js/nav/search-view.js
@@ -225,7 +225,7 @@ define([
getGlobalDashboardFindings: function (q) {
var dashboards = this.model.get('globalDashboards') || [],
items = dashboards.map(function (d) {
- return { name: d.name, url: baseUrl + d.url };
+ return { name: d.name, url: baseUrl + '/dashboard/index?did=' + encodeURIComponent(d.key) };
});
var findings = items.filter(function (f) {
return f.name.match(new RegExp(q, 'i'));
diff --git a/server/sonar-web/src/main/js/nav/settings-navbar-view.js b/server/sonar-web/src/main/js/nav/settings-navbar-view.js
index 58865ccd2ae..5fb2616a55c 100644
--- a/server/sonar-web/src/main/js/nav/settings-navbar-view.js
+++ b/server/sonar-web/src/main/js/nav/settings-navbar-view.js
@@ -22,7 +22,11 @@ define([
], function () {
return Marionette.ItemView.extend({
- template: Templates['nav-settings-navbar']
+ template: Templates['nav-settings-navbar'],
+
+ modelEvents: {
+ 'change:settings': 'render'
+ }
});
});
diff --git a/server/sonar-web/src/main/js/nav/state.js b/server/sonar-web/src/main/js/nav/state.js
new file mode 100644
index 00000000000..f41557663ee
--- /dev/null
+++ b/server/sonar-web/src/main/js/nav/state.js
@@ -0,0 +1,51 @@
+/*
+ * 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 });
+ });
+ }
+
+ });
+
+});
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf.html.erb
index 4df94dfcd71..194fe53bd42 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf.html.erb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf.html.erb
@@ -1,35 +1,22 @@
-<script>
- window.navbarOptions = new Backbone.Model();
-
- window.navbarOptions.set({
- qualifiers: [
- <% qualifiers = Project.root_qualifiers.sort
- qualifiers.each_with_index do |qualifier, index| %>
- '<%= qualifier -%>'<% if index < qualifiers.size - 1 %>,<% end %>
- <% end %>
- ]
- });
- window.SS.isUserAdmin = <%= current_user && is_admin? ? 'true' : 'false' -%>;
-</script>
-
-
-
<%
selected_section = controller.class::SECTION if defined?(controller.class::SECTION)
- if selected_section==Navigation::SECTION_RESOURCE && !@project && !@resource
+ if selected_section == Navigation::SECTION_RESOURCE && !@project && !@resource
selected_section = Navigation::SECTION_HOME
end
- @project=@resource unless @project || selected_section==Navigation::SECTION_HOME
- period_param = "period=#{u(params[:period])}" if params[:period]
- displayed_resource = @resource || @project
- display_only_root = @issue
- resource_id=displayed_resource ? (displayed_resource.is_a?(Fixnum) ? displayed_resource : displayed_resource.permanent_id) : nil
+
+ @project = @resource unless @project || selected_section == Navigation::SECTION_HOME
%>
-<%= render :partial => 'layouts/navbar_conf_global' %>
+<script>
+ window.navbarOptions = new Backbone.Model();
+
+ <% if selected_section == Navigation::SECTION_RESOURCE %>
+ window.navbarOptions.set({ space: 'component', componentKey: '<%= escape_javascript @project.key -%>' });
+ <% end %>
-<% if selected_section==Navigation::SECTION_RESOURCE %>
- <%= render :partial => 'layouts/navbar_conf_context' %>
-<% elsif selected_section==Navigation::SECTION_CONFIGURATION %>
- <%= render :partial => 'layouts/navbar_conf_settings' %>
-<% end %>
+ <% if selected_section == Navigation::SECTION_CONFIGURATION %>
+ window.navbarOptions.set({ space: 'settings' });
+ <% end %>
+
+ window.SS.isUserAdmin = <%= current_user && is_admin? ? 'true' : 'false' -%>;
+</script>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_context.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_context.html.erb
deleted file mode 100644
index cbd190fe575..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_context.html.erb
+++ /dev/null
@@ -1,168 +0,0 @@
-<%
- @project=@resource unless @project || selected_section==Navigation::SECTION_HOME
- period_param = "period=#{u(params[:period])}" if params[:period]
- displayed_resource = @resource || @project
- display_only_root = @issue
- resource_id=displayed_resource ? (displayed_resource.is_a?(Fixnum) ? displayed_resource : displayed_resource.permanent_id) : nil
-%>
-
-
-<script>
- window.navbarOptions.set({
- contextId: '<%= @project.id -%>',
- contextKey: '<%= @project.key -%>',
- contextUuid: '<%= @project.uuid -%>',
- contextComparable: <%= controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'comparable') -%>,
- canFavoriteContext: <%= logged_in? && displayed_resource && !display_only_root ? 'true' : 'false' -%>,
- isContextFavorite: <%= logged_in? && current_user.favourite?(resource_id) ? 'true' : 'false' -%>,
- <% if @snapshot && @snapshot.version.present? %>
- contextVersion: '<%= @snapshot.version -%>',
- <% end %>
- <% if @snapshot %>
- contextDate: '<%= @snapshot.created_at.strftime('%FT%T%:z') -%>',
- <% end %>
- contextDashboards: [
- <% dashboards = ActiveDashboard.user_dashboards(current_user, false)
- dashboards.each_with_index do |active_dashboard, index| %>
- {
- url: '/dashboard/index?id=<%= @project.key -%>&did=<%= active_dashboard.dashboard_id -%><%= "&"+period_param if period_param -%>',
- name: '<%= escape_javascript active_dashboard.dashboard.name(true) -%>'
- }<% if index < dashboards.size - 1 -%>, <% end %>
- <% end %>
- ],
- contextExtensions: [
- <% project_metrics = @project.last_snapshot.metric_keys.to_java(:string) if @project.last_snapshot
- pages = controller.java_facade.getPages(Navigation::SECTION_RESOURCE.key, @project.scope, @project.qualifier, @project.language, project_metrics)
- pages.each_with_index do |page, index|
- page_url = (page.isController() ? "#{page.getId()}?id=#{@project.id}" : "/plugins/resource/#{@project.id}?page=#{page.getId()}")
- %>
- {
- url: '<%= page_url -%>',
- label: '<%= escape_javascript message(page.getId() + '.page', :default => page.getTitle()) -%>'
- }<% if index < pages.size - 1 -%>, <% end %>
- <% end %>
- ]
- });
-
- <% if (has_role?(:admin, displayed_resource) || profiles_administrator?) && !displayed_resource.entity? %>
- <% is_admin = has_role?(:admin, @project) %>
- window.navbarOptions.set({
- contextConfiguration: [
- <% if (is_admin && controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'configurable')) %>
- {
- url: '/project/settings/<%= @project.id -%>',
- name: '<%= escape_javascript message('project_settings.page') -%>'
- },
- <% end %>
- <% if (@project.project?) %>
- {
- url: '/project/profile/<%= @project.id -%>',
- name: '<%= escape_javascript message('project_quality_profiles.page') -%>'
- },
- <% end %>
- <% if (@project.project?) %>
- {
- url: '/project/qualitygate/<%= @project.id -%>',
- name: '<%= escape_javascript message('project_quality_gate.page') -%>'
- },
- <% end %>
- <% if is_admin %>
- {
- url: '/manual_measures/index/<%= @project.id -%>',
- name: '<%= escape_javascript message('manual_measures.page') -%>'
- },
- <% end %>
- <% if (is_admin && @project.project?) %>
- {
- url: '/action_plans/index/<%= @project.id -%>',
- name: '<%= escape_javascript message('action_plans.page') -%>'
- },
- <% end %>
- <% if (is_admin && @project.project?) %>
- {
- url: '/project/links/<%= @project.id -%>',
- name: '<%= escape_javascript message('project_links.page') -%>'
- },
- <% end %>
- <% if is_admin && controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'hasRolePolicy') %>
- {
- url: '/project_roles/index/<%= @project.id -%>',
- name: '<%= escape_javascript message('permissions.page') -%>'
- },
- <% end %>
- <% if is_admin && controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'modifiable_history') %>
- {
- url: '/project/history/<%= @project.id -%>',
- name: '<%= escape_javascript message('project_history.page') -%>'
- },
- <% end %>
- <% if is_admin && controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'updatable_key') %>
- {
- url: '/project/key/<%= @project.id -%>',
- name: '<%= escape_javascript message('update_key.page') -%>'
- },
- <% end %>
- <% if is_admin && controller.java_facade.getResourceTypeBooleanProperty(@project.qualifier, 'deletable') %>
- {
- url: '/project/deletion/<%= @project.id -%>',
- name: '<%= escape_javascript message('deletion.page') -%>'
- },
- <% end %>
- <% if is_admin
- controller.java_facade.getPages(Navigation::SECTION_RESOURCE_CONFIGURATION.key, @project.scope, @project.qualifier, @project.language, nil).each do |page|
- page_url = "#{page.getId()}?resource=#{@project.id}"
- %>
- {
- url: '<%= page_url -%>',
- name: '<%= escape_javascript message(page.getId() + '.page', :default => page.getTitle()) -%>'
- },
- <% end end %>
- ]
- });
- <% end %>
-
- window.navbarOptions.set({
- contextBreadcrumbs: [
- <%
- resource_link = {:controller => params[:controller], :action => params[:action]}
- if display_only_root
- resource_link = {:controller => 'dashboard', :action => 'index'}
- end
-
- # ======== Path for resources ========
-
- if displayed_resource
- if displayed_resource.last_snapshot
- resources=[]
- s=displayed_resource.last_snapshot
- while (s!=nil) do
- resources.insert(0, s.project)
- s=s.parent
- end
- else
- resources = [displayed_resource]
- end
- %>
- <%
- resources.each do |resource|
- root = "/#{u resource_link[:controller]}/#{u resource_link[:action]}?"
- path = ''
- query = request.query_parameters
- query[:id] = resource.key
- query.each do |key, value|
- path += '&' unless path.empty?
- path += "#{u key}=#{u value}"
- end
- %>
- {
- q: '<%= resource.qualifier -%>',
- url: '<%= root + path -%>',
- name: '<%= escape_javascript resource.name -%>'
- },
- <%
- end
- end
- %>
- ]
- });
-</script>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_global.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_global.html.erb
deleted file mode 100644
index c41b43add15..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_global.html.erb
+++ /dev/null
@@ -1,44 +0,0 @@
-<%
- selected_section = controller.class::SECTION if defined?(controller.class::SECTION)
- if selected_section==Navigation::SECTION_RESOURCE && !@project && !@resource
- selected_section = Navigation::SECTION_HOME
- end
-%>
-
-<script>
- window.navbarOptions.set({
- globalDashboards: [
- <% dashboards = ActiveDashboard.user_dashboards(current_user, true)
- dashboards.each_with_index do |dashboard, index| %>
- {
- url: '/dashboard/?did=<%= dashboard.dashboard_id -%>',
- name: '<%= escape_javascript dashboard.dashboard.name(true) -%>'
- }<% if index < dashboards.size - 1 -%>, <% end %>
- <% end %>
- ],
- globalPages: [
- <% pages = controller.java_facade.getPages(Navigation::SECTION_HOME.key, nil, nil, nil, nil)
- pages.each_with_index do |page, index|
- %>
- {
- url: '<%= page.isController() ? page.getId() : "/plugins/home/#{page.getId()}" -%>',
- name: '<%= escape_javascript message(page.getId() + '.page', :default => page.getTitle()) -%>'
- }<% if index < pages.size - 1 -%>, <% end %>
- <% end %>
- ],
- <%
- logo_url = property_value_by_key('sonar.lf.logoUrl')
- logo_width = property_value_by_key('sonar.lf.logoWidthPx')
- %>
- <%
- if logo_url
- %>
- logoUrl: '<%= escape_javascript logo_url -%>',
- <% end %>
- <%
- if logo_width
- %>
- logoWidth: '<%= escape_javascript logo_width -%>'
- <% end %>
- });
-</script>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_settings.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_settings.html.erb
deleted file mode 100644
index 772c56bafed..00000000000
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_navbar_conf_settings.html.erb
+++ /dev/null
@@ -1,25 +0,0 @@
-<%
- selected_section = controller.class::SECTION if defined?(controller.class::SECTION)
- if selected_section==Navigation::SECTION_RESOURCE && !@project && !@resource
- selected_section = Navigation::SECTION_HOME
- end
-%>
-
-<script>
- window.navbarOptions.set({
- space: 'settings',
- settingsPages: [
- <% pages = controller.java_facade.getPages(Navigation::SECTION_CONFIGURATION.key, nil, nil, nil, nil)
- pages.each_with_index do |page, index|
- page_url = (page.isController() ? page.getId() : "/plugins/configuration/#{page.getId()}")
- %>
- {
- url: '<%= page_url -%>',
- name: '<%= escape_javascript message(page.getId() + '.page', :default => page.getTitle()) %>'
- }<% if index < pages.size - 1 -%>, <% end %>
- <% end %>
- ],
- settingsProvisioning: <%= has_role?("provisioning") -%>,
- settingsUpdateCenter: <%= controller.java_facade.getSettings().getBoolean('sonar.updatecenter.activate') -%>
- });
-</script>
diff --git a/server/sonar-web/src/test/js/nav-spec.js b/server/sonar-web/src/test/js/nav-spec.js
index 89f7552246f..f5c21461e27 100644
--- a/server/sonar-web/src/test/js/nav-spec.js
+++ b/server/sonar-web/src/test/js/nav-spec.js
@@ -32,6 +32,8 @@ casper.test.begin(testName('Global Spaces'), 8, function (test) {
casper
.start(lib.buildUrl('nav'), function () {
lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/navigation/global', 'global.json');
})
.then(function () {
@@ -76,49 +78,44 @@ casper.test.begin(testName('Global Dashboards'), 12, function (test) {
casper
.start(lib.buildUrl('nav'), function () {
lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/navigation/global', 'global.json');
})
.then(function () {
casper.evaluate(function () {
window.SS.isUserAdmin = false;
window.navbarOptions = new Backbone.Model();
- window.navbarOptions.set({
- globalDashboards: [
- { url: '/dashboard/?did=1', name: 'First Global Dashboard' },
- { url: '/dashboard/?did=2', name: 'Second Global Dashboard' },
- { url: '/dashboard/?did=3', name: 'Third Global Dashboard' }
- ]
- });
require(['/js/nav/app.js']);
});
})
.then(function () {
- casper.waitForSelector('.navbar-global .nav');
+ casper.waitForSelector('.navbar-global a[href*="/dashboard/index?did=1"]');
})
.then(function () {
// check links existence
- test.assertExists('.navbar-global a[href*="/dashboard/?did=1"]');
- test.assertSelectorContains('.navbar-global a[href*="/dashboard/?did=1"]', 'First Global Dashboard');
- test.assertExists('.navbar-global a[href*="/dashboard/?did=2"]');
- test.assertSelectorContains('.navbar-global a[href*="/dashboard/?did=2"]', 'Second Global Dashboard');
- test.assertExists('.navbar-global a[href*="/dashboard/?did=3"]');
- test.assertSelectorContains('.navbar-global a[href*="/dashboard/?did=3"]', 'Third Global Dashboard');
+ test.assertExists('.navbar-global a[href*="/dashboard/index?did=1"]');
+ test.assertSelectorContains('.navbar-global a[href*="/dashboard/index?did=1"]', 'First Global Dashboard');
+ test.assertExists('.navbar-global a[href*="/dashboard/index?did=2"]');
+ test.assertSelectorContains('.navbar-global a[href*="/dashboard/index?did=2"]', 'Second Global Dashboard');
+ test.assertExists('.navbar-global a[href*="/dashboard/index?did=3"]');
+ test.assertSelectorContains('.navbar-global a[href*="/dashboard/index?did=3"]', 'Third Global Dashboard');
})
.then(function () {
// check that dashboards are not visible by default
- test.assertNotVisible('.navbar-global a[href*="/dashboard/?did=1"]');
- test.assertNotVisible('.navbar-global a[href*="/dashboard/?did=2"]');
- test.assertNotVisible('.navbar-global a[href*="/dashboard/?did=3"]');
+ test.assertNotVisible('.navbar-global a[href*="/dashboard/index?did=1"]');
+ test.assertNotVisible('.navbar-global a[href*="/dashboard/index?did=2"]');
+ test.assertNotVisible('.navbar-global a[href*="/dashboard/index?did=3"]');
// check dropdown
casper.click('.navbar-global .t-dashboards [data-toggle="dropdown"]');
- test.assertVisible('.navbar-global a[href*="/dashboard/?did=1"]');
- test.assertVisible('.navbar-global a[href*="/dashboard/?did=2"]');
- test.assertVisible('.navbar-global a[href*="/dashboard/?did=3"]');
+ test.assertVisible('.navbar-global a[href*="/dashboard/index?did=1"]');
+ test.assertVisible('.navbar-global a[href*="/dashboard/index?did=2"]');
+ test.assertVisible('.navbar-global a[href*="/dashboard/index?did=3"]');
})
.then(function () {
@@ -135,26 +132,21 @@ casper.test.begin(testName('Global Plugin Pages'), 12, function (test) {
casper
.start(lib.buildUrl('nav'), function () {
lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/navigation/global', 'global.json');
})
.then(function () {
casper.evaluate(function () {
window.SS.isUserAdmin = false;
window.navbarOptions = new Backbone.Model();
- window.navbarOptions.set({
- globalPages: [
- { url: '/page/1', name: 'First Global Page' },
- { url: '/page/2', name: 'Second Global Page' },
- { url: '/page/3', name: 'Third Global Page' }
- ]
- });
require(['/js/nav/app.js']);
});
})
.then(function () {
- casper.waitForSelector('.navbar-global .nav');
+ casper.waitForSelector('.navbar-global a[href*="/page/1"]');
})
.then(function () {
@@ -233,6 +225,7 @@ casper.test.begin(testName('Search'), 24, function (test) {
.start(lib.buildUrl('nav'), function () {
lib.setDefaultViewport();
+ lib.mockRequestFromFile('/api/navigation/global', 'global.json');
lib.mockRequestFromFile('/api/components/suggestions', 'search.json');
lib.mockRequestFromFile('/api/favourites', 'favorite.json');
})
@@ -242,8 +235,6 @@ casper.test.begin(testName('Search'), 24, function (test) {
window.SS.user = 'user';
window.SS.isUserAdmin = false;
window.navbarOptions = new Backbone.Model();
- window.navbarOptions.set({ qualifiers: ['TRK', 'VW', 'DEV'] });
- window.navbarOptions.set({ globalDashboards: [{ name: 'Quality', url: '/dashboard/?did=50' }] });
window.localStorage.setItem('sonar_recent_history',
'[{"key":"localhistoryproject","name":"Local History Project","icon":"trk"}]');
@@ -252,7 +243,7 @@ casper.test.begin(testName('Search'), 24, function (test) {
})
.then(function () {
- casper.waitForSelector('.navbar-global .nav');
+ casper.waitForSelector('.navbar-global a[href*="/page/1"]');
})
.then(function () {
@@ -292,7 +283,7 @@ casper.test.begin(testName('Search'), 24, function (test) {
test.assertElementCount('.js-search-results a', 7);
test.assertExists('.js-search-results a[href*="/profiles"]');
test.assertExists('.js-search-results a[href*="/quality_gates"]');
- test.assertExists('.js-search-results a[href*="/dashboard/?did=50"]');
+ test.assertExists('.js-search-results a[href*="/dashboard/index?did=50"]');
test.assertExists('.js-search-results a[href*="quality-project"]');
test.assertSelectorContains('.js-search-results a', 'SonarQube Java');
test.assertSelectorContains('.js-search-results a', 'SonarQube Java :: Squid');
@@ -331,38 +322,23 @@ casper.test.begin(testName('Context'), function (test) {
casper
.start(lib.buildUrl('nav'), function () {
lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/navigation/component', 'component.json',
+ { data: { componentKey: 'org.codehaus.sonar-plugins.java:java' } });
})
.then(function () {
casper.evaluate(function () {
window.SS.isUserAdmin = false;
window.navbarOptions = new Backbone.Model();
- window.navbarOptions.set({
- contextId: '1',
- contextKey: 'org.codehaus.sonar-plugins.java:java',
- contextUuid: 'acfc6a2d-d28c-4302-987c-697544fb096e',
- contextComparable: true,
- canFavoriteContext: false,
- isContextFavorite: false,
- contextVersion: '2.9-SNAPSHOT',
- contextDate: '2015-03-03T09:43:37+01:00'
- });
- window.navbarOptions.set({
- contextBreadcrumbs: [
- {
- q: 'TRK',
- url: '/dashboard/index?id=org.codehaus.sonar-plugins.java%3Ajava',
- name: 'SonarQube Java'
- }
- ]
- });
+ window.navbarOptions.set({ space: 'component', componentKey: 'org.codehaus.sonar-plugins.java:java' });
require(['/js/nav/app.js']);
});
})
.then(function () {
- casper.waitForSelector('.navbar-context .nav');
+ casper.waitForText('SonarQube Java');
})
.then(function () {
diff --git a/server/sonar-web/src/test/json/nav-spec/component.json b/server/sonar-web/src/test/json/nav-spec/component.json
new file mode 100644
index 00000000000..aaa0c919da2
--- /dev/null
+++ b/server/sonar-web/src/test/json/nav-spec/component.json
@@ -0,0 +1,37 @@
+{
+ "key": "org.codehaus.sonar-plugins.java:java",
+ "uuid": "acfc6a2d-d28c-4302-987c-697544fb096e",
+ "name": "MAIF :: Cobol plugin",
+ "isComparable": true,
+ "canBeFavorite": false,
+ "isFavorite": false,
+ "dashboards": [
+ {
+ "key": 1,
+ "name": "Main Dashboard"
+ }
+ ],
+ "version": "2.9-SNAPSHOT",
+ "snapshotDate": "2015-03-03T09:43:37+01:00",
+ "extensions": [],
+ "configuration": {
+ "showSettings": true,
+ "showQualityProfiles": true,
+ "showQualityGates": true,
+ "showManualMeasures": true,
+ "showActionPlans": true,
+ "showLinks": true,
+ "showPermissions": true,
+ "showHistory": true,
+ "showUpdateKey": true,
+ "showDeletion": true,
+ "extensions": []
+ },
+ "breadcrumbs": [
+ {
+ "key": "/dashboard/index?id=org.codehaus.sonar-plugins.java%3Ajava",
+ "name": "SonarQube Java",
+ "qualifier": "TRK"
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/nav-spec/global.json b/server/sonar-web/src/test/json/nav-spec/global.json
new file mode 100644
index 00000000000..709993d8f2a
--- /dev/null
+++ b/server/sonar-web/src/test/json/nav-spec/global.json
@@ -0,0 +1,39 @@
+{
+ "globalDashboards": [
+ {
+ "key": 1,
+ "name": "First Global Dashboard"
+ },
+ {
+ "key": 2,
+ "name": "Second Global Dashboard"
+ },
+ {
+ "key": 3,
+ "name": "Third Global Dashboard"
+ },
+ {
+ "key": 50,
+ "name": "Quality"
+ }
+ ],
+ "globalPages": [
+ {
+ "url": "/page/1",
+ "name": "First Global Page"
+ },
+ {
+ "url": "/page/2",
+ "name": "Second Global Page"
+ },
+ {
+ "url": "/page/3",
+ "name": "Third Global Page"
+ }
+ ],
+ "qualifiers": [
+ "TRK",
+ "VW",
+ "DEV"
+ ]
+}