warped 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +43 -11
@@ -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
|