else
@filter = MeasureFilter.new
end
- @filter.set_criteria_from_url_params(params)
+ @filter.criteria=(params)
+ @filter.enable_default_display
@filter.execute(self, :user => current_user)
end
@filter = find_filter(params[:id])
@filter.load_criteria_from_data
+ @filter.enable_default_display
@filter.execute(self, :user => current_user)
render :action => 'search'
end
else
@filter = MeasureFilter.new
end
- @filter.set_criteria_from_url_params(params)
+ @filter.criteria=(params)
@filter.convert_criteria_to_data
render :partial => 'measures/save_form'
end
else
html=h(column.name)
end
- #if column.variation
- # html="<img src='#{ApplicationController.root_context}/images/trend-up.png'></img> #{html}"
- #end
-
if filter.sort_key==column.key
html << (filter.sort_asc? ? image_tag("asc12.png") : image_tag("desc12.png"))
end
snapshot.resource
end
+ # For internal use
def add_measure(measure)
@measures_by_metric[measure.metric] = measure
end
+ # For internal use
def add_link(link)
@links ||= []
@links << link
end
end
- # Column to be displayed
- class Column
- attr_reader :key, :metric
-
- def initialize(key)
- @key = key
- metric_key = @key.split(':')[1]
- @metric = Metric.by_key(metric_key) if metric_key
- end
-
- def name
- if @metric
- Api::Utils.message("metric.#{@metric.key}.name", :default => @metric.short_name)
- else
- Api::Utils.message("measure_filter.col.#{@key}", :default => @key)
- end
- end
-
- def align
- @align ||=
- begin
- # by default is table cells are left-aligned
- (@key=='name' || @key=='short_name' || @key=='description') ? '' : 'right'
- end
- end
-
- def sort?
- !links?
- end
-
- def links?
- @key == 'links'
- end
- end
-
- class Display
- attr_reader :metric_ids
-
- def initialize(filter)
- end
-
- def load_links?
- false
- end
- end
-
- class ListDisplay < Display
- attr_reader :columns
-
- KEY = :list
-
- def initialize(filter)
- filter.set_criteria_default_value('columns', ['metric:alert_status', 'name', 'date', 'metric:ncloc', 'metric:violations', 'links'])
- filter.set_criteria_default_value('sort', 'name')
- filter.set_criteria_default_value('asc', 'true')
- filter.set_criteria_default_value('pageSize', '30')
- filter.pagination.per_page = [filter.criteria['pageSize'].to_i, 200].min
- filter.pagination.page = (filter.criteria['page'] || 1).to_i
-
- @columns = filter.criteria['columns'].map { |column_key| Column.new(column_key) }
- @metric_ids = @columns.map { |column| column.metric.id if column.metric }.compact.uniq
- end
-
- def load_links?
- @columns.index { |column| column.links? }
- end
-
- end
-
- class TreemapDisplay < Display
- attr_reader :columns
-
- KEY = :treemap
-
- def initialize(filter)
- filter.set_criteria_default_value('columns', ['metric:ncloc', 'metric:violations_density'])
- @columns = filter.criteria['columns'].map { |column_key| Column.new(column_key) }
- @metric_ids = @columns.map { |column| column.metric.id if column.metric }.compact.uniq
- end
-
- def size_metric
- @size_metric ||= Metric.by_key('ncloc')
- end
-
- def color_metric
- @color_metric ||= Metric.by_key('violations_density')
- end
- end
-
- class CloudDisplay < Display
- attr_reader :columns
-
- KEY = :cloud
-
- def initialize(filter)
- filter.set_criteria_default_value('sort', 'name')
- filter.set_criteria_default_value('asc', 'true')
- @metric_ids = [size_metric.id, color_metric.id]
- end
-
- def size_metric
- @size_metric ||= Metric.by_key('function_complexity')
- end
-
- def color_metric
- @color_metric ||= Metric.by_key('violations_density')
- end
- end
-
- DISPLAYS = [ListDisplay, TreemapDisplay, CloudDisplay]
-
- SUPPORTED_CRITERIA_KEYS=Set.new([:qualifiers, :scopes, :onFavourites, :base, :onBaseComponents, :languages, :fromDate, :toDate, :beforeDays, :afterDays,
- :keyRegexp, :nameRegexp,
- :sort, :asc, :columns, :display, :pageSize, :page])
CRITERIA_SEPARATOR = '|'
CRITERIA_KEY_VALUE_SEPARATOR = ','
- # Configuration available after call to execute()
- attr_reader :pagination, :security_exclusions, :columns
-
- # Results : sorted array of Result
- attr_reader :base_result, :results
-
belongs_to :user
has_many :measure_filter_favourites, :dependent => :delete_all
validates_length_of :name, :maximum => 100, :message => Api::Utils.message('measure_filter.name_too_long')
validates_length_of :description, :allow_nil => true, :maximum => 4000
- def criteria
- @criteria ||= {}
- end
+ attr_reader :pagination, :security_exclusions, :base_result, :results, :display
def sort_key
criteria['sort']
criteria['asc']=='true'
end
-# API for plugins
- def self.register_display(display_class)
- DISPLAYS<<display_class
+ # array of the metrics to use when loading measures
+ def metrics
+ @metrics ||= []
end
- def self.supported_criteria?(key)
- SUPPORTED_CRITERIA_KEYS.include?(key.to_sym)
+ def metrics=(array)
+ @metrics = array
end
- def set_criteria_from_url_params(params)
+ def require_links=(flag)
+ @require_links=flag
+ end
+
+ # boolean flag that indicates if project links should be loaded
+ def require_links?
+ @require_links
+ end
+
+ def criteria(key=nil)
+ @criteria ||= {}
+ if key
+ @criteria[key.to_s]
+ else
+ @criteria
+ end
+ end
+
+ def criteria=(hash)
+ @display = nil
@criteria = {}
- params.each_pair do |k, v|
- if MeasureFilter.supported_criteria?(k) && !v.empty? && v!=['']
+ hash.each_pair do |k, v|
+ if k && v && !v.empty? && v!=['']
@criteria[k.to_s]=v
end
end
self.data = string_data.join(CRITERIA_SEPARATOR)
end
- def display
- @display ||=
- begin
- display_class = nil
- key = criteria['display']
- if key.present?
- display_class = DISPLAYS.find { |d| d::KEY==key.to_sym }
- end
- display_class ||= DISPLAYS.first
- display_class.new(self)
- end
+ def enable_default_display
+ set_criteria_default_value('display', 'list')
end
-
# ==== Options
# :user : the authenticated user
def execute(controller, options={})
init_results
-
+ init_display(options)
user = options[:user]
rows=Api::Utils.java_facade.executeMeasureFilter2(criteria, (user ? user.id : nil))
snapshot_ids = filter_authorized_snapshot_ids(rows, controller)
load_results(snapshot_ids)
-
self
end
@pagination = Api::Pagination.new
@security_exclusions = nil
@results = nil
+ @base_result = nil
self
end
+ def init_display(options)
+ @display = MeasureFilterDisplay.create(self, options)
+ end
+
def filter_authorized_snapshot_ids(rows, controller)
project_ids = rows.map { |row| row.getResourceRootId() }.compact.uniq
authorized_project_ids = controller.select_authorized(:user, project_ids)
def load_results(snapshot_ids)
@results = []
+ metric_ids = metrics.map(&:id)
+
if !snapshot_ids.empty?
results_by_snapshot_id = {}
snapshots = Snapshot.find(:all, :include => ['project'], :conditions => ['id in (?)', snapshot_ids])
@results << results_by_snapshot_id[sid]
end
- if display.metric_ids && !display.metric_ids.empty?
+ unless metric_ids.empty?
measures = ProjectMeasure.find(:all, :conditions =>
- ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id in (?) and metric_id in (?)', snapshot_ids, display.metric_ids]
+ ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id in (?) and metric_id in (?)', snapshot_ids, metric_ids]
)
measures.each do |measure|
result = results_by_snapshot_id[measure.snapshot_id]
- result.add_measure measure
+ result.add_measure(measure)
end
end
- if display.load_links?
+ if require_links?
project_ids = []
results_by_project_id = {}
snapshots.each do |snapshot|
base_snapshot = Snapshot.find(:first, :include => 'project', :conditions => ['projects.kee=? and islast=?', criteria['base'], true])
if base_snapshot
@base_result = Result.new(base_snapshot)
- if display.metric_ids && !display.metric_ids.empty?
+ unless metric_ids.empty?
base_measures = ProjectMeasure.find(:all, :conditions =>
- ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id=? and metric_id in (?)', base_snapshot.id, display.metric_ids]
+ ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id=? and metric_id in (?)', base_snapshot.id, metric_ids]
)
base_measures.each do |base_measure|
@base_result.add_measure(base_measure)
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar 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.
+#
+# Sonar 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 Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class MeasureFilterDisplay
+
+ DISPLAY_CLASSES = [MeasureFilterDisplayList, MeasureFilterDisplayTreemap]
+
+ def self.create(filter, options)
+ key = filter.criteria('display')
+ display_class=DISPLAY_CLASSES.find{|display_class| display_class::KEY==key.to_sym} if key
+ display_class.new(filter, options) if display_class
+ end
+
+ def self.keys
+ DISPLAY_CLASSES.map{|display_class| display_class::KEY}
+ end
+
+ def key
+ self.class::KEY
+ end
+
+ attr_reader :filter, :options
+
+ def initialize(filter, options)
+ @filter = filter
+ @options = options
+ end
+
+ def url_params
+ {}
+ end
+end
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar 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.
+#
+# Sonar 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 Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+require 'set'
+class MeasureFilterDisplayList < MeasureFilterDisplay
+ KEY = :list
+
+ class Column
+ attr_reader :key, :metric
+
+ def initialize(key)
+ @key = key
+ metric_key = @key.split(':')[1]
+ @metric = Metric.by_key(metric_key) if metric_key
+ end
+
+ def name
+ if @metric
+ Api::Utils.message("metric.#{@metric.key}.name", :default => @metric.short_name)
+ else
+ Api::Utils.message("measure_filter.col.#{@key}", :default => @key)
+ end
+ end
+
+ def align
+ @align ||=
+ begin
+ # by default is table cells are left-aligned
+ (@key=='name' || @key=='short_name' || @key=='description') ? '' : 'right'
+ end
+ end
+
+ def sort?
+ !links?
+ end
+
+ def links?
+ @key == 'links'
+ end
+ end
+
+ attr_reader :columns
+
+ def initialize(filter, options)
+ super(filter, options)
+
+ # default values
+ filter.set_criteria_default_value('cols', ['metric:alert_status', 'name', 'date', 'metric:ncloc', 'metric:violations', 'links'])
+ filter.set_criteria_default_value('sort', 'name')
+ filter.set_criteria_default_value('asc', 'true')
+ filter.set_criteria_default_value('pageSize', '30')
+ filter.pagination.per_page = [filter.criteria['pageSize'].to_i, 200].min
+ filter.pagination.page = (filter.criteria['page'] || 1).to_i
+
+ @columns = []
+ metrics = []
+ filter.criteria('cols').each do |column_key|
+ column = Column.new(column_key)
+ @columns << column
+ metrics << column.metric if column.metric
+ filter.require_links=true if column.links?
+ end
+ filter.metrics=(metrics)
+ end
+
+ PROPERTY_KEYS = Set.new(['cols', 'sort', 'asc', 'pageSize'])
+ def url_params
+ @filter.criteria.delete_if { |k,v| !PROPERTY_KEYS.include?(k)}
+ end
+end
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar 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.
+#
+# Sonar 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 Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class MeasureFilterDisplayTreemap < MeasureFilterDisplay
+ include ActionView::Helpers::UrlHelper
+
+ KEY = :treemap
+
+ attr_reader :height, :id, :size, :size_metric, :color_metric
+
+ def initialize(filter, options)
+ super(filter, options)
+
+ @size_metric = Metric.by_key(@filter.criteria('tmSize')||'ncloc')
+ @color_metric = Metric.by_key(@filter.criteria('tmColor')||'violations_density')
+ @html_id = options[:html_id]
+ @filter.metrics=([@size_metric, @color_metric].compact)
+ @height = (@filter.criteria('tmHeight')||'600').to_i
+ @id_count = 0
+ end
+
+ def html
+ if filter.results
+ root = Treemap::Node.new(:id => -1, :label => '')
+ build_tree(root)
+
+ output = Sonar::HtmlOutput.new do |o|
+ # width in percents
+ o.width = 100
+ o.height = @height
+ o.full_html = false
+ o.details_at_depth = 1
+ end
+ html = output.to_html(root)
+ html + "<script>treemapById(#{@html_id}).onLoaded(#{@filter.results.size});</script>"
+ end
+ end
+
+ def empty?
+ @filter.results.nil? || @filter.results.empty?
+ end
+
+ private
+
+ def build_tree(node)
+ if @filter.results
+ @filter.results.each do |result|
+ size_measure=result.measure(@size_metric)
+ if size_measure
+ color_measure=(@color_metric ? result.measure(@color_metric) : nil)
+ resource = result.snapshot.resource
+ child = Treemap::Node.new(:id => "#{@html_id}-#{@id_count += 1}",
+ :size => size_value(size_measure),
+ :label => resource.name(false),
+ :title => escape_javascript(resource.name(true)),
+ :tooltip => tooltip(resource, size_measure, color_measure),
+ :color => html_color(color_measure),
+ :rid => resource.id,
+ :leaf => resource.source_code?)
+ node.add_child(child)
+ end
+ end
+ end
+ end
+
+ def tooltip(resource, size_measure, color_measure)
+ html=CGI::escapeHTML(resource.name(true))
+ html += " - #{CGI::escapeHTML(@size_metric.short_name)}: #{CGI::escapeHTML(size_measure.formatted_value)}"
+ if color_measure
+ html += " - #{CGI::escapeHTML(@color_metric.short_name)}: #{CGI::escapeHTML(color_measure.formatted_value)}"
+ end
+ html
+ end
+
+ def size_value(measure)
+ if measure.value
+ measure.value.to_f.abs||0.0
+ else
+ 0.0
+ end
+ end
+
+ def html_color(measure)
+ MeasureColor.color(measure).html
+ end
+
+end
+
+class Sonar::HtmlOutput < Treemap::HtmlOutput
+
+ def draw_node(node)
+ return "" if node.bounds.nil?
+
+ html = ''
+ html += "<div style=\""
+ html += "overflow:hidden;position:absolute;"
+ html += "left:#{node.bounds.x1}%; top:#{node.bounds.y1}px;"
+ html += "width:#{node.bounds.width}%;height: #{node.bounds.height}px;"
+ html += "background-color:#FFF;\">"
+ html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: #{node.bounds.height-4}px;
+border: 1px solid #{node.color};' alt=\"#{node.tooltip}\" title=\"#{node.tooltip}\""
+ if node.leaf
+ html += "l=1 "
+ end
+ html += ' >'
+ html += draw_node_body(node)
+
+ if (!node.children.nil? && node.children.size > 0)
+ node.children.each do |c|
+ html += draw_node(c)
+ end
+ end
+ html + '</div></div>'
+ end
+
+ def draw_label(node)
+ if node.leaf
+ "<a onclick=\"window.open(this.href,'resource','height=800,width=900,scrollbars=1,resizable=1');return false;\" " +
+ "href=\"#{ApplicationController.root_context}/resource/index/#{node.rid}\">#{node_label(node)}</a>"
+ else
+ "<a href='#{ApplicationController.root_context}/dashboard/index/#{node.rid}'>#{node_label(node)}</a>"
+ end
+ end
+end
\ No newline at end of file
+++ /dev/null
-#
-# Sonar, entreprise quality control tool.
-# Copyright (C) 2008-2012 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# Sonar 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.
-#
-# Sonar 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 Sonar; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
-#
-class MeasureFilterTreemap
- include ActionView::Helpers::UrlHelper
-
- attr_reader :filter, :height, :id, :size, :size_metric, :color_metric
-
- def initialize(filter, height, id)
- @filter = filter
- @height = height
- @id = id
- @size = 0
- @size_metric = filter.display.size_metric
- @color_metric = filter.display.color_metric
- end
-
- def html
- root = Treemap::Node.new(:id => -1, :label => '')
- build_tree(root)
-
- output = Sonar::HtmlOutput.new do |o|
- # width in percents
- o.width = 100
- o.height = @height
- o.full_html = false
- o.details_at_depth = 1
- end
- html = output.to_html(root)
- html + "<script>treemapById(#{@id}).onLoaded(#{@size});</script>"
- end
-
- def empty?
- @size==0
- end
-
- private
-
- def build_tree(node)
- if @filter.results
- @filter.results.each do |result|
- size_measure=result.measure(@size_metric)
- if size_measure
- color_measure=(@color_metric ? result.measure(@color_metric) : nil)
- resource = result.snapshot.resource
- child = Treemap::Node.new(:id => "#{@id}-#{@size += 1}",
- :size => size_value(size_measure),
- :label => resource.name(false),
- :title => escape_javascript(resource.name(true)),
- :tooltip => tooltip(resource, size_measure, color_measure),
- :color => html_color(color_measure),
- :rid => resource.id,
- :leaf => resource.source_code?)
- node.add_child(child)
- end
- end
- end
- end
-
- def tooltip(resource, size_measure, color_measure)
- html=CGI::escapeHTML(resource.name(true))
- html += " - #{CGI::escapeHTML(@size_metric.short_name)}: #{CGI::escapeHTML(size_measure.formatted_value)}"
- if color_measure
- html += " - #{CGI::escapeHTML(@color_metric.short_name)}: #{CGI::escapeHTML(color_measure.formatted_value)}"
- end
- html
- end
-
- def size_value(measure)
- if measure.value
- measure.value.to_f.abs||0.0
- else
- 0.0
- end
- end
-
- def html_color(measure)
- MeasureColor.color(measure).html
- end
-
-end
-
-class Sonar::HtmlOutput < Treemap::HtmlOutput
-
- def draw_node(node)
- return "" if node.bounds.nil?
-
- html = ''
- html += "<div style=\""
- html += "overflow:hidden;position:absolute;"
- html += "left:#{node.bounds.x1}%; top:#{node.bounds.y1}px;"
- html += "width:#{node.bounds.width}%;height: #{node.bounds.height}px;"
- html += "background-color:#FFF;\">"
- html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: #{node.bounds.height-4}px;
-border: 1px solid #{node.color};' alt=\"#{node.tooltip}\" title=\"#{node.tooltip}\""
- if node.leaf
- html += "l=1 "
- end
- html += ' >'
- html += draw_node_body(node)
-
- if (!node.children.nil? && node.children.size > 0)
- node.children.each do |c|
- html += draw_node(c)
- end
- end
- html + '</div></div>'
- end
-
- def draw_label(node)
- if node.leaf
- "<a onclick=\"window.open(this.href,'resource','height=800,width=900,scrollbars=1,resizable=1');return false;\" " +
- "href=\"#{ApplicationController.root_context}/resource/index/#{node.rid}\">#{node_label(node)}</a>"
- else
- "<a href='#{ApplicationController.root_context}/dashboard/index/#{node.rid}'>#{node_label(node)}</a>"
- end
- end
-end
\ No newline at end of file
display_favourites = logged_in?
colspan = @filter.display.columns.size
colspan += 1 if display_favourites
+ if edit_mode
+ content_for :script do
%>
+ <script>
+ var cols = [<%= @filter.display.columns.map{|c| "'#{c.key}'"}.join(',')-%>];
+ function leftCol(id) {
+
+ }
+ function rightCol(id) {
+
+ }
+ function deleteCol(id) {
+
+ }
+ </script>
+ <%
+ end
+ end
+ %>
+
+<% if edit_mode %>
+ <table class="data width100 admin">
+ <tr>
+ <td>
+ <%= metric_select_tag 'metric', Metric.all.reject { |m| m.data? }, :html_id => 'select-metric', :allow_empty => true -%>
+ <button id="add-metric" disabled>Add</button>
+ </td>
+ <td class="right">
+ <a href="#" class="button" id="exit-edit">Done</a>
+ </td>
+ </tr>
+ </table>
+ <script>
+ $j("#select-metric").on("change", function (e) {
+ $j("#add-metric").removeAttr('disabled');
+ });
+ $j("#add-metric").on("click", function (e) {
+ var metric = $j("#select-metric option:selected").val();
+ cols.push('metric:' + metric);
+ window.location = window.location.href.replace(/&?cols\[\]=([^&]$|[^&]*)/g, '') + '&' + $j.map(cols, function (a) {
+ return 'cols[]=' + a;
+ }).join('&');
+ });
+ $j("#exit-edit").on("click", function (e) {
+ window.location = window.location.href.replace(/&?edit=([^&]$|[^&]*)/g, '');
+ });
+ </script>
+<% end %>
+
<table class="data">
<thead>
<tr>
</thead>
<tbody>
+ <% if edit_mode %>
+ <tr class="admin">
+ <% if display_favourites %>
+ <th></th>
+ <% end %>
+ <% @filter.display.columns.each_with_index do |column, index| %>
+ <td class="<%= column.align -%>">
+ <a href="#" onclick="leftCol(<%= index -%>)" title="<%= message('move_left') -%>"><%= image_tag("controls/resultset_previous.png") -%></a>
+ <a href="#" onclick="deleteCol(<%= index -%>)" title="<%= message('delete_column') -%>"><%= image_tag("bin_closed.png") -%></a>
+ <a href="#" onclick="rightCol(<%= index -%>)" title="<%= message('move_right') -%>"><%= image_tag("controls/resultset_next.png") -%></a>
+ </td>
+ <% end %>
+ <% end %>
+
<% if @filter.base_result %>
<tr class="highlight">
<% if display_favourites %>
-<% treemap = MeasureFilterTreemap.new(@filter, 600, @filter.id.to_s) %>
-<div class="treemap" style="width: 100%; height:<%= treemap.height %>px;">
- <%= treemap.html() -%>
+<div class="treemap" style="width: 100%; height:<%= @filter.display.height %>px;">
+ <%= @filter.display.html -%>
</div>
\ No newline at end of file
}
</style>
<% end %>
-
+<% content_for :script do %>
+ <script>
+ function submitSearch() {
+ // remove empty parameters from URL
+ var form = $j("#filter-form");
+ form.find(':input[value=""]').attr('name', '');
+ form.submit();
+ return false;
+ }
+ </script>
+<% end %>
<div id="measure-filters">
- <div id="filter-form" class="page-split-left">
- <form method="GET" action="<%= ApplicationController.root_context -%>/measures/search">
+ <div class="page-split-left">
+ <form id="filter-form" method="GET" action="<%= ApplicationController.root_context -%>/measures/search">
<% if @filter.id %>
<input type="hidden" name="id" value="<%= @filter.id -%>">
<% end %>
+ <%
+ if @filter.display
+ @filter.display.url_params.each_pair do |k, v|
+ if v.is_a?(String)
+ %>
+ <%= hidden_field_tag k, v -%>
+ <% else
+ v.each do |string_val|
+ %>
+ <%= hidden_field_tag "#{k}[]", string_val -%>
+ <% end
+ end
+ end
+ end
+ %>
<table class="width100">
<tbody>
<tr>
<tr>
<td>
<br/>
- <input type="submit" name="search" value="Search">
+ <input type="button" name="search" value="Search" onclick="submitSearch()">
<a href="<%= ApplicationController.root_context -%>/measures">New search</a>
</td>
</tr>
<% end %>
</div>
- <% if @filter.results %>
+ <% if @filter.results && @filter.display %>
<div id="filter-result" class="page-split-right width100">
<% if @filter.name %>
<p>
<% end %>
- Display as:
- <% MeasureFilter::DISPLAYS.each do |display_class| %>
- <%= link_to_if display_class::KEY!=@filter.display.class::KEY, display_class::KEY, params.merge(:action => 'search', :display => display_class::KEY, :id => @filter.id) -%>
- <% end %>
-
- <% if logged_in? && (@filter.user_id==nil || @filter.user_id==current_user.id) %>
- <a id="save_as" href="<%= url_for params.merge({:action => 'save_form', :id => @filter.id}) -%>" class="link-action open-modal"><%= message('save') -%></a>
+ <%
+ edit_mode = (params[:edit]=='true')
+ unless edit_mode %>
+ Display as:
+ <% MeasureFilterDisplay.keys.each do |display_key| %>
+ <%= link_to_if display_key!=@filter.display.key, display_key, params.merge(:action => 'search', :display => display_key, :id => @filter.id) -%>
+ <% end %>
+ <a id="edit" href="<%= url_for params.merge({:edit => true, :id => @filter.id}) -%>" class="button"><%= message('configure') -%></a>
+ <% if logged_in? && (@filter.user_id==nil || @filter.user_id==current_user.id) %>
+ <a id="save_as" href="<%= url_for params.merge({:action => 'save_form', :id => @filter.id}) -%>" class="button open-modal"><%= message('save') -%></a>
+ <% end %>
<% end %>
-
- <%= render :partial => "measures/display_#{@filter.display.class::KEY}" -%>
+ <%= render :partial => "measures/display_#{@filter.display.class::KEY}", :locals => {:edit_mode => edit_mode} -%>
<br>
<% if @filter.security_exclusions %>