headmin 0.4.0 → 0.5.0
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/.lock-487e157d270f3062a98b7b2a012753708-1272821827 +0 -0
- data/CHANGELOG.md +16 -2
- data/Gemfile.lock +77 -79
- data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +84 -21
- data/app/assets/javascripts/headmin/controllers/date_range_controller.js +12 -6
- data/app/assets/javascripts/headmin/controllers/filter_controller.js +61 -11
- data/app/assets/javascripts/headmin/controllers/filter_row_controller.js +50 -0
- data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +2 -6
- data/app/assets/javascripts/headmin/controllers/popup_controller.js +14 -5
- data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +16 -21
- data/app/assets/javascripts/headmin/index.js +2 -0
- data/app/assets/javascripts/headmin.js +186 -56
- data/app/assets/stylesheets/headmin/filter.scss +74 -0
- data/app/assets/stylesheets/headmin/general.scss +8 -0
- data/app/assets/stylesheets/headmin/layout/body.scss +5 -0
- data/app/assets/stylesheets/headmin/popup.scss +0 -1
- data/app/assets/stylesheets/headmin.css +70 -1
- data/app/controllers/concerns/headmin/filterable.rb +27 -0
- data/app/models/concerns/headmin/field.rb +4 -2
- data/app/models/concerns/headmin/fieldable.rb +138 -44
- data/app/models/headmin/filter/base.rb +238 -0
- data/app/models/headmin/filter/base_view.rb +64 -0
- data/app/models/headmin/filter/boolean.rb +15 -0
- data/app/models/headmin/filter/boolean_view.rb +61 -0
- data/app/models/headmin/filter/button_view.rb +25 -0
- data/app/models/headmin/filter/conditional_view.rb +16 -0
- data/app/models/headmin/filter/date.rb +19 -0
- data/app/models/headmin/filter/date_view.rb +52 -0
- data/app/models/headmin/filter/flatpickr_view.rb +54 -0
- data/app/models/headmin/filter/menu_item_view.rb +6 -0
- data/app/models/headmin/filter/money.rb +13 -0
- data/app/models/headmin/filter/number.rb +27 -0
- data/app/models/headmin/filter/number_view.rb +54 -0
- data/app/models/headmin/filter/operator_view.rb +30 -0
- data/app/models/headmin/filter/options_view.rb +61 -0
- data/app/models/headmin/filter/row_view.rb +13 -0
- data/app/models/headmin/filter/search.rb +18 -0
- data/app/models/headmin/filter/search_view.rb +31 -0
- data/app/models/headmin/filter/text.rb +25 -0
- data/app/models/headmin/filter/text_view.rb +53 -0
- data/app/models/headmin/filters.rb +29 -0
- data/app/models/headmin/form/blocks_view.rb +1 -1
- data/app/models/headmin/form/checkbox_view.rb +3 -3
- data/app/models/headmin/form/date_range_view.rb +2 -2
- data/app/models/headmin/form/date_view.rb +5 -5
- data/app/models/headmin/form/datetime_range_view.rb +25 -0
- data/app/models/headmin/form/datetime_view.rb +45 -0
- data/app/models/headmin/form/email_view.rb +7 -7
- data/app/models/headmin/form/file_view.rb +6 -6
- data/app/models/headmin/form/flatpickr_range_view.rb +11 -22
- data/app/models/headmin/form/flatpickr_view.rb +4 -13
- data/app/models/headmin/form/input_group_view.rb +1 -1
- data/app/models/headmin/form/label_view.rb +1 -1
- data/app/models/headmin/form/number_view.rb +5 -5
- data/app/models/headmin/form/password_view.rb +5 -5
- data/app/models/headmin/form/redactorx_view.rb +2 -2
- data/app/models/headmin/form/search_view.rb +7 -7
- data/app/models/headmin/form/select_view.rb +6 -6
- data/app/models/headmin/form/switch_view.rb +1 -1
- data/app/models/headmin/form/text_view.rb +7 -7
- data/app/models/headmin/form/textarea_view.rb +5 -5
- data/app/models/headmin/form/url_view.rb +7 -7
- data/app/models/headmin/form/wrapper_view.rb +1 -1
- data/app/models/headmin/form/wysiwyg_view.rb +1 -1
- data/app/models/view_model.rb +1 -1
- data/app/views/examples/admin.html.erb +13 -13
- data/app/views/examples/auth.html.erb +1 -1
- data/app/views/headmin/_filters.html.erb +6 -6
- data/app/views/headmin/_form.html.erb +2 -2
- data/app/views/headmin/_index.html.erb +1 -1
- data/app/views/headmin/_pagination.html.erb +1 -1
- data/app/views/headmin/_popup.html.erb +2 -2
- data/app/views/headmin/_table.html.erb +1 -1
- data/app/views/headmin/dropdown/_devise.html.erb +8 -8
- data/app/views/headmin/dropdown/_locale.html.erb +4 -4
- data/app/views/headmin/filters/_base.html.erb +95 -0
- data/app/views/headmin/filters/_boolean.html.erb +23 -0
- data/app/views/headmin/filters/_date.html.erb +14 -38
- data/app/views/headmin/filters/_flatpickr.html.erb +15 -48
- data/app/views/headmin/filters/_number.html.erb +23 -0
- data/app/views/headmin/filters/_options.html.erb +24 -0
- data/app/views/headmin/filters/_search.html.erb +14 -12
- data/app/views/headmin/filters/_text.html.erb +23 -0
- data/app/views/headmin/filters/filter/_button.html.erb +9 -10
- data/app/views/headmin/filters/filter/_conditional.html.erb +18 -0
- data/app/views/headmin/filters/filter/_menu_item.html.erb +5 -2
- data/app/views/headmin/filters/filter/_null_select.html.erb +8 -0
- data/app/views/headmin/filters/filter/_operator.html.erb +16 -0
- data/app/views/headmin/filters/filter/_row.html.erb +11 -0
- data/app/views/headmin/forms/_blocks.html.erb +1 -1
- data/app/views/headmin/forms/_date_range.html.erb +3 -3
- data/app/views/headmin/forms/_datetime.html.erb +41 -0
- data/app/views/headmin/forms/_datetime_range.html.erb +40 -0
- data/app/views/headmin/forms/_file.html.erb +3 -3
- data/app/views/headmin/forms/_flatpickr.html.erb +1 -1
- data/app/views/headmin/forms/_flatpickr_range.html.erb +3 -4
- data/app/views/headmin/forms/_label.html.erb +1 -1
- data/app/views/headmin/forms/_repeater.html.erb +12 -12
- data/app/views/headmin/forms/fields/_base.html.erb +1 -1
- data/app/views/headmin/forms/fields/_file.html.erb +3 -3
- data/app/views/headmin/forms/fields/_files.html.erb +17 -0
- data/app/views/headmin/forms/fields/_group.html.erb +10 -5
- data/app/views/headmin/forms/fields/_list.html.erb +4 -4
- data/app/views/headmin/forms/fields/_text.html.erb +2 -2
- data/app/views/headmin/layout/_footer.html.erb +1 -1
- data/app/views/headmin/layout/_main.html.erb +1 -1
- data/app/views/headmin/nav/_dropdown.html.erb +3 -3
- data/app/views/headmin/nav/_item.html.erb +2 -2
- data/app/views/headmin/nav/item/_devise.html.erb +8 -8
- data/app/views/headmin/nav/item/_locale.html.erb +4 -4
- data/app/views/headmin/table/_actions.html.erb +3 -6
- data/app/views/headmin/table/actions/_export.html.erb +1 -1
- data/app/views/headmin/table/body/_row.html.erb +3 -3
- data/app/views/headmin/table/foot/_id.html.erb +1 -1
- data/app/views/headmin/views/devise/confirmations/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/passwords/_edit.html.erb +2 -2
- data/app/views/headmin/views/devise/passwords/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/registrations/_edit.html.erb +4 -4
- data/app/views/headmin/views/devise/registrations/_new.html.erb +3 -3
- data/app/views/headmin/views/devise/sessions/_new.html.erb +3 -3
- data/app/views/headmin/views/devise/unlocks/_new.html.erb +1 -1
- data/config/locales/en.yml +4 -0
- data/config/locales/headmin/dropdown/en.yml +6 -0
- data/config/locales/headmin/dropdown/nl.yml +6 -0
- data/config/locales/headmin/filters/en.yml +26 -1
- data/config/locales/headmin/filters/nl.yml +26 -1
- data/config/locales/headmin/forms/en.yml +1 -1
- data/config/locales/headmin/forms/nl.yml +1 -1
- data/config/locales/headmin/layout/en.yml +0 -9
- data/config/locales/headmin/layout/nl.yml +0 -9
- data/config/locales/headmin/nav/en.yml +7 -0
- data/config/locales/headmin/nav/nl.yml +7 -0
- data/config/locales/nl.yml +4 -0
- data/lib/generators/templates/views/layouts/auth.html.erb +1 -1
- data/lib/headmin/version.rb +1 -1
- data/package.json +1 -1
- metadata +44 -7
- data/app/controllers/concerns/headmin/filter.rb +0 -5
- data/app/controllers/concerns/headmin/searchable.rb +0 -15
- data/app/views/headmin/filters/_select.html.erb +0 -45
- data/app/views/headmin/filters/filter/_template.html.erb +0 -13
- data/app/views/headmin/forms/fields/_image.html.erb +0 -17
@@ -0,0 +1,61 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class BooleanView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def value
|
19
|
+
# If the value is nil we want to display the first option (which is true)
|
20
|
+
@value.nil? ? @value = true : ""
|
21
|
+
end
|
22
|
+
|
23
|
+
def id
|
24
|
+
"#{name}_value"
|
25
|
+
end
|
26
|
+
|
27
|
+
def name
|
28
|
+
@name || attribute
|
29
|
+
end
|
30
|
+
|
31
|
+
def label
|
32
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_base_options
|
36
|
+
{
|
37
|
+
label: label,
|
38
|
+
name: attribute,
|
39
|
+
filter: Headmin::Filter::Boolean.new(name, @params),
|
40
|
+
display_values: [[I18n.t("headmin.filters.values.true"), true], [I18n.t("headmin.filters.values.false"), false]],
|
41
|
+
allowed_operators: Headmin::Filter::Boolean::OPERATORS
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def default_input_options
|
46
|
+
{
|
47
|
+
label: false,
|
48
|
+
wrapper: false,
|
49
|
+
id: id,
|
50
|
+
collection: [[I18n.t("headmin.filters.values.true"), 1], [I18n.t("headmin.filters.values.false"), 0]],
|
51
|
+
selected: value ? 1 : 0,
|
52
|
+
data: {
|
53
|
+
action: "change->filter#updateHiddenValue",
|
54
|
+
filter_target: "value",
|
55
|
+
filter_row_target: "original"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class ButtonView < ViewModel
|
4
|
+
def id
|
5
|
+
@id || SecureRandom.hex
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
@name.to_sym
|
10
|
+
end
|
11
|
+
|
12
|
+
def label
|
13
|
+
@label || name.to_s.humanize
|
14
|
+
end
|
15
|
+
|
16
|
+
def display_values
|
17
|
+
@display_values || []
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter
|
21
|
+
@filter || nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class ConditionalView < ViewModel
|
4
|
+
def selected
|
5
|
+
@selected ? "+#{@selected.to_s.upcase}+" : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def values
|
9
|
+
{
|
10
|
+
"+AND+": I18n.t("headmin.filters.filter.conditional.and"),
|
11
|
+
"+OR+": I18n.t("headmin.filters.filter.conditional.or")
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class Date < Headmin::Filter::Base
|
4
|
+
OPERATORS = %w[eq not_eq gt gteq lt lteq between not_between in not_in is_null is_not_null]
|
5
|
+
|
6
|
+
def cast_value(value)
|
7
|
+
value.present? ? value.to_date : ::Date.current
|
8
|
+
rescue
|
9
|
+
raise TypeError, "The value that was passed to this filter is not a date"
|
10
|
+
end
|
11
|
+
|
12
|
+
def display_value(value)
|
13
|
+
# This uses the default date format of headmin.
|
14
|
+
# Can be overwritten by setting default date format of the application.
|
15
|
+
I18n.l(value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class DateView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def id
|
19
|
+
"#{name}_value"
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name || attribute
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_base_options
|
31
|
+
{
|
32
|
+
label: label,
|
33
|
+
name: attribute,
|
34
|
+
filter: Headmin::Filter::Date.new(name, @params),
|
35
|
+
allowed_operators: Headmin::Filter::Date::OPERATORS - %w[in not_in between not_between]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_input_options
|
40
|
+
{
|
41
|
+
label: false,
|
42
|
+
wrapper: false,
|
43
|
+
id: id,
|
44
|
+
data: {action: "change->filter#updateHiddenValue",
|
45
|
+
filter_target: "value",
|
46
|
+
filter_row_target: "original"},
|
47
|
+
class: "form-control"
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class FlatpickrView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def id
|
19
|
+
"#{name}_value"
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name || attribute
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_base_options
|
31
|
+
{
|
32
|
+
label: label,
|
33
|
+
name: attribute,
|
34
|
+
filter: Headmin::Filter::Date.new(name, @params),
|
35
|
+
allowed_operators: Headmin::Filter::Date::OPERATORS - %w[in not_in between not_between]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_input_options
|
40
|
+
{
|
41
|
+
label: false,
|
42
|
+
wrapper: false,
|
43
|
+
id: id,
|
44
|
+
data: {
|
45
|
+
action: "change->filter#updateHiddenValue",
|
46
|
+
filter_target: "value",
|
47
|
+
filter_row_target: "original"
|
48
|
+
},
|
49
|
+
class: "form-control"
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class Number < Headmin::Filter::Base
|
4
|
+
OPERATORS = %w[eq not_eq gt gteq lt lteq between not_between in not_in is_null is_not_null]
|
5
|
+
|
6
|
+
def cast_value(value)
|
7
|
+
is_i?(value) ? value.to_i : 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
string
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def is_i?(value)
|
17
|
+
# Regex: this selects signed digits (\d) only, it is then checked to the value, e.g.:
|
18
|
+
# is_i?("3") = true
|
19
|
+
# is_i?("-3") = true
|
20
|
+
# is_i?("3a") = false
|
21
|
+
# is_i?("3.2") = false
|
22
|
+
|
23
|
+
/\A[-+]?\d+\z/.match(value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class NumberView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def id
|
19
|
+
"#{name}_value"
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name || attribute
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_base_options
|
31
|
+
{
|
32
|
+
label: label,
|
33
|
+
name: attribute,
|
34
|
+
filter: Headmin::Filter::Number.new(name, @params),
|
35
|
+
allowed_operators: Headmin::Filter::Number::OPERATORS - %w[in not_in between not_between]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_input_options
|
40
|
+
{
|
41
|
+
label: false,
|
42
|
+
wrapper: false,
|
43
|
+
id: id,
|
44
|
+
data: {
|
45
|
+
action: "change->filter#updateHiddenValue",
|
46
|
+
filter_target: "value",
|
47
|
+
filter_row_target: "original"
|
48
|
+
},
|
49
|
+
class: "form-control"
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class OperatorView < ViewModel
|
4
|
+
def allowed_operators
|
5
|
+
@allowed_operators || []
|
6
|
+
end
|
7
|
+
|
8
|
+
def selected
|
9
|
+
@selected || nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def operator_symbol
|
13
|
+
{
|
14
|
+
eq: "= #{I18n.t("headmin.filters.operators.eq")}",
|
15
|
+
not_eq: "≠ #{I18n.t("headmin.filters.operators.not_eq")}",
|
16
|
+
gt: "> #{I18n.t("headmin.filters.operators.gt")}",
|
17
|
+
gteq: "≥ #{I18n.t("headmin.filters.operators.gteq")}",
|
18
|
+
lt: "< #{I18n.t("headmin.filters.operators.lt")}",
|
19
|
+
lteq: "≤ #{I18n.t("headmin.filters.operators.lteq")}",
|
20
|
+
starts_with: "⊏ #{I18n.t("headmin.filters.operators.starts_with")}",
|
21
|
+
ends_with: "⊐ #{I18n.t("headmin.filters.operators.ends_with")}",
|
22
|
+
matches: "≈ #{I18n.t("headmin.filters.operators.matches")}",
|
23
|
+
does_not_match: "≉ #{I18n.t("headmin.filters.operators.does_not_match")}",
|
24
|
+
is_null: "○ #{I18n.t("headmin.filters.operators.is_null")}",
|
25
|
+
is_not_null: "● #{I18n.t("headmin.filters.operators.is_not_null")}"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class OptionsView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def collection
|
17
|
+
@collection || []
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def id
|
23
|
+
"#{name}_value"
|
24
|
+
end
|
25
|
+
|
26
|
+
def name
|
27
|
+
@name || attribute
|
28
|
+
end
|
29
|
+
|
30
|
+
def label
|
31
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_base_options
|
35
|
+
{
|
36
|
+
label: label,
|
37
|
+
name: attribute,
|
38
|
+
display_values: collection,
|
39
|
+
filter: Headmin::Filter::Text.new(name, @params),
|
40
|
+
allowed_operators: Headmin::Filter::Text::OPERATORS - %w[starts_with ends_with in not_in]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_input_options
|
45
|
+
{
|
46
|
+
label: false,
|
47
|
+
wrapper: false,
|
48
|
+
id: id,
|
49
|
+
data: {
|
50
|
+
action: "change->filter#updateHiddenValue",
|
51
|
+
filter_target: "value",
|
52
|
+
filter_row_target: "original"
|
53
|
+
},
|
54
|
+
collection: collection,
|
55
|
+
selected: selected,
|
56
|
+
class: "form-select"
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class Search < Headmin::Filter::Base
|
4
|
+
def query(collection)
|
5
|
+
return collection unless @instructions.any?
|
6
|
+
collection.search(raw_value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def cast_value(value)
|
10
|
+
value
|
11
|
+
end
|
12
|
+
|
13
|
+
def display_value(value)
|
14
|
+
value.downcase
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class SearchView < ViewModel
|
4
|
+
def input_options
|
5
|
+
keys = attributes - %i[params]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
options = default_input_options.merge(options)
|
8
|
+
options.merge(label: false)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def default_input_options
|
14
|
+
{
|
15
|
+
name: name,
|
16
|
+
value: params[name],
|
17
|
+
wrapper: false,
|
18
|
+
placeholder: placeholder
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name || attribute || :search
|
24
|
+
end
|
25
|
+
|
26
|
+
def placeholder
|
27
|
+
@placeholder || I18n.t("headmin.filters.search.placeholder", resource: label)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class Text < Headmin::Filter::Base
|
4
|
+
OPERATORS = %w[eq not_eq in not_in matches does_not_match starts_with ends_with is_null is_not_null starts_with ends_with]
|
5
|
+
|
6
|
+
def cast_value(value)
|
7
|
+
value
|
8
|
+
end
|
9
|
+
|
10
|
+
def display_value(value)
|
11
|
+
value.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def convert_to_ends(value)
|
17
|
+
"%#{value}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert_to_starts(value)
|
21
|
+
"#{value}%"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Filter
|
3
|
+
class TextView < ViewModel
|
4
|
+
def base_options
|
5
|
+
keys = %i[name label form]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_base_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def input_options
|
11
|
+
keys = %i[form]
|
12
|
+
options = to_h.slice(*keys)
|
13
|
+
default_input_options.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def id
|
19
|
+
"#{name}_value"
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name || attribute
|
24
|
+
end
|
25
|
+
|
26
|
+
def label
|
27
|
+
@label || I18n.t("attributes.#{attribute}", default: name.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_base_options
|
31
|
+
{
|
32
|
+
label: label,
|
33
|
+
name: attribute,
|
34
|
+
filter: Headmin::Filter::Text.new(name, @params),
|
35
|
+
allowed_operators: Headmin::Filter::Text::OPERATORS - %w[in not_in]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_input_options
|
40
|
+
{
|
41
|
+
label: false,
|
42
|
+
wrapper: false,
|
43
|
+
id: id,
|
44
|
+
data: {
|
45
|
+
action: "change->filter#updateHiddenValue",
|
46
|
+
filter_target: "value",
|
47
|
+
filter_row_target: "original"
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Headmin
|
2
|
+
class Filters
|
3
|
+
# Example:
|
4
|
+
#
|
5
|
+
# @orders = Headmin::Filters.new(params, {
|
6
|
+
# status: :text,
|
7
|
+
# price: :number,
|
8
|
+
# in_stock: :boolean
|
9
|
+
# }).query(Order)
|
10
|
+
|
11
|
+
def initialize(params, param_types)
|
12
|
+
@params = params
|
13
|
+
@param_types = param_types
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(attribute, type)
|
17
|
+
class_name = "Headmin::Filter::#{type.to_s.classify}".constantize
|
18
|
+
class_name.new(attribute, @params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def query(collection)
|
22
|
+
@param_types.each do |attribute, type|
|
23
|
+
filter = parse(attribute, type)
|
24
|
+
collection = filter.query(collection)
|
25
|
+
end
|
26
|
+
collection
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -17,7 +17,7 @@ module Headmin
|
|
17
17
|
def input_options
|
18
18
|
keys = attributes - %i[attribute form label validate wrapper checked_value unchecked_value]
|
19
19
|
options = to_h.slice(*keys)
|
20
|
-
default_input_options.
|
20
|
+
default_input_options.deep_merge(options)
|
21
21
|
end
|
22
22
|
|
23
23
|
def label_options
|
@@ -31,11 +31,11 @@ module Headmin
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def wrapper_options
|
34
|
-
default_wrapper_options.
|
34
|
+
default_wrapper_options.deep_merge(
|
35
35
|
{
|
36
36
|
class: %w[form-check mb-3]
|
37
37
|
}
|
38
|
-
).
|
38
|
+
).deep_merge(@wrapper || {})
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
@@ -2,11 +2,11 @@ module Headmin
|
|
2
2
|
module Form
|
3
3
|
class DateRangeView < ViewModel
|
4
4
|
def start_options
|
5
|
-
default_start_options.
|
5
|
+
default_start_options.deep_merge(@start || {})
|
6
6
|
end
|
7
7
|
|
8
8
|
def end_options
|
9
|
-
default_end_options.
|
9
|
+
default_end_options.deep_merge(@end || {})
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -12,19 +12,19 @@ module Headmin
|
|
12
12
|
def input_options
|
13
13
|
keys = attributes - %i[append attribute float form input_group input_group label prepend validate wrapper]
|
14
14
|
options = to_h.slice(*keys)
|
15
|
-
default_input_options.
|
15
|
+
default_input_options.deep_merge(options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def input_group_options
|
19
19
|
default_input_group_options
|
20
|
-
.
|
21
|
-
.
|
20
|
+
.deep_merge(label_input_group_options)
|
21
|
+
.deep_merge(@input_group || {})
|
22
22
|
end
|
23
23
|
|
24
24
|
def wrapper_options
|
25
|
-
default_wrapper_options.
|
25
|
+
default_wrapper_options.deep_merge({
|
26
26
|
class: ["mb-3", ("form-floating" if float)]
|
27
|
-
}).
|
27
|
+
}).deep_merge(@wrapper || {})
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|