From 03dea21c4a826526aefb3a4287f3380a215f0956 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 23 Sep 2014 16:33:01 +0600 Subject: [PATCH] SONAR-5646 Initial dashborad js app --- server/sonar-web/Gruntfile.coffee | 3 + .../sonar-web/src/main/es6/dashboard/app.js | 58 +++++ .../main/es6/dashboard/collections/widgets.js | 12 + .../src/main/es6/dashboard/mockjax.js | 58 +++++ .../src/main/es6/dashboard/models/widget.js | 7 + .../main/es6/dashboard/views/widget-view.js | 45 ++++ .../main/es6/dashboard/views/widgets-view.js | 31 +++ .../src/main/hbs/dashboard/widget.hbs | 9 + .../src/main/hbs/dashboard/widgets.hbs | 19 ++ .../app/controllers/dashboard2_controller.rb | 227 ++++++++++++++++++ .../dashboard2/_configure_widget.html.erb | 55 +++++ .../app/views/dashboard2/_header.html.erb | 34 +++ .../app/views/dashboard2/_widget.html.erb | 48 ++++ .../dashboard2/_widget_definition.html.erb | 10 + .../dashboard2/_widget_definitions.html.erb | 27 +++ .../dashboard2/_widget_properties.html.erb | 67 ++++++ .../views/dashboard2/_widget_title.html.erb | 3 + .../app/views/dashboard2/configure.html.erb | 105 ++++++++ .../app/views/dashboard2/empty.html.erb | 3 + .../app/views/dashboard2/index.html.erb | 12 + .../views/dashboard2/no_dashboard.html.erb | 12 + 21 files changed, 845 insertions(+) create mode 100644 server/sonar-web/src/main/es6/dashboard/app.js create mode 100644 server/sonar-web/src/main/es6/dashboard/collections/widgets.js create mode 100644 server/sonar-web/src/main/es6/dashboard/mockjax.js create mode 100644 server/sonar-web/src/main/es6/dashboard/models/widget.js create mode 100644 server/sonar-web/src/main/es6/dashboard/views/widget-view.js create mode 100644 server/sonar-web/src/main/es6/dashboard/views/widgets-view.js create mode 100644 server/sonar-web/src/main/hbs/dashboard/widget.hbs create mode 100644 server/sonar-web/src/main/hbs/dashboard/widgets.hbs create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard2_controller.rb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_configure_widget.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_header.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definition.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definitions.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_properties.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_title.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/configure.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/empty.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/index.html.erb create mode 100644 server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/no_dashboard.html.erb diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee index 0c3624005f8..6f2c24bf29d 100644 --- a/server/sonar-web/Gruntfile.coffee +++ b/server/sonar-web/Gruntfile.coffee @@ -264,6 +264,9 @@ module.exports = (grunt) -> '<%= pkg.assets %>js/templates/libraries.js': [ '<%= pkg.sources %>hbs/libraries/**/*.hbs' ] + '<%= pkg.assets %>js/templates/dashboard.js': [ + '<%= pkg.sources %>hbs/dashboard/**/*.hbs' + ] clean: diff --git a/server/sonar-web/src/main/es6/dashboard/app.js b/server/sonar-web/src/main/es6/dashboard/app.js new file mode 100644 index 00000000000..7239062ac5a --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/app.js @@ -0,0 +1,58 @@ +requirejs.config({ + baseUrl: `${baseUrl}/js`, + + paths: { + 'backbone': 'third-party/backbone', + 'backbone.marionette': 'third-party/backbone.marionette', + 'handlebars': 'third-party/handlebars' + }, + + shim: { + 'backbone.marionette': { + deps: ['backbone'], + exports: 'Marionette' + }, + 'backbone': { + exports: 'Backbone' + }, + 'handlebars': { + exports: 'Handlebars' + } + } +}); + + +requirejs([ + 'backbone', + 'backbone.marionette', + 'dashboard/collections/widgets', + 'dashboard/views/widgets-view', + 'dashboard/mockjax', + 'common/handlebars-extensions' +], function (Backbone, Marionette, Widgets, WidgetsView) { + + var App = new Marionette.Application(), + $ = jQuery; + + App.addInitializer(function () { + this.widgetsView = new WidgetsView({ + collection: this.widgets, + dashboard: this.dashboard, + el: $('#dashboard') + }); + this.widgetsView.render(); + }); + + var requestDetails = function () { + return $.get(`${baseUrl}/api/dashboards/details`, { did: window.did }, function (data) { + console.log(JSON.stringify(data)); + App.dashboard = new Backbone.Model(_.omit(data, 'widgets')); + App.widgets = new Widgets(data.widgets); + }); + }; + + $.when(requestDetails(), window.requestMessages()).done(function () { + App.start(); + }); + +}); diff --git a/server/sonar-web/src/main/es6/dashboard/collections/widgets.js b/server/sonar-web/src/main/es6/dashboard/collections/widgets.js new file mode 100644 index 00000000000..03826f31482 --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/collections/widgets.js @@ -0,0 +1,12 @@ +define([ + 'backbone', + 'dashboard/models/widget' +], function ( + Backbone, + Widget) { + + return Backbone.Collection.extend({ + model: Widget + }); + +}); diff --git a/server/sonar-web/src/main/es6/dashboard/mockjax.js b/server/sonar-web/src/main/es6/dashboard/mockjax.js new file mode 100644 index 00000000000..b3cce8f4d42 --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/mockjax.js @@ -0,0 +1,58 @@ +define(['third-party/jquery.mockjax'], function () { + + jQuery.mockjaxSettings.contentType = 'text/json'; + jQuery.mockjaxSettings.responseTime = 250; + + jQuery.mockjax({ + url: `${baseUrl}/api/dashboards/details`, + responseText: JSON.stringify({ + name: 'Helicopter View', + description: '', + shared: true, + layout: '50%-50%', + + canManageDashboards: true, + canManageWidgets: true, + + widgets: [ + { + key: 'measure_filter_list', + props: [ + { + key: 'filter', + value: '48' + } + ], + layout: { + column: 1, + row: 1 + } + }, + { + key: 'my_reviews', + props: [], + layout: { + column: 2, + row: 1 + } + } + ] + }) + }); + + jQuery.mockjax({ + url: `${baseUrl}/api/dashboards/available_widgets`, + responseText: JSON.stringify({ + widgets: [ + { + key: '', + name: '', + description: '', + category: '', + props: [] + } + ] + }) + }); + +}); diff --git a/server/sonar-web/src/main/es6/dashboard/models/widget.js b/server/sonar-web/src/main/es6/dashboard/models/widget.js new file mode 100644 index 00000000000..79300beaf71 --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/models/widget.js @@ -0,0 +1,7 @@ +define(['backbone'], function (Backbone) { + + return Backbone.Model.extend({ + idAttribute: 'key' + }); + +}); diff --git a/server/sonar-web/src/main/es6/dashboard/views/widget-view.js b/server/sonar-web/src/main/es6/dashboard/views/widget-view.js new file mode 100644 index 00000000000..0507d5933b4 --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/views/widget-view.js @@ -0,0 +1,45 @@ +define([ + 'backbone.marionette', + 'templates/dashboard' +], function (Marionette, Templates) { + + var $ = jQuery; + + + class WidgetView extends Marionette.ItemView { + + initialize() { + this.requestContent(); + } + + requestContent() { + var props = this.getWidgetProps(); + $.get(`${baseUrl}/widget/show?id=${this.model.id}&${props}`, (html) => { + this.model.set('html', html); + this.render(); + }); + } + + getWidgetProps() { + var props = this.model.get('props') + .map(function (prop) { + return `${prop.key}=${encodeURIComponent(prop.value)}`; + }) + .join('&'); + return props; + } + + serializeData() { + var props = this.getWidgetProps(); + return _.extend(super.serializeData(), { + url: `${baseUrl}/widget?id=${this.model.id}&${props}` + }); + } + + } + + WidgetView.prototype.template = Templates['widget'] + + return WidgetView; + +}); diff --git a/server/sonar-web/src/main/es6/dashboard/views/widgets-view.js b/server/sonar-web/src/main/es6/dashboard/views/widgets-view.js new file mode 100644 index 00000000000..ce8692d38a7 --- /dev/null +++ b/server/sonar-web/src/main/es6/dashboard/views/widgets-view.js @@ -0,0 +1,31 @@ +define([ + 'backbone.marionette', + 'templates/dashboard', + 'dashboard/views/widget-view' +], function (Marionette, Templates, WidgetView) { + + class WidgetsView extends Marionette.CompositeView { + + appendHtml(compositeView, itemView) { + var layout = itemView.model.get('layout'), + column = layout.column - 1; + var $container = this.getItemViewContainer(compositeView); + $container.eq(column).append(itemView.el); + } + + serializeData() { + return _.extend(super.serializeData(), { + dashboard: this.options.dashboard.toJSON(), + manageDashboardsUrl: `${baseUrl}/dashboards` + }); + } + + } + + WidgetsView.prototype.template = Templates['widgets']; + WidgetsView.prototype.itemView = WidgetView; + WidgetsView.prototype.itemViewContainer = '.dashboard-column'; + + return WidgetsView; + +}); diff --git a/server/sonar-web/src/main/hbs/dashboard/widget.hbs b/server/sonar-web/src/main/hbs/dashboard/widget.hbs new file mode 100644 index 00000000000..91dcae71e96 --- /dev/null +++ b/server/sonar-web/src/main/hbs/dashboard/widget.hbs @@ -0,0 +1,9 @@ +
+
+ {{#if html}} + {{{html}}} + {{else}} + + {{/if}} +
+
diff --git a/server/sonar-web/src/main/hbs/dashboard/widgets.hbs b/server/sonar-web/src/main/hbs/dashboard/widgets.hbs new file mode 100644 index 00000000000..7dd17d1b8ea --- /dev/null +++ b/server/sonar-web/src/main/hbs/dashboard/widgets.hbs @@ -0,0 +1,19 @@ +
+
+ + {{t 'dashboard.manage_dashboards'}} +
+
+ +{{#eq dashboard.layout '50%-50%'}} +
+
+ +
+
+
+
+ +
+
+{{/eq}} diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard2_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard2_controller.rb new file mode 100644 index 00000000000..73a3a5e1999 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/dashboard2_controller.rb @@ -0,0 +1,227 @@ +# +# 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. +# +class Dashboard2Controller < ApplicationController + + SECTION=Navigation::SECTION_RESOURCE + + before_filter :login_required, :except => [:index] + + def index + load_resource() + + if !@resource || @resource.display_dashboard? + load_dashboard() + load_authorized_widget_definitions() + else + # display the layout of the parent without the sidebar, usually the directory, but display the file viewers + @hide_sidebar = true + @file = @resource + @project = @snapshot.parent.project + @metric=params[:metric] + render :action => 'no_dashboard' + end + end + + def configure + load_resource() + load_dashboard() + + @category=params[:category] + load_widget_definitions(@category) + end + + def set_layout + verify_post_request + dashboard=Dashboard.find(params[:did]) + if dashboard.editable_by?(current_user) + dashboard.column_layout=params[:layout] + dashboard.save! + columns=dashboard.column_layout.split('-') + dashboard.widgets.find(:all, :conditions => ["column_index > ?", columns.size()]).each do |widget| + widget.column_index=columns.size() + widget.save + end + end + redirect_to :action => 'configure', :did => dashboard.id, :id => params[:id] + end + + def set_dashboard + verify_post_request + load_dashboard() + + dashboardstate=params[:dashboardstate] + + columns=dashboardstate.split(";") + all_ids=[] + columns.each_with_index do |col, index| + ids=col.split(",") + ids.each_with_index do |id, order| + widget=@dashboard.widgets.to_a.find { |i| i.id==id.to_i() } + if widget + widget.column_index=index+1 + widget.row_index=order+1 + widget.save! + all_ids< {:status => 'ok'} + end + + def add_widget + verify_post_request + dashboard=Dashboard.find(params[:did]) + widget_id=nil + if dashboard.editable_by?(current_user) + definition=java_facade.getWidget(params[:widget]) + if definition + first_column_widgets=dashboard.widgets.select { |w| w.column_index==1 }.sort_by { |w| w.row_index } + new_widget=dashboard.widgets.create(:widget_key => definition.getId(), + :name => definition.getTitle(), + :column_index => 1, + :row_index => 1, + :configured => !(definition.hasRequiredProperties() || (dashboard.global && !definition.isGlobal))) + widget_id=new_widget.id + first_column_widgets.each_with_index do |w, index| + w.row_index=index+2 + w.save + end + end + end + redirect_to :action => 'configure', :did => dashboard.id, :id => params[:id], :highlight => widget_id, :category => params[:category] + end + + def save_widget + verify_post_request + widget=Widget.find(params[:wid]) + #TODO check owner of dashboard + Widget.transaction do + widget.properties.clear + widget.java_definition.getWidgetProperties().each do |java_property| + value=params[java_property.key()] || java_property.defaultValue() + if value && !value.empty? + prop = widget.properties.build(:kee => java_property.key, :text_value => value) + prop.save! + end + end + widget.resource_id=Project.by_key(params[:resource_id]).id if params[:resource_id].present? + widget.configured=true + widget.save! + render :update do |page| + page.redirect_to(url_for(:action => 'configure', :did => widget.dashboard_id, :id => params[:id])) + end + end + end + + def widget_definitions + @category=params[:category] + load_resource() + load_dashboard() + load_widget_definitions(@category) + render :partial => 'widget_definitions', :locals => {:category => @category} + end + + private + + def load_dashboard + active=nil + @dashboard=nil + + if logged_in? + if params[:did] + @dashboard=Dashboard.first(:conditions => ['id=? AND user_id=?', params[:did].to_i, current_user.id]) + elsif params[:name] + @dashboard=Dashboard.first(:conditions => ['name=? AND user_id=?', params[:name], current_user.id]) + elsif params[:id] + active=ActiveDashboard.user_dashboards(current_user, false).first + else + active=ActiveDashboard.user_dashboards(current_user, true).first + end + end + + unless active or @dashboard + # anonymous or not found in user dashboards + if params[:did] + @dashboard=Dashboard.first(:conditions => ['id=? AND shared=?', params[:did].to_i, true]) + elsif params[:name] + @dashboard=Dashboard.first(:conditions => ['name=? AND shared=?', params[:name], true]) + elsif params[:id] + active=ActiveDashboard.user_dashboards(nil, false).first + else + active=ActiveDashboard.user_dashboards(nil, true).first + end + end + + unless @dashboard + @dashboard=(active && active.dashboard) + end + + not_found('dashboard') unless @dashboard + + @dashboard_configuration=Api::DashboardConfiguration.new(@dashboard, :period_index => params[:period], :snapshot => @snapshot) if @dashboard && @snapshot + end + + def load_resource + if params[:id] + @resource=Project.by_key(params[:id]) + return project_not_found unless @resource + @resource=@resource.permanent_resource + + @snapshot=@resource.last_snapshot + return project_not_analyzed unless @snapshot + + access_denied unless has_role?(:user, @resource) + + @project=@resource # for backward compatibility with old widgets + end + end + + def project_not_found + flash[:error] = message('dashboard.project_not_found') + redirect_to :action => :index + end + + def project_not_analyzed + render :action => 'empty' + end + + def load_authorized_widget_definitions + @authorized_widget_definitions=java_facade.getWidgets().select do |widget| + roles = widget.getUserRoles() + roles.empty? || roles.any? { |role| (role=='user') || (role=='viewer') || has_role?(role, @resource) } + end + end + + def load_widget_definitions(filter_on_category) + @widget_definitions=java_facade.getWidgets().to_a.sort {|w1,w2| widgetL10nName(w1) <=> widgetL10nName(w2)} + + @widget_categories=@widget_definitions.map(&:getWidgetCategories).to_a.flatten.uniq.sort + unless filter_on_category.blank? + @widget_definitions=@widget_definitions.select { |definition| definition.getWidgetCategories().to_a.include?(filter_on_category) } + end + end + + def widgetL10nName(widget) + Api::Utils.message('widget.' + widget.id + '.name') + end +end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_configure_widget.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_configure_widget.html.erb new file mode 100644 index 00000000000..e2ceea91e73 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_configure_widget.html.erb @@ -0,0 +1,55 @@ +<% + switch_to_widget_resource(widget) + widget_body=widget_body(widget) + default_layout=(widget.layout=='DEFAULT') +%> + +
+
+ <% if widget.java_definition.isEditable() || (!widget.java_definition.global && @dashboard.global) %> + <%= message('edit') -%> + <% end %> + <%= message('delete') -%> +
+
+ <%= h message('widget.' + widget.java_definition.getId() + '.name', :default => widget.java_definition.getTitle()) -%> +
+
+ +
+ <%= render :partial => 'widget_properties', :locals => {:widget => widget} -%> +
+ +<%= render :partial => 'widget_title', :locals => {:widget => widget} -%> +
+
+ <% if !widget_body %> +
+ <% if default_layout %> +
+ <%= message('widget.error_occurred_please_read_logs', :params => [widget.key]) -%> +
+
+ <% else %> + <%= message('widget.error_occurred_please_read_logs', :params => [widget.key]) -%> + <% end %> +
+ <% elsif widget_body.include? '<' %> + <% + + if default_layout + %> +
+ <% end %> + <%= widget_body -%> + <% if default_layout %> +
+
+ <% end %> + <% else %> +

<%= message('no_data') -%>

+ <% end %> +
+
+ +<% restore_global_resource %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_header.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_header.html.erb new file mode 100644 index 00000000000..900075c19f0 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_header.html.erb @@ -0,0 +1,34 @@ +<% if logged_in? || @snapshot %> +
+ + <% if logged_in? %> +
+ <% if back %> + <%= link_to message('dashboard.back_to_dashboard'), dashboard_action(:index), :class => 'button' -%> + <% else %> + <% if @dashboard.editable_by?(current_user) %> + <%= link_to message('dashboard.configure_widgets'), dashboard_action(:configure), :class => 'button' -%> + <% end %> + <% end %> + <%= link_to message('dashboard.manage_dashboards'), {:controller => :dashboards, :action => :index, :resource => (@resource.id if @resource) }, :class => 'button' -%> +
+ <% end %> + + <% if @snapshot %> +
+

+ <%= "Version #{@snapshot.version} - " if @snapshot.version.present? -%><%= l @snapshot.created_at -%> + <% if @snapshot.project_snapshot.periods? %> + <% period_options = period_select_option_tags(@snapshot, 'small') %> + <% if period_options %> +
+ + <%= dropdown_tag 'period', period_options, {:width => '250px'}, {:id => 'select-comparison', :onchange => 'submit()'} -%> +
+ <% end %> + <% end %> +

+
+ <% end %> +
+<% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget.html.erb new file mode 100644 index 00000000000..b706fd19076 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget.html.erb @@ -0,0 +1,48 @@ +<% + switch_to_widget_resource(widget) + widget_body=widget_body(widget) + default_layout=(widget.java_definition.getWidgetLayout().name()=='DEFAULT') +%> + +<% if !widget.configured %> + + +<% elsif !widget_body %> +
+ <% if default_layout %> +
+ <%= message('widget.error_occurred_please_read_logs', :params => [widget.key]) -%> +
+
+ <% else %> + <%= message('widget.error_occurred_please_read_logs', :params => [widget.key]) -%> + <% end %> +
+ +<% elsif widget_body.include?('<') %> +
+ <%= render :partial => 'widget_title', :locals => {:widget => widget} -%> + +
+ <% if default_layout %> +
+ <%= widget_body -%> +
+
+ <% else %> + <%= widget_body -%> + <% end %> + +
+
+
+<% end %> + +<% restore_global_resource %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definition.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definition.html.erb new file mode 100644 index 00000000000..c0ab98601ff --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definition.html.erb @@ -0,0 +1,10 @@ +
+

<%= h message("widget.#{definition.id}.name", :default => definition.title) -%>

+ +

<%= h message("widget.#{definition.id}.description", :default => definition.description) -%>

+ + <% form_tag dashboard_action(:add_widget, :widget => definition.id) do -%> + + + <% end -%> +
\ No newline at end of file diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definitions.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definitions.html.erb new file mode 100644 index 00000000000..64ed279cc23 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_definitions.html.erb @@ -0,0 +1,27 @@ + + + + + +
+ + <%= image_tag 'loading.gif', :style => 'vertical-align: top; display: none', :id => 'filter-widgets-loading' -%> + + Search: + +
+ +<% @widget_definitions.each do |definition| %> + <%= render :partial => 'widget_definition', :locals => {:definition => definition, :dashboard => @dashboard, :resource => @resource, :category => category} %> +<% end %> + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_properties.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_properties.html.erb new file mode 100644 index 00000000000..ae419530933 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_properties.html.erb @@ -0,0 +1,67 @@ +
+ + + + + <% if !widget.java_definition.global && @dashboard.global %> + + + + + <% end %> + + <% widget.java_definition.getWidgetProperties().each do |property_def| %> + + + + + <% end %> + + + + + +
<%= message('widget.resource_id') %> * + <%= resource_select_tag 'resource_id', { + :resource_type_property => 'supportsGlobalDashboards', + :selected_resource => widget.resource, + :width => '250px', + :html_id => "widget-#{widget.id}-select-prj-#{widget.key.parameterize}", + :html_class => "widget-select-prj-#{widget.key.parameterize}" + } -%> +
<%= message("widget." + widget.key + ".property." + property_def.key() + ".name", :default => property_def.key()) -%><%= " *" unless property_def.optional() -%> + <%= property_value_field(property_def, widget.property_text_value(property_def.key()), widget) -%> +
+ <% + # Old key used for retro-compatibility + property_description = message("widget." + widget.key + ".param." + property_def.key(), :default => '') + property_description = message("widget." + widget.key + ".property." + property_def.key() + ".desc", :default => property_def.description()) unless property_description != '' + -%> + + <% unless property_description.blank? -%> +
<%= property_description -%>
+ <% end %> + <% if !property_def.defaultValue.blank? || property_def.type.name == PropertyType::TYPE_BOOLEAN -%> +
<%= message('default') %>: <%= h(default_value property_def) -%>
+ <% end -%> +
+
+ <%= submit_tag message('save'), :id => "widget-#{widget.id}-save-#{widget.key.parameterize}", :class => "widget-save-#{widget.key.parameterize}" -%> + <% if widget.configured %> + <%= message('cancel') -%> + <% end %> +
+ <%= hidden_field_tag "widgetid", "", :class => "widgetid" %> +
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_title.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_title.html.erb new file mode 100644 index 00000000000..0c9fb7ae468 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/_widget_title.html.erb @@ -0,0 +1,3 @@ +<% unless widget_title(widget).blank? %> +
<%= widget_title(widget) -%>
+<% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/configure.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/configure.html.erb new file mode 100644 index 00000000000..30c43cc9aa0 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/configure.html.erb @@ -0,0 +1,105 @@ +
+ <%= render :partial => 'header', :locals => {:back => true} %> + +
+
+ <%= render :partial => 'widget_definitions', :locals => {:category => @category} -%> +
+ +
+ <% {'100%', 'layout100.png', + '50%-50%', 'layout5050.png', + '30%-70%', 'layout3070.png', + '70%-30%', 'layout7030.png', + '33%-33%-33%', 'layout333333.png' + }.each_pair do |layout, picto| %> +
+ <%= link_to image_tag(picto), dashboard_action(:set_layout, :layout => layout), :method => :post, :title => layout %> +
+ <% end %> +
+
+ + <% + columns=@dashboard.column_layout.split('-') + for index in 1..columns.size() + %> +
+
0 <%= index>1 ? "5px" : "0px" -%>;"> + <% + @dashboard.widgets.select { |widget| widget.column_index==index && widget.java_definition }.sort_by { |widget| widget.row_index }.each do |widget| + %> +
+ <%= render :partial => 'configure_widget', :locals => {:widget => widget} %> +
+ <% + end + %> + +
+
+ <% end %> +
+ + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/empty.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/empty.html.erb new file mode 100644 index 00000000000..a297b76e3f3 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/empty.html.erb @@ -0,0 +1,3 @@ +<% if @resource and !@snapshot %> +

<%= message('provisioning.no_analysis') -%>

+<% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/index.html.erb new file mode 100644 index 00000000000..8dd759d6cf1 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/index.html.erb @@ -0,0 +1,12 @@ +<% content_for :script do %> + +<% end %> + +
+ +
+ + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/no_dashboard.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/no_dashboard.html.erb new file mode 100644 index 00000000000..8802eb19301 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/dashboard2/no_dashboard.html.erb @@ -0,0 +1,12 @@ +<% content_for :script do %> + +<% end %> + +
+
+ + -- 2.39.5