diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-10-29 15:11:39 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-10-29 15:11:39 +0000 |
commit | 4e8a23e0d25305990324c1ddf31f2bdd097c95da (patch) | |
tree | f5596e6069f407dba32e5903f690efce88b14804 /sonar-server | |
parent | 9ed3191362c27c60a6f41fd2a4756cc92942be6d (diff) | |
download | sonarqube-4e8a23e0d25305990324c1ddf31f2bdd097c95da.tar.gz sonarqube-4e8a23e0d25305990324c1ddf31f2bdd097c95da.zip |
SONAR-1643 add widget properties
Diffstat (limited to 'sonar-server')
11 files changed, 173 insertions, 138 deletions
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb index 3fc136ecbc3..3811e1c6b83 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb @@ -21,7 +21,7 @@ class DashboardController < ApplicationController SECTION=Navigation::SECTION_RESOURCE - verify :method => :post, :only => [:set_layout, :add_widget, :set_dashboard], :redirect_to => {:action => :index} + verify :method => :post, :only => [:set_layout, :add_widget, :set_dashboard, :save_widget], :redirect_to => {:action => :index} before_filter :login_required, :except => [:index] def index @@ -71,7 +71,7 @@ class DashboardController < ApplicationController widget=@dashboard.widgets.to_a.find { |i| i.id==id.to_i() } if widget widget.column_index=index+1 - widget.order_index=order+1 + widget.row_index=order+1 widget.save! all_ids<<widget.id end @@ -92,14 +92,49 @@ class DashboardController < ApplicationController new_widget=dashboard.widgets.create(:widget_key => definition.getId(), :name => definition.getTitle(), :column_index => dashboard.number_of_columns, - :order_index => dashboard.column_size(dashboard.number_of_columns) + 1, - :state => Widget::STATE_ACTIVE) + :row_index => dashboard.column_size(dashboard.number_of_columns) + 1, + :configured => !definition.isEditable()) widget_id=new_widget.id end end redirect_to :action => 'configure', :id => dashboard.id, :resource => params[:resource], :highlight => widget_id end + + def save_widget + widget=Widget.find(params[:id].to_i) + #TODO check owner of dashboard + definition=java_facade.getWidget(widget.widget_key) + errors_by_property_key={} + definition.getProperties().each do |property_def| + value=params[property_def.key()] || property_def.defaultValue() + value='false' if value.empty? && property_def.type()==WidgetProperty::TYPE_BOOLEAN + + errors=WidgetProperty.validate_definition(property_def, value) + if errors.empty? + widget.set_property(property_def.key(), value) + else + widget.unset_property(property_def.key()) + errors_by_property_key[property_def.key()]=errors + end + end + + if errors_by_property_key.empty? + widget.configured=true + widget.save + widget.properties.each {|p| p.save} + render :update do |page| + page.redirect_to(url_for(:action => :configure, :id => widget.dashboard_id, :resource => params[:resource])) + end + else + widget.configured=false + widget.save + render :update do |page| + page.alert('errors ' + errors_by_property_key.inspect) + end + end + end + private def load_dashboard @@ -156,4 +191,5 @@ class DashboardController < ApplicationController def load_widget_definitions() @widget_definitions = java_facade.getWidgets() end + end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/dashboard_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/dashboard_helper.rb index cfbdb64e9c6..be8ccad5ad4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/dashboard_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/dashboard_helper.rb @@ -30,7 +30,7 @@ module DashboardHelper def active_widgets_ids_formatted(column) active_widget_ids=[] - @dashboard.widgets.find(:all, :conditions => {:column_index => column}, :order => :order_index).each do |widget| + @dashboard.widgets.find(:all, :conditions => {:column_index => column}, :order => 'row_index ASC').each do |widget| widget_view=nil found_index=-1 @widgets.each_with_index {|item, index| diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb index 543a2864f63..9b353e4f638 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb @@ -18,55 +18,42 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
module WidgetPropertiesHelper
- VALUE_TYPE_INT = 'INT'
- VALUE_TYPE_BOOLEAN = 'BOOL'
- VALUE_TYPE_FLOAT = 'FLOAT'
- VALUE_TYPE_STRING = 'STRING'
- VALUE_TYPE_REGEXP = 'REGEXP'
+
def valid_property_value?(type, value, parameter="")
- if type==VALUE_TYPE_INT
+ if type==WidgetProperty::TYPE_INTEGER
value.to_i.to_s == value
- elsif type==VALUE_TYPE_FLOAT
+ elsif type==WidgetProperty::TYPE_FLOAT
true if Float(value) rescue false
- elsif type==VALUE_TYPE_BOOLEAN
+ elsif type==WidgetProperty::TYPE_BOOLEAN
value=="1" || value=="0"
- elsif type==VALUE_TYPE_STRING
+ elsif type==WidgetProperty::TYPE_STRING
true
- elsif type==VALUE_TYPE_REGEXP
- value.to_s.match(parameter) == nil ? false : true
-
else
false
end
end
- def property_value_field(type, fieldname, value, param_value="")
- val= param_value ? param_value : value
-
- if type==VALUE_TYPE_INT
- text_field_tag fieldname, val , :size => 10
+ def property_value_field(definition, value)
+ val=value || definition.defaultValue()
+ if definition.type()==WidgetProperty::TYPE_INTEGER
+ text_field_tag definition.key(), val, :size => 10
- elsif type==VALUE_TYPE_FLOAT
- text_field_tag fieldname, val, :size => 10
+ elsif definition.type()==WidgetProperty::TYPE_FLOAT
+ text_field_tag definition.key(), val, :size => 10
- elsif type==VALUE_TYPE_BOOLEAN
- opts="<option value=''>Select value</option>"
- opts+="<option value='1'"+(val=="1" ? " selected" : "" )+">Yes</option>"
- opts+="<option value='0'"+(val=="0" ? " selected" : "" )+">No</option>"
- select_tag fieldname, opts
+ elsif definition.type()==WidgetProperty::TYPE_BOOLEAN
+ check_box_tag definition.key(), "true", val=='true'
- elsif type==VALUE_TYPE_STRING
- text_field_tag fieldname, val, :size => 10
+ elsif definition.type()==WidgetProperty::TYPE_STRING
+ text_field_tag definition.key(), val, :size => 10
- elsif type==VALUE_TYPE_REGEXP
- text_field_tag fieldname, val, :size => 10
else
- hidden_field_tag fieldname
+ hidden_field_tag definition.key()
end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb index 11416159f18..8751e4a7c4c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/dashboard.rb @@ -20,7 +20,7 @@ class Dashboard < ActiveRecord::Base
belongs_to :user
- has_many :widgets, :include => 'widget_properties', :dependent => :delete_all
+ has_many :widgets, :include => 'properties', :dependent => :delete_all
has_many :active_dashboards, :dependent => :delete_all
validates_length_of :name, :within => 1..256
@@ -49,8 +49,8 @@ class Dashboard < ActiveRecord::Base end
def column_size(column_index)
- last_widget=widgets.select{|w| w.column_index==column_index}.max{|x,y| x.order_index <=> y.order_index}
- last_widget ? last_widget.order_index : 0
+ last_widget=widgets.select{|w| w.column_index==column_index}.max{|x,y| x.row_index <=> y.row_index}
+ last_widget ? last_widget.row_index : 0
end
def deep_copy()
@@ -59,9 +59,9 @@ class Dashboard < ActiveRecord::Base self.widgets.each do |child|
new_widget = Widget.create(child.attributes)
- child.widget_properties.each do |prop|
+ child.properties.each do |prop|
widget_prop = WidgetProperty.create(prop.attributes)
- new_widget.widget_properties << widget_prop
+ new_widget.properties << widget_prop
end
new_widget.save
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/widget.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/widget.rb index 62e04d842cc..7cba190ed7f 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/widget.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/widget.rb @@ -18,10 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
class Widget < ActiveRecord::Base
- STATE_ACTIVE='A'
- STATE_INACTIVE='I'
-
- has_many :widget_properties, :dependent => :delete_all
+ has_many :properties, :dependent => :delete_all, :class_name => 'WidgetProperty'
belongs_to :dashboards
validates_presence_of :name
@@ -30,57 +27,52 @@ class Widget < ActiveRecord::Base validates_presence_of :widget_key
validates_length_of :widget_key, :within => 1..256
- validates_length_of :description, :maximum => 1000, :allow_blank => true, :allow_nil => true
-
- def state
- read_attribute(:state) || 'V'
- end
-
#---------------------------------------------------------------------
# WIDGET PROPERTIES
#---------------------------------------------------------------------
- def properties
- widget_properties
- end
-
- def widget_property(key)
- widget_properties().each do |p|
+ def property(key)
+ properties().each do |p|
return p if (p.key==key)
end
nil
end
- def widget_property_value(key)
- prop=widget_property(key)
- prop ? prop.value : nil
+ def property_value(key, default_value=nil)
+ prop=property(key)
+ (prop ? prop.value : nil) || default_value
end
- def set_widget_property(options)
- key=options[:kee]
- prop=widget_property(key)
+ def set_property(key, value)
+ prop=property(key)
if prop
- prop.attributes=options
- prop.widget_id=id
- prop.save!
+ prop.text_value=value
else
- prop=WidgetProperty.new(options)
- prop.widget_id=id
- widget_properties<<prop
+ self.properties.build(:kee => key, :text_value => value)
end
+ properties_as_hash[key]=value
end
- def delete_widget_property(key)
- prop=widget_property(key)
+ def unset_property(key)
+ prop=property(key)
+ self.properties.delete(prop) if prop
+ end
+
+ def delete_property(key)
+ prop=property(key)
if prop
- widget_properties.delete(prop)
+ properties.delete(prop)
end
end
def properties_as_hash
- hash={}
- widget_properties.each do |prop|
- hash[prop.key]=prop.value
- end
- hash
+ @properties_hash ||=
+ begin
+ hash={}
+ properties.each do |prop|
+ hash[prop.key]=prop.value
+ end
+ hash
+ end
+ @properties_hash
end
end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb index be6b9522aa5..3909618cde1 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb @@ -18,20 +18,22 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#
class WidgetProperty < ActiveRecord::Base
+ TYPE_INTEGER = 'INTEGER'
+ TYPE_BOOLEAN = 'BOOLEAN'
+ TYPE_FLOAT = 'FLOAT'
+ TYPE_STRING = 'STRING'
- belongs_to :widgets
+ belongs_to :widget
- validates_presence_of :kee
validates_length_of :kee, :within => 1..100
- validates_length_of :description, :maximum => 4000, :allow_blank => true, :allow_nil => true
validates_length_of :text_value, :maximum => 4000, :allow_blank => true, :allow_nil => true
def key
- kee
- end
+ kee
+ end
def value
- text_value
+ text_value
end
def to_hash_json
@@ -45,5 +47,22 @@ class WidgetProperty < ActiveRecord::Base end
xml
end
-
+
+ def self.validate_definition(definition, value)
+ errors=[]
+ if value.empty?
+ errors<<"Missing value" unless definition.optional()
+ else
+ errors<<"Please type an integer (example: 123)" if definition.type()==TYPE_INTEGER && value.to_i.to_s!=value
+ if definition.type()==TYPE_FLOAT
+ begin
+ Float(value)
+ rescue
+ errors<<"Please type a number (example: 123.45)"
+ end
+ end
+ errors<<"Please check value" if definition.type()==TYPE_BOOLEAN && !(value=="true" || value=="false")
+ end
+ errors
+ end
end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb index 4712106bb1a..ec677b689a8 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb @@ -15,47 +15,43 @@ <a class="block-view-toggle" onclick="portal.editWidget(<%= widget.id -%>);return false;">Edit</a> <% end %> </div> -<% if defined?(validation_result) %> - <div class="error" style="<%= "display: none;" unless validation_result["errormsg"] %>clear:both;margin: 0;border-bottom:0;"> - <span class="errormsg"><%= validation_result["errormsg"] if validation_result["errormsg"] %></span> [<a href="#" onclick="hide_block_info($(this).up('.block'));return false;">hide</a>] - </div> - <div class="notice" style="<%= "display: none;" unless validation_result["infomsg"] %>clear:both;margin: 0;border-bottom:0;"> - <span class="infomsg"><%= validation_result["infomsg"] if validation_result["infomsg"] %></span> [<a href="#" onclick="hide_block_info($(this).up('.block'));return false;">hide</a>] - </div> -<% end %> -<div class="widget_props" id="widget_props_<%= widget.id -%>" style="display: none"> - <% form_remote_tag :url => {:action => 'save_widget', :id => @dashboard.id}, :method => :post do -%> - <table class="form" align="center" style="border-collapse:separate;border-spacing:5px;"> +<div class="widget_props" id="widget_props_<%= widget.id -%>" style="<%= 'display:none' if widget.configured -%>"> + <% form_remote_tag :url => {:action => 'save_widget', :id => widget.id, :resource => params[:resource]}, :method => :post do -%> + <table class="form"> <tbody> - <% definition.getProperties().each do |property| - db_property_value=widget.widget_property_value(property.key()) - entered_value=params[property.key()] - entered_value=property.defaultValue() if !entered_value || entered_value.empty? + <% definition.getProperties().each do |property_def| + value=widget.property_value(property_def.key(), property_def.defaultValue()) editrow_class="" if defined?(validation_result) - editrow_class= validation_result[property.key()]=="valid" ? "valid-editrow" : "invalid-editrow" + editrow_class= validation_result[property_def.key()]=="valid" ? "valid-editrow" : "invalid-editrow" end %> <tr> - <td class="first"><%= property.name() -%>:<br> - <span style="font-size: 85%;font-weight: normal;">[<%= property.type()+" "+property.key() -%>]</span></td> - <td id="row_<%= property.key() -%>" class="editrow <%= editrow_class %>" style="vertical-align: middle;"><%= property_value_field(property.type(), property.key(), db_property_value, entered_value) %><%= " *" unless property.optional() %> - <br> - <span style="font-size: 85%;font-weight: normal;">[<%= property.description() -%>]</span></td> + <td valign="top" nowrap><b><%= property_def.key() -%></b><%= "*" unless property_def.optional()==true -%>: </td> + <td id="row_<%= property_def.key() -%>"> + <%= property_value_field(property_def, value) -%> + <span class="note"><%= property_def.description() -%></span> + </td> </tr> <% end %> + <tr> + <td colspan="2"> + <%= submit_tag 'Save' %> + <% if widget.configured %> + <a href="#" onClick="portal.cancelEditWidget(<%= widget.id -%>);return false;">Cancel</a> + <% end %> + </td> + </tr> </tbody> </table> <%= hidden_field_tag "widgetid", "", :class => "widgetid" %> - <div align="center"><%= submit_tag 'Save' %> <a href="#" onClick="portal.cancelEditWidget(<%= widget.id -%>);return false;">Cancel</a></div> - <% end -%> </div> -<div id="widget_<%= widget.id -%>" class="configure_widget <%= definition.getId() -%>" style="height:100%;"> +<div id="widget_<%= widget.id -%>" class="configure_widget <%= definition.getId() -%>" style="height:100%;<%= 'display:none;' if !widget.configured -%>"> <!--[if lte IE 6]> <style type="text/css"> #dashboard .block .content .transparent { diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb index e3b9aeaf071..8ec81757294 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb @@ -1,18 +1,24 @@ <div class="<%= definition.getId() %>" style="height:100%;"> -<% - begin - widget_body=render :inline => definition.getTarget().getTemplate(), :locals => {:widget_properties => widget.properties_as_hash} - rescue => error - logger.error("Can not render widget #{definition.getId()}: " + error) - logger.error(error.backtrace.join("\n")) - widget_body="" - end +<% if widget.configured %> + <% + begin + widget_body=render :inline => definition.getTarget().getTemplate(), :locals => {:widget_properties => widget.properties_as_hash} + rescue => error + logger.error("Can not render widget #{definition.getId()}: " + error) + logger.error(error.backtrace.join("\n")) + widget_body="" + end - if widget_body.include?('<') -%> - <%= widget_body %> -<% - end -%> + if widget_body.include?('<') + %> + <%= widget_body %> + <% + end + %> +<% else %> + <div class="widget"> + <p>Please configure the widget <b><%= definition.getTitle() -%></b>.</p> + </div> +<% end %> <div style="clear: both;"></div> </div>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb index 8ff64d6fb48..7c0f54e612a 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/configure.html.erb @@ -11,7 +11,7 @@ dashboardstate: 'dashboardstate', toggle: 'block-toggle', blocklist: 'widget_defs', - highlight_duration: 3, + highlight_duration: 2, highlight_startcolor: '#cae3f2', highlight_endcolor: '#ffffff', saveurl: '<%= url_for :action => 'set_dashboard', :id => @dashboard.id, :resource => @resource.id -%>' @@ -52,7 +52,7 @@ <div class="column-handle" style="display: none"> </div> <% - @dashboard.widgets.select{|widget| widget.column_index==index}.sort_by{|widget| widget.order_index}.each do |widget| + @dashboard.widgets.select{|widget| widget.column_index==index}.sort_by{|widget| widget.row_index}.each do |widget| widget_definition=@widget_definitions.find{|wd| wd.getId()==widget.widget_key } if widget_definition %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb index e7a6d569daa..8902604dea9 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/index.html.erb @@ -8,7 +8,7 @@ <div class="dashboard-column-wrapper" style="width: <%= (columns.size()>0) ? columns[index-1].to_i : 100 %>%; clear: right;"> <div class="dashboard-column" id="dashboard-column-<%= index -%>" style="margin: 0px <%= index<columns.size() ? "5px" : "0px" %> 0px <%= index>1 ? "5px" : "0px" %>;"> <% - @dashboard.widgets.select{|widget| widget.column_index==index}.sort_by{|widget| widget.order_index}.each do |widget| + @dashboard.widgets.select{|widget| widget.column_index==index}.sort_by{|widget| widget.row_index}.each do |widget| widget_definition=@widget_definitions.find{|wd| wd.getId()==widget.widget_key } if widget_definition %> diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb index 180e9c53db2..6130b0814a6 100755 --- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/151_create_dashboards.rb @@ -44,8 +44,8 @@ class CreateDashboards < ActiveRecord::Migration t.column :name, :string, :null => true, :limit => 256 t.column :description, :string, :null => true, :limit => 1000 t.column :column_index, :integer, :null => true - t.column :order_index, :integer, :null => true - t.column :state, :string, :null => true, :limit => 1 + t.column :row_index, :integer, :null => true + t.column :configured, :boolean, :null => true t.timestamps end add_index :widgets, [:dashboard_id], :name => 'widgets_dashboards' @@ -53,7 +53,6 @@ class CreateDashboards < ActiveRecord::Migration create_table :widget_properties do |t| t.column :widget_id, :integer, :null => false - t.column :description, :string, :null => true, :limit => 4000 t.column :kee, :string, :null => true, :limit => 100 t.column :text_value, :string, :null => true, :limit => 4000 end @@ -66,18 +65,18 @@ class CreateDashboards < ActiveRecord::Migration def self.create_dashboard dashboard=::Dashboard.new(:name => 'Dashboard', :shared => true, :description => 'Default dashboard', :column_layout => "50-50") - dashboard.widgets.build(:widget_key => 'static_analysis', :name => 'Static analysis', :column_index => 1, :order_index => 1, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'comments_duplications', :name => 'Comments duplications', :column_index => 1, :order_index => 2, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'extended_analysis', :name => 'Extended analysis', :column_index => 1, :order_index => 3, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'code_coverage', :name => 'Code coverage', :column_index => 1, :order_index => 4, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'events', :name => 'Events', :column_index => 1, :order_index => 5, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'description', :name => 'Description', :column_index => 1, :order_index => 6, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'rules', :name => 'Rules', :column_index => 2, :order_index => 1, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'alerts', :name => 'Alerts', :column_index => 2, :order_index => 2, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'custom_measures', :name => 'Custom measures', :column_index => 2, :order_index => 3, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'file-design', :name => 'File design', :column_index => 2, :order_index => 4, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'package-design', :name => 'Package design', :column_index => 2, :order_index => 5, :state => Widget::STATE_ACTIVE) - dashboard.widgets.build(:widget_key => 'ckjm', :name => 'CKJM', :column_index => 2, :order_index => 6, :state => Widget::STATE_ACTIVE) + dashboard.widgets.build(:widget_key => 'static_analysis', :name => 'Static analysis', :column_index => 1, :row_index => 1, :configured => true) + dashboard.widgets.build(:widget_key => 'comments_duplications', :name => 'Comments duplications', :column_index => 1, :row_index => 2, :configured => true) + dashboard.widgets.build(:widget_key => 'extended_analysis', :name => 'Extended analysis', :column_index => 1, :row_index => 3, :configured => true) + dashboard.widgets.build(:widget_key => 'code_coverage', :name => 'Code coverage', :column_index => 1, :row_index => 4, :configured => true) + dashboard.widgets.build(:widget_key => 'events', :name => 'Events', :column_index => 1, :row_index => 5, :configured => true) + dashboard.widgets.build(:widget_key => 'description', :name => 'Description', :column_index => 1, :row_index => 6, :configured => true) + dashboard.widgets.build(:widget_key => 'rules', :name => 'Rules', :column_index => 2, :row_index => 1, :configured => true) + dashboard.widgets.build(:widget_key => 'alerts', :name => 'Alerts', :column_index => 2, :row_index => 2, :configured => true) + dashboard.widgets.build(:widget_key => 'custom_measures', :name => 'Custom measures', :column_index => 2, :row_index => 3, :configured => true) + dashboard.widgets.build(:widget_key => 'file-design', :name => 'File design', :column_index => 2, :row_index => 4, :configured => true) + dashboard.widgets.build(:widget_key => 'package-design', :name => 'Package design', :column_index => 2, :row_index => 5, :configured => true) + dashboard.widgets.build(:widget_key => 'ckjm', :name => 'CKJM', :column_index => 2, :row_index => 6, :configured => true) dashboard.save dashboard |