will_filter 3.1.3 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.rdoc +0 -3
  5. data/app/assets/javascripts/will_filter/filter.js +5 -5
  6. data/app/assets/javascripts/will_filter/filter_prototype_effects.js +1 -1
  7. data/app/assets/stylesheets/will_filter/exporter.css.scss +72 -49
  8. data/app/assets/stylesheets/will_filter/filter.css.scss +1 -0
  9. data/app/controllers/will_filter/application_controller.rb +1 -1
  10. data/app/controllers/will_filter/calendar_controller.rb +1 -1
  11. data/app/controllers/will_filter/exporter_controller.rb +15 -26
  12. data/app/controllers/will_filter/filter_controller.rb +7 -1
  13. data/app/models/will_filter/filter.rb +69 -12
  14. data/app/views/will_filter/exporter/export.html.erb +26 -2
  15. data/app/views/will_filter/exporter/index.html.erb +35 -43
  16. data/app/views/will_filter/filter/_conditions.html.erb +13 -32
  17. data/app/views/will_filter/filter/_conditions_footer.html.erb +17 -0
  18. data/app/views/will_filter/filter/_conditions_header.html.erb +38 -0
  19. data/app/views/will_filter/filter/_container.html.erb +3 -25
  20. data/lib/generators/will_filter/templates/config.yml +34 -1
  21. data/lib/generators/will_filter/will_filter_generator.rb +1 -1
  22. data/lib/tasks/will_filter_tasks.rake +1 -5
  23. data/lib/will_filter.rb +1 -1
  24. data/lib/will_filter/calendar.rb +1 -1
  25. data/lib/will_filter/config.rb +9 -1
  26. data/lib/will_filter/containers/boolean.rb +1 -1
  27. data/lib/will_filter/containers/date.rb +2 -8
  28. data/lib/will_filter/containers/date_range.rb +3 -9
  29. data/lib/will_filter/containers/date_time.rb +2 -8
  30. data/lib/will_filter/containers/date_time_range.rb +4 -16
  31. data/lib/will_filter/containers/double.rb +52 -0
  32. data/lib/will_filter/containers/double_delimited.rb +50 -0
  33. data/lib/will_filter/containers/double_range.rb +64 -0
  34. data/lib/will_filter/containers/filter_list.rb +1 -1
  35. data/lib/will_filter/containers/list.rb +1 -1
  36. data/lib/will_filter/containers/nil.rb +1 -1
  37. data/lib/will_filter/containers/numeric.rb +1 -1
  38. data/lib/will_filter/containers/numeric_delimited.rb +1 -1
  39. data/lib/will_filter/containers/numeric_range.rb +1 -1
  40. data/lib/will_filter/containers/single_date.rb +3 -3
  41. data/lib/will_filter/containers/text.rb +1 -1
  42. data/lib/will_filter/containers/text_delimited.rb +1 -1
  43. data/lib/will_filter/engine.rb +1 -1
  44. data/lib/will_filter/extensions/action_controller_extension.rb +1 -1
  45. data/lib/will_filter/extensions/action_view_extension.rb +1 -1
  46. data/lib/will_filter/extensions/active_record_extension.rb +1 -1
  47. data/lib/will_filter/extensions/array_extension.rb +1 -1
  48. data/lib/will_filter/filter_condition.rb +1 -1
  49. data/lib/will_filter/filter_container.rb +21 -3
  50. data/lib/will_filter/filter_exception.rb +1 -1
  51. data/lib/will_filter/railtie.rb +1 -1
  52. data/lib/will_filter/version.rb +2 -2
  53. data/spec/containers/double_spec.rb +16 -0
  54. data/spec/fake_app.rb +6 -12
  55. data/test/dummy/app/models/event.rb +1 -1
  56. data/test/dummy/app/models/event_filter.rb +4 -0
  57. data/test/dummy/app/models/event_user_filter.rb +4 -0
  58. data/test/dummy/app/models/user_filter.rb +31 -2
  59. data/test/dummy/config/will_filter/config.yml +9 -1
  60. data/test/dummy/db/migrate/20120223232000_add_rank_to_events.rb +5 -0
  61. data/test/dummy/db/schema.rb +2 -1
  62. metadata +40 -108
  63. data/config/will_filter/config.yml +0 -97
  64. data/db/migrate/20110924023807_create_will_filter_filters.rb +0 -15
