merged feature/widget into feature/regional_companies

pull/6827/head
Philipp Tessenow 14 years ago
commit af667a2872
  1. 28
      assets/javascripts/reporting/filters.js
  2. 4
      assets/javascripts/reporting/restore_query.js
  3. 22
      assets/stylesheets/reporting.css
  4. 6
      lib/report/filter/base.rb
  5. 11
      lib/report/filter/multi_choice.rb
  6. 31
      lib/report/operator.rb
  7. 8
      lib/widget/filters.rb
  8. 37
      lib/widget/filters/multi_choice.rb

@ -3,7 +3,7 @@
Reporting.Filters = { Reporting.Filters = {
load_available_values_for_filter: function (filter_name, callback_func) { load_available_values_for_filter: function (filter_name, callback_func) {
var select; var select, radio_options;
select = $('' + filter_name + '_arg_1_val'); select = $('' + filter_name + '_arg_1_val');
//TODO: the following code ist cost report specific, we should refactor that to be general useful //TODO: the following code ist cost report specific, we should refactor that to be general useful
if (select !== null && select.readAttribute('data-loading') === "ajax" && select.childElements().length === 0) { if (select !== null && select.readAttribute('data-loading') === "ajax" && select.childElements().length === 0) {
@ -26,7 +26,15 @@ Reporting.Filters = {
callback_func(); callback_func();
} }
// select first option by default // select first option by default
select.selectedIndex = 0; if (select.tagName.toLowerCase() === "div") {
// check if we might have a radio-box
radio_options = $$('.' + filter_name + '_radio_option input');
if (radio_options && radio_options.size() !== 0) {
radio_options.first().checked = true;
}
} else if (select.tagName.toLowerCase() === "select") {
select.selectedIndex = 0;
}
}, },
show_filter: function (field, options) { show_filter: function (field, options) {
@ -58,7 +66,7 @@ Reporting.Filters = {
(options.slowly ? Effect.Appear : Element.show)(field_el); (options.slowly ? Effect.Appear : Element.show)(field_el);
Reporting.Filters.load_available_values_for_filter(field, options.callback_func); Reporting.Filters.load_available_values_for_filter(field, options.callback_func);
$('rm_' + field).value = field; // set the value, so the serialized form will return this filter $('rm_' + field).value = field; // set the value, so the serialized form will return this filter
Reporting.Filters.value_changed(field) Reporting.Filters.value_changed(field);
Reporting.Filters.set_filter_value_widths(100); Reporting.Filters.set_filter_value_widths(100);
} else { } else {
(options.slowly ? Effect.Fade : Element.hide)(field_el); (options.slowly ? Effect.Fade : Element.hide)(field_el);
@ -144,15 +152,13 @@ Reporting.Filters = {
val = $(field + '_arg_1_val'); val = $(field + '_arg_1_val');
tr = $('tr_' + field); tr = $('tr_' + field);
if (!val) { if (!val) {
return return;
}
if (val.value === '<<inactive>>') {
tr.addClassName('inactive-filter');
} else {
tr.removeClassName('inactive-filter');
} }
if (val.value == '<<inactive>>') {
tr.addClassName('inactive-filter')
}
else
{
tr.removeClassName('inactive-filter')
}
}, },
change_argument_visibility: function (field, arg_nr) { change_argument_visibility: function (field, arg_nr) {

@ -33,8 +33,8 @@ Reporting.RestoreQuery = {
// (and possibly are dependents themselfes) // (and possibly are dependents themselfes)
initialize_load_dependent_filters: function(elements) { initialize_load_dependent_filters: function(elements) {
var filters_to_load, dependent_filters; var filters_to_load, dependent_filters;
dependent_filters = elements.findAll(function (select) { return select.value == '<<inactive>>' }); dependent_filters = elements.findAll(function (select) { return select.getValue() == '<<inactive>>' || select.select('option[selected]').size()==0 });
filters_to_load = elements.reject( function (select) { return select.value == '<<inactive>>' }); filters_to_load = elements.reject( function (select) { return select.getValue() == '<<inactive>>' });
// Filters which are <<inactive>> are probably dependents themselfes, so remove and forget them for now. // Filters which are <<inactive>> are probably dependents themselfes, so remove and forget them for now.
// This is OK as they get reloaded later // This is OK as they get reloaded later
dependent_filters.each(function(select) { dependent_filters.each(function(select) {

@ -64,9 +64,9 @@
background-color: #e8e8e8 !important; background-color: #e8e8e8 !important;
} }
.report tr:hover .inner, .report tr:hover .inner,
.report tr:hover .bottom, .report tr:hover .bottom,
.report tr:hover .empty, .report tr:hover .empty,
.report tr:hover .right { .report tr:hover .right {
background-color: #f5f5c5 !important; background-color: #f5f5c5 !important;
} }
@ -164,6 +164,11 @@
white-space: nowrap; white-space: nowrap;
} }
.filter_radio_option {
padding-left: 5px;
padding-right: 5px;
}
#add_filter_block { #add_filter_block {
margin-top: 6px; margin-top: 6px;
} }
@ -495,3 +500,14 @@ html>body #ajax-indicator { position: fixed; }
padding-left: 26px; padding-left: 26px;
vertical-align: bottom; vertical-align: bottom;
} }
<<<<<<< HEAD
#content p,
#content label,
#content a,
#content div {
font-size: 11px;
line-height: 16px;
}
=======
>>>>>>> feature/widgets

@ -23,6 +23,12 @@ class Report::Filter
false false
end end
# Indicates whether this Filter is a multiple choice filter,
# meaning that the user must select a value of a given set of choices.
def self.is_multiple_choice?
false
end
## ##
# A Filter may have depentent filters. See the following example: # A Filter may have depentent filters. See the following example:
# Filter::Project.dependents --> [Filter::IssueId] # Filter::Project.dependents --> [Filter::IssueId]

@ -0,0 +1,11 @@
class Report::Filter
class MultiChoice < Base
dont_inherit :available_operators
use '='
def self.is_multiple_choice?
true
end
end
end

@ -177,6 +177,16 @@ class Report::Operator
end end
end end
new "?=", :label => :label_null_or_equal do
def modify(query, field, *values)
where_clause = "(#{field} IS NULL"
where_clause += " OR #{field} IN #{collection(*values)}" unless values.compact.empty?
where_clause += ")"
query.where where_clause
query
end
end
end end
############################################################################################# #############################################################################################
@ -207,6 +217,10 @@ class Report::Operator
all[name.to_s] or raise ArgumentError, "Operator #{name.inspect} not defined" all[name.to_s] or raise ArgumentError, "Operator #{name.inspect} not defined"
end end
def self.exists?(name)
all.has_key?(name.to_s)
end
def self.defaults(&block) def self.defaults(&block)
class_eval &block class_eval &block
end end
@ -272,6 +286,17 @@ class Report::Operator
self.name <=> other.name self.name <=> other.name
end end
## Creates an alias for a given operator.
def aka(alt_name, alt_label)
all = self.class.all
alt = alt_name.to_s
raise ArgumentError, "Can't alias operator with an existing one's name ( #{alt} )." if all.has_key?(alt)
op = all[name].clone
op.send(:rename_to, alt_name)
op.singleton_class.send(:define_method, 'label') { alt_label }
all[alt] = op
end
module DateRange module DateRange
def modify(query, field, from, to) def modify(query, field, from, to)
query.where ["#{field} > '%s'", quoted_date((Date.yesterday + from).to_time.end_of_day)] if from query.where ["#{field} > '%s'", quoted_date((Date.yesterday + from).to_time.end_of_day)] if from
@ -280,6 +305,12 @@ class Report::Operator
end end
end end
private
def rename_to(new_name)
@name = new_name
end
# Done with class method definition, let's initialize the operators # Done with class method definition, let's initialize the operators
load load

@ -64,8 +64,12 @@ class Widget::Filters < Widget::Base
render_widget Filters::MultiValues, f, :to => html render_widget Filters::MultiValues, f, :to => html
end end
else else
render_widget Filters::MultiValues, f, :to => html if f_cls.is_multiple_choice?
render_widget Filters::MultiChoice, f, :to => html
else
render_widget Filters::MultiValues, f, :to => html
end
end end
render_widget Filters::RemoveButton, f, :to => html render_widget Filters::RemoveButton, f, :to => html
end end
end end

@ -0,0 +1,37 @@
class Widget::Filters::MultiChoice < Widget::Filters::Base
def render
filterName = filter_class.underscore_name
content_tag :td do
content_tag :div, :id => "#{filterName}_arg_1", :class => "filter_values" do
choices = filter_class.available_values.each_with_index.map do |(label, value), i|
opts = {
:type => "radio",
:name => "values[#{filterName}][]",
:id => "#{filterName}_radio_option_#{i}",
:value => value
}
opts[:checked] = "checked" if filter.values == value
radio_button = tag :input, opts
content_tag :label, radio_button + translate(label),
:for => "#{filterName}_radio_option_#{i}",
:'data-filter-name' => filter_class.underscore_name,
:class => "#{filterName}_radio_option filter_radio_option"
end
content_tag :div, choices.join.html_safe,
:id => "#{filter_class.underscore_name}_arg_1_val"
end
end
end
private
def translate(label)
if label.is_a?(Symbol)
::I18n.t(label)
else
label
end
end
end
Loading…
Cancel
Save