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.

@@ -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
- applied_filters.each do |filter_class, filter_value|
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 applied_filters
312
- if params[:filters].present?
313
- return JSON.parse(Base64.decode64(params[:filters]))
314
- end
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
- if filter.default.present?
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: 7.days)
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
- .filter((key) => filters[key] !== '')
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
- return Array.from(this.selectorTarget.selectedOptions).map(({ value }) => value)
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() {
@@ -4,7 +4,7 @@ export default class extends BaseFilterController {
4
4
  static targets = ['selector']
5
5
 
6
6
  getFilterValue() {
7
- return this.selectorTarget.value
7
+ return this.selectorTarget.value === '' ? null : this.selectorTarget.value
8
8
  }
9
9
 
10
10
  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, set_value[value.to_s],
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, set_value),
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: :sm, data: { action: "multiple-select-filter#changeFilter" } do %>
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, set_value),
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, set_value,
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: :sm do %>
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.symbolize_keys! if value.is_a? Hash
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
@@ -4,6 +4,10 @@ module Avo
4
4
  class_attribute :button_label
5
5
 
6
6
  self.template = "avo/base/text_filter"
7
+
8
+ def selected_value(applied_filters)
9
+ applied_or_default_value
10
+ end
7
11
  end
8
12
  end
9
13
  end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.3.0"
2
+ VERSION = "2.3.1.pre.1"
3
3
  end