data/.gitignore CHANGED
@@ -4,6 +4,7 @@ pkg/
4
4
  test/dummy/db/*.sqlite3
5
5
  test/dummy/log/*.log
6
6
  test/dummy/tmp/
7
+ test/dummy/.sass-cache/
7
8
  db/schema.rb*
8
9
  tmp/*
9
10
  log/*
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm 1.9.2 --create
1
+ rvm use 1.9.2@will_filter --create
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- will_filter (3.1.3)
4
+ will_filter (3.1.5)
5
5
  coffee-script
6
6
  kaminari
7
7
  rails (>= 3.1.0)
@@ -126,7 +126,7 @@ GEM
126
126
  sprockets (2.0.0)
127
127
  hike (~> 1.2)
128
128
  rack (~> 1.0)
129
- tilt (!= 1.3.0, ~> 1.1)
129
+ tilt (~> 1.1, != 1.3.0)
130
130
  sqlite3 (1.3.4)
131
131
  steak (2.0.0)
132
132
  capybara (>= 1.0.0)
data/README.rdoc CHANGED
@@ -72,9 +72,6 @@ Open your browser and point to:
72
72
 
73
73
  http://localhost:3000
74
74
 
75
- Live will_filter_examples application is running here:
76
-
77
- http://wf.tr8n.org
78
75
 
79
76
  If you have any questions, comments or suggestions, email me at theiceberk@gmail.com
80
77
 
@@ -1,5 +1,5 @@
1
1
  /****************************************************************************
2
- Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -235,7 +235,7 @@ Wf.Calendar.prototype = {
235
235
  var trigger_position = Wf.Utils.cumulativeOffset(wfCalendar.trigger);
236
236
  var calendar_container = Wf.element("wf_calendar");
237
237
  calendar_container.style.left = (trigger_position[0] - 273) + "px";
238
- calendar_container.style.top = trigger_position[1] - 6 + "px";
238
+ calendar_container.style.top = trigger_position[1] - 38 + "px";
239
239
  calendar_container.style.width = "260px";
240
240
  Wf.Effects.appear("wf_calendar");
241
241
  }
@@ -261,7 +261,7 @@ Wf.Calendar.prototype = {
261
261
  var width = (mode=='annual' ? 760 : 400);
262
262
  var calendar_container = Wf.element("wf_calendar");
263
263
  calendar_container.style.left = (trigger_position[0] - width - 13) + "px";
264
- calendar_container.style.top = trigger_position[1] - 6 + "px";
264
+ calendar_container.style.top = trigger_position[1] - 38 + "px";
265
265
  calendar_container.style.width = width + "px";
266
266
  }
267
267
  });
@@ -340,8 +340,8 @@ Wf.Exporter.prototype = {
340
340
  onComplete: function(transport) {
341
341
  var trigger_position = Wf.Utils.cumulativeOffset(trigger);
342
342
  var exporter_container = Wf.element("wf_exporter");
343
- exporter_container.style.left = (trigger_position[0] - 245) + "px";
344
- exporter_container.style.top = trigger_position[1] + "px";
343
+ exporter_container.style.left = (trigger_position[0] - 240) + "px";
344
+ exporter_container.style.top = (trigger_position[1] - 32) + "px";
345
345
  Wf.Effects.appear("wf_exporter");
346
346
  }
347
347
  });
@@ -1,5 +1,5 @@
1
1
  /****************************************************************************
2
- Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -5,62 +5,85 @@
5
5
  }
6
6
 
7
7
  @mixin shadow($info) {
8
- box-shadow:$info;
9
- -moz-box-shadow:$info;
10
- -webkit-box-shadow:$info;
8
+ box-shadow:$info;
9
+ -moz-box-shadow:$info;
10
+ -webkit-box-shadow:$info;
11
+ }
12
+
13
+ .wf_exporter_header {
14
+ font-size:12px;
15
+ font-weight:bold;
16
+ margin:0 10px;
17
+
18
+ .close {
19
+ text-decoration:none;
20
+ font-size:18px;
21
+ color:#888;
22
+ &:hover { color:#222;}
23
+ }
11
24
  }
12
25
 
13
26
  .wf_exporter {
14
- background-color:#eee;
15
- position:absolute;
16
- width:230px;
17
- padding: 5px;
18
- font-size:10px;
19
- border:solid 1px #e8e8e8;
20
- border-color:#e8e8e8 #bababa #bababa #e8e8e8;
21
- @include rounded-corners(10px);
22
- @include shadow(2px 3px 3px 2px rgba(0,0,0,0.6));
27
+ background-color:#eee;
28
+ position:absolute;
29
+ width:230px;
30
+ padding: 5px;
31
+ font-size:10px;
32
+ border:solid 1px #e8e8e8;
33
+ border-color:#e8e8e8 #bababa #bababa #e8e8e8;
34
+ @include rounded-corners(10px);
35
+ @include shadow(2px 3px 3px 2px rgba(0,0,0,0.6));
36
+
37
+ img {
38
+ border: 0px;
39
+ }
40
+
41
+ input {
42
+ border: 1px solid #ccc;
43
+ font-size: 12px;
44
+ font-family: Arial;
45
+ @include rounded-corners(10px);
46
+ }
23
47
 
24
- img {
25
- border: 0px;
26
- }
48
+ select {
49
+ border: 1px solid #ccc;
50
+ font-size: 12px;
51
+ font-family: Arial;
52
+ background-color:#EDEDED;
53
+ @include rounded-corners(10px);
54
+ }
27
55
 
28
- input {
29
- border: 1px solid #ccc;
30
- font-size: 12px;
31
- font-family: Arial;
32
- @include rounded-corners(10px);
33
- }
34
-
35
- select {
36
- border: 1px solid #ccc;
37
- font-size: 12px;
38
- font-family: Arial;
39
- background-color:#EDEDED;
40
- @include rounded-corners(10px);
41
- }
56
+ table {
57
+ width:100%;
58
+ border-collapse: collapse;
59
+ font-size:12px;
60
+ padding:0px;
61
+ margin:0px;
62
+
63
+ thead tr {
64
+ border-bottom:1px solid #bababa;
65
+ font-weight:bold;
66
+ }
67
+
68
+ td {
69
+ vertical-align:top;
70
+ padding: 0px;
71
+ margin: 0px;
72
+ }
73
+
74
+ }
75
+
76
+ .center { padding-bottom: 5px;}
42
77
 
43
- table {
44
- width:100%;
45
- border-collapse: collapse;
46
- font-size:12px;
47
- padding:0px;
48
- margin:0px;
49
- }
50
-
51
- td {
52
- vertical-align:top;
53
- padding: 0px;
54
- margin: 0px;
55
- }
56
78
  }
57
79
 
58
80
  .wf_exporter_container {
59
- background-color:white;
60
- padding: 5px;
61
- margin: 5px;
62
- font-size:10px;
63
- border:solid 1px #bababa;
64
- border-color:#bababa #e8e8e8 #e8e8e8 #bababa;
65
- @include rounded-corners(10px);
81
+ background-color:white;
82
+ padding: 5px;
83
+ margin: 5px;
84
+ font-size:10px;
85
+ border:solid 1px #bababa;
86
+ border-color:#bababa #e8e8e8 #e8e8e8 #bababa;
87
+ @include rounded-corners(10px);
66
88
  }
89
+
@@ -166,6 +166,7 @@
166
166
 
167
167
  .end {float:right;}
168
168
  .begin {float:left;}
169
+ .center {text-align:center;}
169
170
  .full_width {width:100%;}
170
171
 
171
172
  .boolean_container {
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -32,7 +32,7 @@ module WillFilter
32
32
 
33
33
  def export
34
34
  params[:page] = 1
35
- params[:per_page] = 10000 # mas export limit
35
+ params[:wf_per_page] = 10000 # max export limit
36
36
 
37
37
  @wf_filter = WillFilter::Filter.deserialize_from_params(params)
38
38
 
@@ -62,38 +62,27 @@ module WillFilter
62
62
  end
63
63
 
64
64
  private
65
-
66
- def send_xml_data(wf_filter)
67
- class_name = wf_filter.model_class_name.underscore
68
-
69
- result = ""
70
- xml = Builder::XmlMarkup.new(:target => result, :indent => 1)
71
- xml.instruct!
72
- xml.tag!(class_name.pluralize) do
73
- wf_filter.results.each do |obj|
74
- xml.tag!(class_name.underscore) do
75
- wf_filter.fields.each do |field|
76
- xml.tag!(field.to_s, obj.send(field).to_s)
77
- end
78
- end
79
- end
80
- end
81
-
82
- send_data(result, :type => 'text/xml', :charset => 'utf-8')
83
- end
84
-
85
- def send_json_data(wf_filter)
86
- result = []
65
+
66
+ def results_from(wf_filter)
67
+ results = []
87
68
 
88
69
  wf_filter.results.each do |obj|
89
70
  hash = {}
90
71
  wf_filter.fields.each do |field|
91
72
  hash[field] = obj.send(field).to_s
92
73
  end
93
- result << hash
74
+ results << hash
94
75
  end
95
76
 
96
- send_data(result.to_json, :type => 'text', :charset => 'utf-8')
77
+ results
78
+ end
79
+
80
+ def send_xml_data(wf_filter)
81
+ send_data(results_from(wf_filter).to_xml, :type => 'text/xml', :charset => 'utf-8')
82
+ end
83
+
84
+ def send_json_data(wf_filter)
85
+ send_data(results_from(wf_filter).to_json, :type => 'text', :charset => 'utf-8')
97
86
  end
98
87
 
99
88
  def send_csv_data(wf_filter)
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -64,6 +64,8 @@ module WillFilter
64
64
  end
65
65
 
66
66
  def save_filter
67
+ raise WillFilter::FilterException.new("Saving functions are disabled") unless WillFilter::Config.saving_enabled?
68
+
67
69
  params.delete(:wf_id)
68
70
 
69
71
  wf_filter = WillFilter::Filter.deserialize_from_params(params)
@@ -79,6 +81,8 @@ module WillFilter
79
81
  end
80
82
 
81
83
  def update_filter
84
+ raise WillFilter::FilterException.new("Update functions are disabled") unless WillFilter::Config.saving_enabled?
85
+
82
86
  wf_filter = WillFilter::Filter.find_by_id(params.delete(:wf_id))
83
87
  wf_filter.deserialize_from_params(params)
84
88
  wf_filter.validate!
@@ -93,6 +97,8 @@ module WillFilter
93
97
  end
94
98
 
95
99
  def delete_filter
100
+ raise WillFilter::FilterException.new("Delete functions are disabled") unless WillFilter::Config.saving_enabled?
101
+
96
102
  wf_filter = WillFilter::Filter.find_by_id(params[:wf_id])
97
103
  wf_filter.destroy if wf_filter
98
104
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2012 Michael Berkovich
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -33,6 +33,11 @@ module WillFilter
33
33
  #############################################################################
34
34
  def initialize(model_class)
35
35
  super()
36
+
37
+ if WillFilter::Config.require_filter_extensions? and self.class.name == "WillFilter::Filter"
38
+ raise WillFilter::FilterException.new("Your configuration requires you to subclass the filter. Default filter cannot be created.")
39
+ end
40
+
36
41
  self.model_class_name = model_class.to_s
37
42
  end
38
43
 
@@ -378,6 +383,7 @@ module WillFilter
378
383
  #############################################################################
379
384
  def self.deserialize_from_params(params)
380
385
  params = HashWithIndifferentAccess.new(params) unless params.is_a?(HashWithIndifferentAccess)
386
+
381
387
  params[:wf_type] = self.name unless params[:wf_type]
382
388
  params[:wf_type].constantize.new(params[:wf_model]).deserialize_from_params(params)
383
389
  end
@@ -476,14 +482,15 @@ module WillFilter
476
482
  # SQL Conditions
477
483
  #############################################################################
478
484
  def sql_conditions
479
- @sql_conditions ||= begin
480
-
485
+ @sql_conditions ||= begin
481
486
  if errors?
482
- all_sql_conditions = [" 1 = 2 "]
487
+ [" 1 = 2 "]
483
488
  else
484
489
  all_sql_conditions = [""]
485
490
  0.upto(size - 1) do |index|
486
491
  condition = condition_at(index)
492
+ next if custom_condition?(condition)
493
+
487
494
  sql_condition = condition.container.sql_condition
488
495
 
489
496
  unless sql_condition
@@ -493,15 +500,17 @@ module WillFilter
493
500
  if all_sql_conditions[0].size > 0
494
501
  all_sql_conditions[0] << ( match.to_sym == :all ? " AND " : " OR ")
495
502
  end
496
-
503
+
497
504
  all_sql_conditions[0] << sql_condition[0]
505
+
498
506
  sql_condition[1..-1].each do |c|
499
507
  all_sql_conditions << c
500
508
  end
509
+
501
510
  end
511
+
512
+ all_sql_conditions
502
513
  end
503
-
504
- all_sql_conditions
505
514
  end
506
515
  end
507
516
 
@@ -547,7 +556,7 @@ module WillFilter
547
556
  if include_default
548
557
  filters = default_filters
549
558
  if (filters.size > 0)
550
- filters.insert(0, ["-- Select Default Filter --", "-1"])
559
+ filters.insert(0, ["Select default filter", "-1"])
551
560
  end
552
561
  end
553
562
 
@@ -569,7 +578,7 @@ module WillFilter
569
578
  user_filters = WillFilter::Filter.find(:all, :conditions => conditions)
570
579
 
571
580
  if user_filters.size > 0
572
- filters << ["-- Select Saved Filter --", "-2"] if include_default
581
+ filters << ["Select saved filter", "-2"] if include_default
573
582
 
574
583
  user_filters.each do |filter|
575
584
  filters << [filter.name, filter.id.to_s]
@@ -638,12 +647,12 @@ module WillFilter
638
647
  #############################################################################
639
648
  def export_formats
640
649
  formats = []
641
- formats << ["-- Generic Formats --", -1]
650
+ formats << ["Generic formats", -1]
642
651
  WillFilter::Config.default_export_formats.each do |frmt|
643
652
  formats << [frmt, frmt]
644
653
  end
645
654
  if custom_formats.size > 0
646
- formats << ["-- Custom Formats --", -2]
655
+ formats << ["Custom formats", -2]
647
656
  custom_formats.each do |frmt|
648
657
  formats << frmt
649
658
  end
@@ -683,7 +692,49 @@ module WillFilter
683
692
  "INNER JOIN #{join_table_name} ON #{join_table_name}.id = #{table_name}.#{join_on_field}"
684
693
  end
685
694
  end
686
-
695
+
696
+ # overload this method to indicate which conditions are custom
697
+ def custom_conditions
698
+ []
699
+ end
700
+
701
+ # overload this method to evaluate a custom condition on an object
702
+ def custom_condition_met?(condition, object)
703
+ false
704
+ end
705
+
706
+ def custom_condition?(condition)
707
+ custom_conditions.include?(condition.key)
708
+ end
709
+
710
+ def custom_conditions?
711
+ return if custom_conditions.empty?
712
+ conditions.each do |condition|
713
+ return true if custom_condition?(condition)
714
+ end
715
+ end
716
+
717
+ def process_custom_conditions(objects)
718
+ filtered = []
719
+ objects.each do |obj|
720
+ condition_flags = []
721
+
722
+ 0.upto(size - 1) do |index|
723
+ condition = condition_at(index)
724
+ next unless custom_condition?(condition)
725
+ condition_flags << custom_condition_met?(condition, obj)
726
+ end
727
+
728
+ if condition_flags.size > 0
729
+ next if match.to_s == "all" and condition_flags.include?(false)
730
+ next unless condition_flags.include?(true)
731
+ end
732
+
733
+ filtered << obj
734
+ end
735
+ filtered
736
+ end
737
+
687
738
  def results
688
739
  @results ||= begin
689
740
  handle_empty_filter!
@@ -691,6 +742,12 @@ module WillFilter
691
742
  inner_joins.each do |inner_join|
692
743
  recs = recs.joins(association_name(inner_join))
693
744
  end
745
+
746
+ if custom_conditions?
747
+ recs = process_custom_conditions(recs.all)
748
+ recs = Kaminari.paginate_array(recs)
749
+ end
750
+
694
751
  recs = recs.page(page).per(per_page)
695
752
  recs.wf_filter = self
696
753
  recs