warped 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/Gemfile.lock +2 -2
- data/README.md +104 -0
- data/app/assets/config/warped_manifest.js +2 -0
- data/app/assets/javascript/warped/controllers/filter_controller.js +76 -0
- data/app/assets/javascript/warped/controllers/filters_controller.js +21 -0
- data/app/assets/javascript/warped/index.js +2 -0
- data/app/assets/stylesheets/warped/application.css +15 -0
- data/app/assets/stylesheets/warped/base.css +23 -0
- data/app/assets/stylesheets/warped/filters.css +115 -0
- data/app/assets/stylesheets/warped/pagination.css +74 -0
- data/app/assets/stylesheets/warped/search.css +33 -0
- data/app/assets/stylesheets/warped/table.css +114 -0
- data/app/views/warped/_actions.html.erb +9 -0
- data/app/views/warped/_cell.html.erb +3 -0
- data/app/views/warped/_column.html.erb +35 -0
- data/app/views/warped/_filters.html.erb +21 -0
- data/app/views/warped/_hidden_fields.html.erb +19 -0
- data/app/views/warped/_pagination.html.erb +34 -0
- data/app/views/warped/_row.html.erb +19 -0
- data/app/views/warped/_search.html.erb +21 -0
- data/app/views/warped/_table.html.erb +52 -0
- data/app/views/warped/filters/_filter.html.erb +40 -0
- data/config/importmap.rb +3 -0
- data/docs/controllers/FILTERABLE.md +82 -3
- data/docs/controllers/views/PARTIALS.md +285 -0
- data/lib/warped/api/filter/base/value.rb +52 -0
- data/lib/warped/api/filter/base.rb +84 -0
- data/lib/warped/api/filter/boolean.rb +41 -0
- data/lib/warped/api/filter/date.rb +26 -0
- data/lib/warped/api/filter/date_time.rb +32 -0
- data/lib/warped/api/filter/decimal.rb +31 -0
- data/lib/warped/api/filter/factory.rb +38 -0
- data/lib/warped/api/filter/integer.rb +38 -0
- data/lib/warped/api/filter/string.rb +25 -0
- data/lib/warped/api/filter/time.rb +25 -0
- data/lib/warped/api/filter.rb +14 -0
- data/lib/warped/api/sort/value.rb +40 -0
- data/lib/warped/api/sort.rb +65 -0
- data/lib/warped/controllers/filterable/ui.rb +10 -32
- data/lib/warped/controllers/filterable.rb +75 -42
- data/lib/warped/controllers/pageable/ui.rb +13 -3
- data/lib/warped/controllers/pageable.rb +1 -1
- data/lib/warped/controllers/searchable/ui.rb +3 -1
- data/lib/warped/controllers/sortable/ui.rb +21 -26
- data/lib/warped/controllers/sortable.rb +53 -33
- data/lib/warped/controllers/tabulatable/ui.rb +4 -0
- data/lib/warped/controllers/tabulatable.rb +6 -9
- data/lib/warped/engine.rb +19 -0
- data/lib/warped/queries/filter.rb +3 -3
- data/lib/warped/table/action.rb +33 -0
- data/lib/warped/table/column.rb +34 -0
- data/lib/warped/version.rb +1 -1
- data/lib/warped.rb +1 -0
- data/warped.gemspec +1 -1
- metadata +44 -6
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/blank"
|
4
|
+
require "active_support/core_ext/module/delegation"
|
5
|
+
|
6
|
+
module Warped
|
7
|
+
module Filter
|
8
|
+
class Base
|
9
|
+
class Value
|
10
|
+
attr_reader :filter
|
11
|
+
|
12
|
+
delegate :name, :alias_name, :parameter_name, :kind, to: :filter
|
13
|
+
|
14
|
+
# @param filter [Warped::Filter::Base] The filter object
|
15
|
+
# @param relation [String] The filter relation.
|
16
|
+
# @param value [String] The filter value.
|
17
|
+
def initialize(filter, relation, value)
|
18
|
+
@filter = filter
|
19
|
+
@relation = relation
|
20
|
+
@value = value
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [String] The casted filter value.
|
24
|
+
def value
|
25
|
+
filter.cast(@value)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] The validated filter relation.
|
29
|
+
def relation
|
30
|
+
filter.relation(@relation)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Boolean] Whether the filter is empty.
|
34
|
+
def empty?
|
35
|
+
value.nil? && !%w[is_null is_not_null].include?(relation)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
field: filter.name,
|
41
|
+
relation:,
|
42
|
+
value:
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Some filters may need to be parsed/formatted differently for the HTML input value.
|
47
|
+
# This method can be overridden in the filter value class to provide a different value.
|
48
|
+
alias html_value value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
6
|
+
|
7
|
+
module Warped
|
8
|
+
module Filter
|
9
|
+
class Base
|
10
|
+
RELATIONS = %w[eq neq gt gte lt lte between in not_in starts_with ends_with contains is_null is_not_null].freeze
|
11
|
+
|
12
|
+
attr_reader :name, :strict, :alias_name, :options
|
13
|
+
|
14
|
+
delegate :[], to: :options
|
15
|
+
|
16
|
+
# @return [Symbol, nil] The filter kind.
|
17
|
+
def self.kind
|
18
|
+
filter_type = name.demodulize.underscore.to_sym
|
19
|
+
|
20
|
+
filter_type == :filter ? nil : filter_type
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param name [String] The name of the filter.
|
24
|
+
# @param alias_name [String] The alias name of the filter, used for renaming the filter key in the URL params
|
25
|
+
# @param options [Hash] The filter options.
|
26
|
+
def initialize(name, strict:, alias_name: nil, **options)
|
27
|
+
raise ArgumentError, "name cannot be nil" if name.nil?
|
28
|
+
|
29
|
+
@name = name.to_s
|
30
|
+
@strict = strict
|
31
|
+
@alias_name = alias_name&.to_s
|
32
|
+
@options = options
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Symbol, nil] The filter kind.
|
36
|
+
def kind
|
37
|
+
self.class.kind
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Array<String>] The valid filter relations.
|
41
|
+
def relations
|
42
|
+
self.class::RELATIONS
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param relation [Object] The filter relation.
|
46
|
+
# @return [Object] The casted value.
|
47
|
+
# @raise [Warped::Filter::RelationError] If the relation is invalid and strict is true.
|
48
|
+
def cast(value)
|
49
|
+
return if value.nil?
|
50
|
+
|
51
|
+
value
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param relation [String] The validated filter relation.
|
55
|
+
# @return [String] The validated filter relation.
|
56
|
+
# @raise [Warped::Filter::RelationError] If the relation is invalid and strict is true.
|
57
|
+
def relation(relation)
|
58
|
+
if valid_relation?(relation)
|
59
|
+
relation
|
60
|
+
else
|
61
|
+
raise RelationError, "Invalid relation: #{relation}" unless strict
|
62
|
+
|
63
|
+
"eq"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String] The name to use in the URL params.
|
68
|
+
def parameter_name
|
69
|
+
alias_name.presence || name
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [String] The HTML input type.
|
73
|
+
def html_type
|
74
|
+
raise NotImplementedError, "#{self.class.name}#html_type not implemented"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def valid_relation?(relation)
|
80
|
+
relations.include?(relation.to_s)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Warped
|
4
|
+
module Filter
|
5
|
+
class Boolean < Base
|
6
|
+
RELATIONS = %w[eq neq is_null is_not_null].freeze
|
7
|
+
|
8
|
+
def cast(value)
|
9
|
+
return if value.nil?
|
10
|
+
|
11
|
+
casted_value = case value
|
12
|
+
when true, false
|
13
|
+
value
|
14
|
+
when "true", "1", "t", 1
|
15
|
+
true
|
16
|
+
when "false", "0", "f", 0
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
casted_value.tap do |casted|
|
21
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if casted.nil? && strict
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def html_type
|
26
|
+
"text"
|
27
|
+
end
|
28
|
+
|
29
|
+
class Value < Value
|
30
|
+
def html_value
|
31
|
+
case value.class
|
32
|
+
when TrueClass
|
33
|
+
"true"
|
34
|
+
when FalseClass
|
35
|
+
"false"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
|
6
|
+
module Warped
|
7
|
+
module Filter
|
8
|
+
class Date < Base
|
9
|
+
RELATIONS = %w[eq neq gt gte lt lte between is_null is_not_null].freeze
|
10
|
+
|
11
|
+
def cast(value)
|
12
|
+
return if value.blank?
|
13
|
+
|
14
|
+
::Date.parse(value)
|
15
|
+
rescue ::Date::Error
|
16
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if strict
|
17
|
+
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def html_type
|
22
|
+
"date"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
|
6
|
+
module Warped
|
7
|
+
module Filter
|
8
|
+
class DateTime < Base
|
9
|
+
RELATIONS = %w[eq neq gt gte lt lte between is_null is_not_null].freeze
|
10
|
+
|
11
|
+
def cast(value)
|
12
|
+
return if value.blank?
|
13
|
+
|
14
|
+
::DateTime.parse(value)
|
15
|
+
rescue ::Date::Error
|
16
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if strict
|
17
|
+
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def html_type
|
22
|
+
"datetime-local"
|
23
|
+
end
|
24
|
+
|
25
|
+
class Value < Value
|
26
|
+
def html_value
|
27
|
+
value.strftime("%Y-%m-%dT%H:%M:%S")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bigdecimal"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
|
6
|
+
module Warped
|
7
|
+
module Filter
|
8
|
+
class Decimal < Base
|
9
|
+
RELATIONS = %w[eq neq gt gte lt lte between in not_in is_null is_not_null].freeze
|
10
|
+
|
11
|
+
def cast(value)
|
12
|
+
return if value.blank?
|
13
|
+
|
14
|
+
casted_value = case value
|
15
|
+
when ::BigDecimal
|
16
|
+
value
|
17
|
+
when ::Integer, ::Float, ::String
|
18
|
+
value.to_d
|
19
|
+
end
|
20
|
+
|
21
|
+
casted_value.tap do |casted|
|
22
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if casted.nil? && strict
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def html_type
|
27
|
+
"number"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Warped
|
4
|
+
module Filter
|
5
|
+
class Factory
|
6
|
+
TYPES = %i[string integer float decimal date time date_time boolean].freeze
|
7
|
+
|
8
|
+
def self.build(kind, *args, **kwargs)
|
9
|
+
new(kind).build(*args, **kwargs)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(kind = nil)
|
13
|
+
@kind = kind
|
14
|
+
validate_kind!
|
15
|
+
end
|
16
|
+
|
17
|
+
def build(*args, **kwargs)
|
18
|
+
filter_class.new(*args, **kwargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :kind
|
24
|
+
|
25
|
+
def validate_kind!
|
26
|
+
return if kind.nil?
|
27
|
+
|
28
|
+
raise ArgumentError, "#{kind} is not a valid filter type" unless TYPES.include?(kind)
|
29
|
+
end
|
30
|
+
|
31
|
+
def filter_class
|
32
|
+
return Base if kind.nil?
|
33
|
+
|
34
|
+
Filter.const_get(kind.to_s.camelize)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/blank"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
module Filter
|
7
|
+
class Integer < Base
|
8
|
+
RELATIONS = %w[eq neq gt gte lt lte between in not_in is_null is_not_null].freeze
|
9
|
+
|
10
|
+
def cast(value)
|
11
|
+
return if value.blank?
|
12
|
+
|
13
|
+
casted_value = case value
|
14
|
+
when ::Integer
|
15
|
+
value
|
16
|
+
when ::String
|
17
|
+
value.to_i if value.match?(/\A-?\d+\z/)
|
18
|
+
when ::Float, ::BigDecimal
|
19
|
+
value.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
check_casted_value!(casted_value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def html_type
|
26
|
+
"number"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def check_casted_value!(value)
|
32
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if value.nil? && strict
|
33
|
+
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/blank"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
module Filter
|
7
|
+
class String < Base
|
8
|
+
RELATIONS = Queries::Filter::RELATIONS
|
9
|
+
|
10
|
+
def cast(value)
|
11
|
+
return if value.blank?
|
12
|
+
|
13
|
+
value.to_s
|
14
|
+
rescue StandardError
|
15
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if strict
|
16
|
+
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def html_type
|
21
|
+
"text"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/blank"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
module Filter
|
7
|
+
class Time < Base
|
8
|
+
RELATIONS = %w[eq neq gt gte lt lte between is_null is_not_null].freeze
|
9
|
+
|
10
|
+
def cast(value)
|
11
|
+
return if value.blank?
|
12
|
+
|
13
|
+
::Time.parse(value)
|
14
|
+
rescue StandardError
|
15
|
+
raise ValueError, "#{value} cannot be casted to #{kind}" if strict
|
16
|
+
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def html_type
|
21
|
+
"time"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
module Filter
|
7
|
+
class ValueError < StandardError; end
|
8
|
+
class RelationError < StandardError; end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
delegate :build, to: Factory
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
class Sort
|
7
|
+
class Value
|
8
|
+
attr_reader :sort
|
9
|
+
|
10
|
+
delegate :name, :alias_name, :parameter_name, to: :sort
|
11
|
+
|
12
|
+
# @param sort [Warped::Sort] The sort object
|
13
|
+
# @param direction [String] The sort direction.
|
14
|
+
def initialize(sort, direction)
|
15
|
+
@sort = sort
|
16
|
+
@direction = direction
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String] The sort direction.
|
20
|
+
def direction
|
21
|
+
sort.direction!(@direction)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [String] The opposite sort direction.
|
25
|
+
def opposite_direction
|
26
|
+
sort.opposite_direction(direction)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Boolean] Whether the sort is ascending.
|
30
|
+
def asc?
|
31
|
+
%w[asc asc_nulls_first asc_nulls_last].include?(direction)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Boolean] Whether the sort is descending.
|
35
|
+
def desc?
|
36
|
+
%w[desc desc_nulls_first desc_nulls_last].include?(direction)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/blank"
|
4
|
+
|
5
|
+
module Warped
|
6
|
+
class Sort
|
7
|
+
class DirectionError < StandardError; end
|
8
|
+
|
9
|
+
SORT_DIRECTIONS = %w[asc desc].freeze
|
10
|
+
NULLS_SORT_DIRECTION = %w[asc_nulls_first asc_nulls_last desc_nulls_first desc_nulls_last].freeze
|
11
|
+
|
12
|
+
attr_accessor :name, :alias_name
|
13
|
+
|
14
|
+
# @return [Array<String>] The valid sort directions.
|
15
|
+
def self.directions
|
16
|
+
@directions ||= SORT_DIRECTIONS + NULLS_SORT_DIRECTION
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param name [String] The name of the sort.
|
20
|
+
# @param alias_name [String] The alias name of the sort, used for renaming the sort key in the URL params
|
21
|
+
def initialize(name, alias_name: nil)
|
22
|
+
raise ArgumentError, "name cannot be nil" if name.nil?
|
23
|
+
|
24
|
+
@name = name.to_s
|
25
|
+
@alias_name = alias_name&.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] The name to use in the URL params.
|
29
|
+
def parameter_name
|
30
|
+
alias_name.presence || name
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param direction [String] The sort direction.
|
34
|
+
# @return [String] The sort direction.
|
35
|
+
# @raise [DirectionError] If the direction is invalid.
|
36
|
+
def direction!(direction)
|
37
|
+
raise DirectionError, "Invalid direction: #{direction}" unless valid_direction?(direction.to_s)
|
38
|
+
|
39
|
+
direction.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param direction [String] The sort direction.
|
43
|
+
# @return [String] The opposite sort direction.
|
44
|
+
def opposite_direction(direction)
|
45
|
+
opposite_directions[direction]
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def valid_direction?(relation)
|
51
|
+
self.class.directions.include?(relation.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def opposite_directions
|
55
|
+
@opposite_directions ||= {
|
56
|
+
"asc" => "desc",
|
57
|
+
"desc" => "asc",
|
58
|
+
"asc_nulls_first" => "desc_nulls_last",
|
59
|
+
"asc_nulls_last" => "desc_nulls_first",
|
60
|
+
"desc_nulls_first" => "asc_nulls_last",
|
61
|
+
"desc_nulls_last" => "asc_nulls_first"
|
62
|
+
}.freeze
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -10,57 +10,35 @@ module Warped
|
|
10
10
|
include Filterable
|
11
11
|
|
12
12
|
included do
|
13
|
-
helper_method :filters, :filtered?, :
|
13
|
+
helper_method :filters, :filtered?, :filter_url_params, :filterable_by
|
14
14
|
end
|
15
15
|
|
16
|
+
# @see Filterable#filter
|
16
17
|
def filter(...)
|
17
18
|
@filtered = true
|
18
19
|
|
19
20
|
super
|
20
21
|
end
|
21
22
|
|
23
|
+
# @return [Boolean] Whether the current action is filtered.
|
22
24
|
def filtered?
|
23
25
|
@filtered ||= false
|
24
26
|
end
|
25
27
|
|
28
|
+
# @return [Hash] The filters for the current action.
|
26
29
|
def filter_url_params(**options)
|
27
30
|
url_params = {}
|
28
|
-
|
29
|
-
if
|
30
|
-
|
31
|
+
current_action_filter_values.each_with_object(url_params) do |filter_value, hsh|
|
32
|
+
if filter_value.value.is_a?(Array)
|
33
|
+
filter_value.value.each { |value| hsh["#{filter_value.parameter_name}[]"] = value }
|
31
34
|
else
|
32
|
-
hsh[
|
35
|
+
hsh[filter_value.parameter_name] = filter_value.value
|
33
36
|
end
|
34
37
|
|
35
|
-
hsh["#{
|
38
|
+
hsh["#{filter_value.parameter_name}.rel"] = filter_value.relation
|
36
39
|
end
|
37
40
|
|
38
|
-
url_params.
|
39
|
-
end
|
40
|
-
|
41
|
-
def filters
|
42
|
-
(filter_fields | mapped_filter_fields).map do |field|
|
43
|
-
{
|
44
|
-
name: filter_mapped_name(field),
|
45
|
-
value: filter_value(field),
|
46
|
-
relation: filter_rel_value(field)
|
47
|
-
}
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def current_filters
|
52
|
-
(filter_fields | mapped_filter_fields).filter_map do |field|
|
53
|
-
filter_value = filter_value(field)
|
54
|
-
filter_rel_value = filter_rel_value(field)
|
55
|
-
|
56
|
-
next if filter_value.blank? && %w[is_null is_not_null].exclude?(filter_rel_value)
|
57
|
-
|
58
|
-
{
|
59
|
-
name: filter_mapped_name(field),
|
60
|
-
value: filter_value,
|
61
|
-
relation: filter_rel_value
|
62
|
-
}
|
63
|
-
end
|
41
|
+
url_params.merge!(options)
|
64
42
|
end
|
65
43
|
end
|
66
44
|
end
|