avo 2.3.0 → 2.3.1.pre.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +5 -1
- data/app/assets/builds/avo.css +8827 -0
- data/app/assets/builds/avo.js +423 -0
- data/app/assets/builds/avo.js.map +7 -0
- data/app/controllers/avo/base_controller.rb +14 -9
- data/app/javascript/js/controllers/filter_controller.js +11 -1
- data/app/javascript/js/controllers/multiple_select_filter_controller.js +3 -1
- data/app/javascript/js/controllers/select_filter_controller.js +1 -1
- data/app/views/avo/base/_boolean_filter.html.erb +1 -14
- data/app/views/avo/base/_multiple_select_filter.html.erb +2 -13
- data/app/views/avo/base/_select_filter.html.erb +1 -9
- data/app/views/avo/base/_text_filter.html.erb +2 -10
- data/lib/avo/filters/base_filter.rb +17 -2
- data/lib/avo/filters/boolean_filter.rb +12 -0
- data/lib/avo/filters/multiple_select_filter.rb +15 -0
- data/lib/avo/filters/text_filter.rb +4 -0
- data/lib/avo/version.rb +1 -1
- data/public/avo-assets/avo.js +3 -3
- data/public/avo-assets/avo.js.map +2 -2
- metadata +7 -4
@@ -5,6 +5,7 @@ module Avo
|
|
5
5
|
before_action :set_resource_name
|
6
6
|
before_action :set_resource
|
7
7
|
before_action :hydrate_resource
|
8
|
+
before_action :set_applied_filters, only: :index
|
8
9
|
before_action :set_model, only: [:show, :edit, :destroy, :update, :order]
|
9
10
|
before_action :set_model_to_fill
|
10
11
|
before_action :set_edit_title_and_breadcrumbs, only: [:edit, :update]
|
@@ -55,8 +56,8 @@ module Avo
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
# Apply filters
|
59
|
-
|
59
|
+
# Apply filters to the current query
|
60
|
+
filters_to_be_applied.each do |filter_class, filter_value|
|
60
61
|
@query = filter_class.safe_constantize.new.apply_query request, @query, filter_value
|
61
62
|
end
|
62
63
|
|
@@ -308,28 +309,32 @@ module Avo
|
|
308
309
|
.select { |action| action.visible_in_view }
|
309
310
|
end
|
310
311
|
|
311
|
-
def
|
312
|
-
|
313
|
-
|
314
|
-
|
312
|
+
def set_applied_filters
|
313
|
+
@applied_filters = JSON.parse(Base64.decode64(params[:filters]))
|
314
|
+
rescue
|
315
|
+
@applied_filters = {}
|
316
|
+
end
|
315
317
|
|
318
|
+
# Get the default state of the filters and override with the user applied filters
|
319
|
+
def filters_to_be_applied
|
316
320
|
filter_defaults = {}
|
317
321
|
|
318
322
|
@resource.get_filters.each do |filter_class|
|
319
323
|
filter = filter_class.new
|
320
324
|
|
321
|
-
|
325
|
+
unless filter.default.nil?
|
322
326
|
filter_defaults[filter_class.to_s] = filter.default
|
323
327
|
end
|
324
328
|
end
|
325
329
|
|
326
|
-
filter_defaults
|
330
|
+
filter_defaults.merge(@applied_filters)
|
327
331
|
end
|
328
332
|
|
333
|
+
# Caching these so we know when the filters have changed so we reset the pagination
|
329
334
|
def cache_applied_filters
|
330
335
|
::Avo::App.cache_store.delete applied_filters_cache_key if params[:filters].nil?
|
331
336
|
|
332
|
-
::Avo::App.cache_store.write(applied_filters_cache_key, params[:filters], expires_in:
|
337
|
+
::Avo::App.cache_store.write(applied_filters_cache_key, params[:filters], expires_in: 1.day)
|
333
338
|
end
|
334
339
|
|
335
340
|
def reset_pagination_if_filters_changed
|
@@ -38,18 +38,22 @@ export default class extends Controller {
|
|
38
38
|
const value = this.getFilterValue()
|
39
39
|
const filterClass = this.getFilterClass()
|
40
40
|
|
41
|
+
// Get the `filters` param for all params
|
41
42
|
let filters = this.uriParams()[this.uriParam('filters')]
|
42
43
|
|
44
|
+
// Decode the filters
|
43
45
|
if (filters) {
|
44
46
|
filters = JSON.parse(this.b64DecodeUnicode(filters))
|
45
47
|
} else {
|
46
48
|
filters = {}
|
47
49
|
}
|
48
50
|
|
51
|
+
// Get the values for this particular filter
|
49
52
|
filters[filterClass] = value
|
50
53
|
|
51
54
|
const filtered = Object.keys(filters)
|
52
|
-
|
55
|
+
// Filter out the filters without a value
|
56
|
+
.filter((key) => filters[key] !== null)
|
53
57
|
.reduce((obj, key) => {
|
54
58
|
obj[key] = filters[key]
|
55
59
|
|
@@ -58,10 +62,16 @@ export default class extends Controller {
|
|
58
62
|
|
59
63
|
let encodedFilters
|
60
64
|
|
65
|
+
// Encode the filters and their values
|
61
66
|
if (filtered && Object.keys(filtered).length > 0) {
|
62
67
|
encodedFilters = this.b64EncodeUnicode(JSON.stringify(filtered))
|
63
68
|
}
|
64
69
|
|
70
|
+
this.navigateToURLWithFilters(encodedFilters)
|
71
|
+
}
|
72
|
+
|
73
|
+
navigateToURLWithFilters(encodedFilters) {
|
74
|
+
// Create a new URI with them
|
65
75
|
const url = new URI(this.urlRedirectTarget.href)
|
66
76
|
|
67
77
|
const query = {
|
@@ -4,7 +4,9 @@ export default class extends BaseFilterController {
|
|
4
4
|
static targets = ['selector']
|
5
5
|
|
6
6
|
getFilterValue() {
|
7
|
-
|
7
|
+
const filterValue = Array.from(this.selectorTarget.selectedOptions).map(({ value }) => value)
|
8
|
+
|
9
|
+
return filterValue.length === 0 ? null : filterValue
|
8
10
|
}
|
9
11
|
|
10
12
|
getFilterClass() {
|
@@ -1,23 +1,10 @@
|
|
1
|
-
<%
|
2
|
-
begin
|
3
|
-
decoded_filters_param = JSON.parse(Base64.decode64(params[:filters]))
|
4
|
-
set_value = decoded_filters_param[filter.class.to_s]
|
5
|
-
rescue => exception
|
6
|
-
if filter.default.present?
|
7
|
-
set_value = filter.default.stringify_keys
|
8
|
-
else
|
9
|
-
set_value = {}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
set_value = {} if set_value.nil?
|
13
|
-
%>
|
14
1
|
<div data-controller="boolean-filter" data-filter-name="<%= filter.name %>">
|
15
2
|
<%= filter_wrapper name: filter.name do %>
|
16
3
|
<div class="flex items-center">
|
17
4
|
<div class="space-y-2">
|
18
5
|
<% filter.options.each do |value, label| %>
|
19
6
|
<label class="flex items-center text-gray-700 text-sm">
|
20
|
-
<%= check_box_tag filter.id, value,
|
7
|
+
<%= check_box_tag filter.id, value, filter.selected_value(value.to_s, @applied_filters),
|
21
8
|
class: 'mr-2 text-lg h-4 w-4',
|
22
9
|
id: "avo_filters_#{filter.id.parameterize.underscore}",
|
23
10
|
'data-filter-class': filter.class,
|
@@ -1,17 +1,6 @@
|
|
1
|
-
<%
|
2
|
-
set_value = filter.default.present? ? filter.default.select { |key, value| value }.keys.map(&:to_sym) : {}
|
3
|
-
|
4
|
-
begin
|
5
|
-
decoded_filters_param = JSON.parse(Base64.decode64(params[:filters]))
|
6
|
-
if decoded_filters_param[filter.class.to_s].present?
|
7
|
-
set_value = decoded_filters_param[filter.class.to_s]
|
8
|
-
end
|
9
|
-
rescue
|
10
|
-
end
|
11
|
-
%>
|
12
1
|
<div data-controller="multiple-select-filter" data-filter-name="<%= filter.name %>">
|
13
2
|
<%= filter_wrapper name: filter.name do %>
|
14
|
-
<%= select_tag filter.id, options_for_select(filter.options.invert,
|
3
|
+
<%= select_tag filter.id, options_for_select(filter.options.invert, filter.selected_value(@applied_filters)),
|
15
4
|
class: input_classes('w-full mb-0'),
|
16
5
|
multiple: true,
|
17
6
|
id: "avo_filters_#{filter.id.parameterize.underscore}",
|
@@ -19,7 +8,7 @@
|
|
19
8
|
'data-multiple-select-filter-target': 'selector'
|
20
9
|
%>
|
21
10
|
<div class="flex justify-end">
|
22
|
-
<%= a_button class: 'mt-4', color: :blue, size: :
|
11
|
+
<%= a_button class: 'mt-4', color: :blue, size: :xs, data: { action: "multiple-select-filter#changeFilter" } do %>
|
23
12
|
Filter by <%=filter.name %>
|
24
13
|
<% end %>
|
25
14
|
</div>
|
@@ -1,14 +1,6 @@
|
|
1
|
-
<%
|
2
|
-
begin
|
3
|
-
decoded_filters_param = JSON.parse(Base64.decode64(params[:filters]))
|
4
|
-
set_value = decoded_filters_param[filter.class.to_s]
|
5
|
-
rescue => exception
|
6
|
-
set_value = filter.default
|
7
|
-
end
|
8
|
-
%>
|
9
1
|
<div data-controller="select-filter" data-filter-name="<%= filter.name %>">
|
10
2
|
<%= filter_wrapper name: filter.name do %>
|
11
|
-
<%= select_tag filter.id, options_for_select(filter.options.invert,
|
3
|
+
<%= select_tag filter.id, options_for_select(filter.options.invert, filter.applied_or_default_value(@applied_filters)),
|
12
4
|
class: input_classes('w-full mb-0'),
|
13
5
|
include_blank: '—',
|
14
6
|
id: "avo_filters_#{filter.id.parameterize.underscore}",
|
@@ -1,14 +1,6 @@
|
|
1
|
-
<%
|
2
|
-
begin
|
3
|
-
decoded_filters_param = JSON.parse(Base64.decode64(params[:filters]))
|
4
|
-
set_value = decoded_filters_param[filter.class.to_s]
|
5
|
-
rescue => exception
|
6
|
-
set_value = filter.default
|
7
|
-
end
|
8
|
-
%>
|
9
1
|
<div data-controller="text-filter" data-filter-name="<%= filter.name %>">
|
10
2
|
<%= filter_wrapper name: filter.name do %>
|
11
|
-
<%= text_field_tag filter.id,
|
3
|
+
<%= text_field_tag filter.id, filter.applied_or_default_value(@applied_filters),
|
12
4
|
class: input_classes('w-full mb-0'),
|
13
5
|
id: "avo_filters_#{filter.id.parameterize.underscore}",
|
14
6
|
'data-filter-class': filter.class.to_s,
|
@@ -16,7 +8,7 @@
|
|
16
8
|
'data-action': 'keypress->text-filter#tryToSubmit'
|
17
9
|
%>
|
18
10
|
<div class="flex justify-end">
|
19
|
-
<%= a_button class: 'mt-4', color: :blue, data: { action: "text-filter#changeFilter" }, size: :
|
11
|
+
<%= a_button class: 'mt-4', color: :blue, data: { action: "text-filter#changeFilter" }, size: :xs do %>
|
20
12
|
<%= filter.button_label || "Filter by #{filter.name}" %>
|
21
13
|
<% end %>
|
22
14
|
</div>
|
@@ -3,11 +3,11 @@ module Avo
|
|
3
3
|
class BaseFilter
|
4
4
|
class_attribute :name, default: "Filter"
|
5
5
|
class_attribute :component, default: "boolean-filter"
|
6
|
-
class_attribute :default, default:
|
6
|
+
class_attribute :default, default: nil
|
7
7
|
class_attribute :template, default: "avo/base/select_filter"
|
8
8
|
|
9
9
|
def apply_query(request, query, value)
|
10
|
-
value.
|
10
|
+
value.stringify_keys! if value.is_a? Hash
|
11
11
|
|
12
12
|
apply(request, query, value)
|
13
13
|
end
|
@@ -15,6 +15,21 @@ module Avo
|
|
15
15
|
def id
|
16
16
|
self.class.name.underscore.tr("/", "_")
|
17
17
|
end
|
18
|
+
|
19
|
+
# Get the applied value this filter.
|
20
|
+
# If it's not present return the default value.
|
21
|
+
def applied_or_default_value(applied_filters)
|
22
|
+
# Get the values for this particular filter
|
23
|
+
applied_value = applied_filters[self.class.to_s]
|
24
|
+
|
25
|
+
# Return that value if present
|
26
|
+
return applied_value unless applied_value.nil?
|
27
|
+
|
28
|
+
# Return that default
|
29
|
+
default
|
30
|
+
rescue
|
31
|
+
default
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
20
35
|
end
|
@@ -2,6 +2,18 @@ module Avo
|
|
2
2
|
module Filters
|
3
3
|
class BooleanFilter < BaseFilter
|
4
4
|
self.template = "avo/base/boolean_filter"
|
5
|
+
|
6
|
+
def selected_value(item, applied_filters)
|
7
|
+
# See if there are any applied rules for this particular filter
|
8
|
+
if applied_filters[self.class.to_s].present?
|
9
|
+
# Symbolize the keys because they are returned from de-serialization (JSON and Base64)
|
10
|
+
applied_filters[self.class.to_s].stringify_keys.dig(item.to_s)
|
11
|
+
else
|
12
|
+
applied_or_default_value(applied_filters).stringify_keys.dig(item.to_s)
|
13
|
+
end
|
14
|
+
rescue
|
15
|
+
false
|
16
|
+
end
|
5
17
|
end
|
6
18
|
end
|
7
19
|
end
|
@@ -2,6 +2,21 @@ module Avo
|
|
2
2
|
module Filters
|
3
3
|
class MultipleSelectFilter < BaseFilter
|
4
4
|
self.template = "avo/base/multiple_select_filter"
|
5
|
+
|
6
|
+
# The input expects an array of strings for the value
|
7
|
+
# Ex: ['admins', 'non_admins']
|
8
|
+
def selected_value(applied_filters)
|
9
|
+
# Get the values for this particular filter
|
10
|
+
applied_value = applied_filters[self.class.to_s]
|
11
|
+
|
12
|
+
# Return that value if present
|
13
|
+
return applied_value unless applied_value.nil?
|
14
|
+
|
15
|
+
# Return that default
|
16
|
+
return default unless default.nil?
|
17
|
+
|
18
|
+
[]
|
19
|
+
end
|
5
20
|
end
|
6
21
|
end
|
7
22
|
end
|
data/lib/avo/version.rb
CHANGED