headmin 0.3.2 → 0.4.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/.github/workflows/ci.yml +27 -0
- data/.gitignore +14 -0
- data/.nvmrc +1 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile +8 -5
- data/Gemfile.lock +197 -25
- data/README.md +9 -1
- data/Rakefile +1 -7
- data/app/assets/images/document.docx +0 -0
- data/app/assets/images/document.pdf +0 -0
- data/app/assets/images/image.jpg +0 -0
- data/app/assets/images/spreadsheet.xls +0 -0
- data/app/assets/images/video.mp4 +0 -0
- data/app/assets/javascripts/headmin/config/i18n.js +9 -9
- data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +255 -0
- data/app/assets/javascripts/headmin/controllers/blocks_controller.js +74 -79
- data/app/assets/javascripts/headmin/controllers/date_range_controller.js +24 -24
- data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +23 -25
- data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +237 -237
- data/app/assets/javascripts/headmin/controllers/filter_controller.js +44 -44
- data/app/assets/javascripts/headmin/controllers/filters_controller.js +57 -61
- data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +29 -29
- data/app/assets/javascripts/headmin/controllers/hello_controller.js +3 -3
- data/app/assets/javascripts/headmin/controllers/notification_controller.js +7 -6
- data/app/assets/javascripts/headmin/controllers/popup_controller.js +51 -52
- data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +36 -9
- data/app/assets/javascripts/headmin/controllers/repeater_controller.js +122 -125
- data/app/assets/javascripts/headmin/controllers/select_controller.js +40 -39
- data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +88 -77
- data/app/assets/javascripts/headmin/controllers/table_controller.js +103 -89
- data/app/assets/javascripts/headmin/index.js +38 -39
- data/app/assets/javascripts/headmin.js +287 -732
- data/app/assets/stylesheets/headmin/forms/autocomplete.scss +21 -0
- data/app/assets/stylesheets/headmin/forms/file.scss +46 -0
- data/app/assets/stylesheets/headmin/forms/repeater.scss +62 -0
- data/app/assets/stylesheets/headmin/forms/search.scss +12 -0
- data/app/assets/stylesheets/headmin/forms.scss +11 -0
- data/app/assets/stylesheets/headmin/general.scss +5 -0
- data/app/assets/stylesheets/headmin/overrides/bootstrap.scss +5 -3
- data/app/assets/stylesheets/headmin/overrides/redactorx.scss +74 -0
- data/app/assets/stylesheets/headmin/popup.scss +1 -0
- data/app/assets/stylesheets/headmin/syntax.scss +36 -349
- data/app/assets/stylesheets/headmin/table.scss +1 -1
- data/app/assets/stylesheets/headmin/utilities/buttons.scss +19 -0
- data/app/assets/stylesheets/headmin/utilities/dropzone.scss +72 -0
- data/app/assets/stylesheets/headmin/utilities.scss +2 -68
- data/app/assets/stylesheets/headmin/vendor/tom-select-bootstrap.css +1 -2
- data/app/assets/stylesheets/headmin.css +206 -206
- data/app/assets/stylesheets/headmin.scss +1 -1
- data/app/controllers/concerns/headmin/authentication.rb +1 -1
- data/app/controllers/concerns/headmin/searchable.rb +1 -1
- data/app/controllers/concerns/headmin/sortable.rb +7 -7
- data/app/helpers/headmin/admin_helper.rb +1 -2
- data/app/helpers/headmin/bootstrap_helper.rb +2 -24
- data/app/helpers/headmin/filter_helper.rb +1 -1
- data/app/helpers/headmin/form_helper.rb +5 -11
- data/app/helpers/headmin/notification_helper.rb +21 -21
- data/app/helpers/headmin/request_helper.rb +3 -3
- data/app/models/concerns/headmin/block.rb +1 -2
- data/app/models/concerns/headmin/blockable.rb +2 -2
- data/app/models/concerns/headmin/field.rb +2 -1
- data/app/models/concerns/headmin/fieldable.rb +8 -8
- data/app/models/concerns/headmin/form/autocompletable.rb +38 -0
- data/app/models/concerns/headmin/form/hintable.rb +19 -0
- data/app/models/concerns/headmin/form/input_groupable.rb +23 -0
- data/app/models/concerns/headmin/form/labelable.rb +33 -0
- data/app/models/concerns/headmin/form/listable.rb +28 -0
- data/app/models/concerns/headmin/form/placeholderable.rb +13 -0
- data/app/models/concerns/headmin/form/validatable.rb +40 -0
- data/app/models/concerns/headmin/form/wrappable.rb +21 -0
- data/app/models/headmin/.DS_Store +0 -0
- data/app/models/headmin/blocks_view.rb +15 -0
- data/app/models/headmin/form/blocks_view.rb +29 -0
- data/app/models/headmin/form/checkbox_view.rb +52 -0
- data/app/models/headmin/form/date_range_view.rb +25 -0
- data/app/models/headmin/form/date_view.rb +45 -0
- data/app/models/headmin/form/email_view.rb +48 -0
- data/app/models/headmin/form/file_view.rb +116 -0
- data/app/models/headmin/form/flatpickr_range_view.rb +102 -0
- data/app/models/headmin/form/flatpickr_view.rb +37 -0
- data/app/models/headmin/form/hidden_view.rb +10 -0
- data/app/models/headmin/form/hint_view.rb +6 -0
- data/app/models/headmin/form/input_group_view.rb +19 -0
- data/app/models/headmin/form/label_view.rb +24 -0
- data/app/models/headmin/form/number_view.rb +49 -0
- data/app/models/headmin/form/password_view.rb +44 -0
- data/app/models/headmin/form/redactorx_view.rb +59 -0
- data/app/models/headmin/form/search_view.rb +48 -0
- data/app/models/headmin/form/select_view.rb +62 -0
- data/app/models/headmin/form/switch_view.rb +23 -0
- data/app/models/headmin/form/text_view.rb +48 -0
- data/app/models/headmin/form/textarea_view.rb +44 -0
- data/app/models/headmin/form/url_view.rb +48 -0
- data/app/models/headmin/form/wrapper_view.rb +19 -0
- data/app/models/headmin/form/wysiwyg_view.rb +17 -0
- data/app/models/headmin/thumbnail_view.rb +66 -0
- data/app/models/view_model.rb +58 -0
- data/app/views/headmin/_blocks.html.erb +13 -9
- data/app/views/headmin/_heading.html.erb +7 -1
- data/app/views/headmin/_thumbnail.html.erb +5 -39
- data/app/views/headmin/dropdown/_item.html.erb +1 -1
- data/app/views/headmin/forms/_autocomplete.html.erb +11 -0
- data/app/views/headmin/forms/_blocks.html.erb +16 -17
- data/app/views/headmin/forms/_checkbox.html.erb +24 -29
- data/app/views/headmin/forms/_datalist.html.erb +3 -0
- data/app/views/headmin/forms/_date.html.erb +24 -24
- data/app/views/headmin/forms/_date_range.html.erb +19 -21
- data/app/views/headmin/forms/_email.html.erb +27 -32
- data/app/views/headmin/forms/_errors.html.erb +2 -3
- data/app/views/headmin/forms/_file.html.erb +84 -181
- data/app/views/headmin/forms/_flatpickr.html.erb +19 -20
- data/app/views/headmin/forms/_flatpickr_range.html.erb +28 -37
- data/app/views/headmin/forms/_hidden.html.erb +9 -10
- data/app/views/headmin/forms/_hint.html.erb +16 -0
- data/app/views/headmin/forms/_input_group.html.erb +21 -0
- data/app/views/headmin/forms/_label.html.erb +5 -13
- data/app/views/headmin/forms/_number.html.erb +23 -35
- data/app/views/headmin/forms/_password.html.erb +21 -30
- data/app/views/headmin/forms/_redactorx.html.erb +21 -40
- data/app/views/headmin/forms/_repeater.html.erb +55 -60
- data/app/views/headmin/forms/_search.html.erb +43 -0
- data/app/views/headmin/forms/_select.html.erb +24 -49
- data/app/views/headmin/forms/_switch.html.erb +29 -0
- data/app/views/headmin/forms/_text.html.erb +42 -96
- data/app/views/headmin/forms/_textarea.html.erb +21 -32
- data/app/views/headmin/forms/_url.html.erb +26 -31
- data/app/views/headmin/forms/_validation.html.erb +10 -13
- data/app/views/headmin/forms/_wrapper.html.erb +9 -0
- data/app/views/headmin/forms/_wysiwyg.html.erb +28 -0
- data/app/views/headmin/forms/autocomplete/_item.html.erb +3 -0
- data/app/views/headmin/forms/autocomplete/_list.html.erb +3 -0
- data/app/views/headmin/forms/fields/_group.html.erb +6 -4
- data/app/views/headmin/forms/repeater/_row.html.erb +4 -4
- data/app/views/headmin/nav/item/_devise.html.erb +1 -1
- data/app/views/headmin/table/_actions.html.erb +1 -1
- data/app/views/headmin/table/actions/_action.html.erb +2 -1
- data/app/views/headmin/table/actions/_delete.html.erb +1 -1
- data/app/views/headmin/views/devise/registrations/_edit.html.erb +2 -2
- data/bin/console +0 -1
- data/config/initializers/customize_input_error.rb +4 -4
- data/config/locales/headmin/forms/en.yml +0 -11
- data/config/locales/headmin/forms/nl.yml +0 -11
- data/esbuild-css.js +18 -18
- data/esbuild-js.js +8 -8
- data/headmin.gemspec +1 -3
- data/lib/generators/headmin/blocks_generator.rb +8 -8
- data/lib/generators/headmin/devise_generator.rb +4 -4
- data/lib/generators/headmin/fields_generator.rb +9 -9
- data/lib/generators/templates/controllers/auth/confirmations_controller.rb +1 -3
- data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +1 -3
- data/lib/generators/templates/controllers/auth/passwords_controller.rb +1 -3
- data/lib/generators/templates/controllers/auth/registrations_controller.rb +1 -3
- data/lib/generators/templates/controllers/auth/sessions_controller.rb +1 -3
- data/lib/generators/templates/controllers/auth/unlocks_controller.rb +1 -3
- data/lib/generators/templates/models/block.rb +1 -1
- data/lib/headmin/engine.rb +6 -6
- data/lib/headmin/version.rb +1 -3
- data/lib/headmin.rb +0 -2
- data/package-lock.json +5359 -0
- data/package.json +13 -7
- data/view_model_benchmark.rb +74 -0
- data/yarn-error.log +367 -0
- data/yarn.lock +1448 -161
- metadata +69 -25
- data/.rubocop.yml +0 -13
- data/app/assets/stylesheets/headmin/form.scss +0 -132
- data/app/assets/stylesheets/headmin/overrides/redactorx.css +0 -3
- data/app/helpers/headmin/documentation_helper.rb +0 -35
- data/app/models/headmin/documentation_renderer.rb +0 -32
- data/app/models/headmin/form/base.rb +0 -79
- data/app/models/headmin/form/text.rb +0 -53
- data/app/services/block_service.rb +0 -72
- data/app/views/headmin/_card.html.erb +0 -52
- data/app/views/headmin/forms/_actions.html.erb +0 -28
- data/app/views/headmin/forms/_base.html.erb +0 -114
- data/app/views/headmin/forms/_image.html.erb +0 -21
- data/app/views/headmin/forms/_video.html.erb +0 -21
- data/app/views/headmin/forms/actions/_destroy.html.erb +0 -13
- data/app/views/headmin/forms/actions/_save.html.erb +0 -12
- data/app/views/headmin/forms/actions/_view.html.erb +0 -15
- data/docs/blocks-and-fields.md +0 -54
- data/docs/blocks.md +0 -48
- data/docs/devise.md +0 -41
- data/docs/fields.md +0 -79
@@ -12,8 +12,8 @@ module Headmin
|
|
12
12
|
|
13
13
|
def sort_by_params(collection)
|
14
14
|
sort_params.each do |key, value|
|
15
|
-
next unless %w
|
16
|
-
attribute = key.gsub(
|
15
|
+
next unless %w[asc desc].include?(value)
|
16
|
+
attribute = key.gsub("sort_", "")
|
17
17
|
|
18
18
|
# Sort on model columns first, then check for translation columns
|
19
19
|
if collection.attribute_names.include?(attribute.to_s)
|
@@ -26,19 +26,19 @@ module Headmin
|
|
26
26
|
|
27
27
|
order_scope = "order_by_#{attribute}".to_sym
|
28
28
|
sort_scope = "sort_by_#{attribute}".to_sym
|
29
|
-
if collection.respond_to?(order_scope)
|
30
|
-
collection
|
29
|
+
collection = if collection.respond_to?(order_scope)
|
30
|
+
collection.send(order_scope, value)
|
31
31
|
elsif collection.respond_to?(sort_scope)
|
32
|
-
collection
|
32
|
+
collection.send(sort_scope, value)
|
33
33
|
else
|
34
|
-
collection
|
34
|
+
collection.order(column.send(value))
|
35
35
|
end
|
36
36
|
end
|
37
37
|
collection
|
38
38
|
end
|
39
39
|
|
40
40
|
def sort_params
|
41
|
-
params.permit!.select { |p| p.to_s.include?(
|
41
|
+
params.permit!.select { |p| p.to_s.include?("sort_") }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -2,30 +2,8 @@ module Headmin
|
|
2
2
|
module BootstrapHelper
|
3
3
|
def bootstrap_icon(icon, options = {})
|
4
4
|
tag_name = options.extract!(:tag_name).fetch(:tag_name, :i)
|
5
|
-
options[:class] = [
|
5
|
+
options[:class] = ["bi", "bi-#{icon}", options.dig(:class)].compact.join(" ")
|
6
6
|
content_tag(tag_name, options) {}
|
7
7
|
end
|
8
|
-
|
9
|
-
# References
|
10
|
-
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
11
|
-
def bootstrap_icon_for_mime_type(mime_type, options = {})
|
12
|
-
type_map = {
|
13
|
-
image: %w[image/bmp image/gif image/vnd.microsoft.icon image/jpeg image/png image/svg+xml image/tiff image/webp],
|
14
|
-
play: %w[video/mp4 video/mpeg video/ogg video/mp2t video/webm video/3gpp video/3gpp2],
|
15
|
-
music: %w[audio/aac audio/midi audio/x-midi audio/mpeg audio/ogg audio/opus audio/wav audio/webm audio/3gpp audio/3gpp2],
|
16
|
-
word: %w[application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document],
|
17
|
-
ppt: %w[application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation],
|
18
|
-
excel: %w[application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet],
|
19
|
-
slides: %w[application/vnd.oasis.opendocument.presentation],
|
20
|
-
spreadsheet: %w[application/vnd.oasis.opendocument.spreadsheet],
|
21
|
-
richtext: %w[application/vnd.oasis.opendocument.text],
|
22
|
-
zip: %w[application/zip application/x-7z-compressed application/x-bzip application/x-bzip2 application/gzip application/vnd.rar],
|
23
|
-
pdf: %w[application/pdf],
|
24
|
-
}
|
25
|
-
icon_name = type_map.find{|key, mime_types| mime_types.include?(mime_type)}.first
|
26
|
-
|
27
|
-
icon = ['file', 'earmark', icon_name].compact.join('-')
|
28
|
-
bootstrap_icon(icon, options)
|
29
|
-
end
|
30
8
|
end
|
31
|
-
end
|
9
|
+
end
|
@@ -1,20 +1,14 @@
|
|
1
1
|
module Headmin
|
2
2
|
module FormHelper
|
3
|
-
|
4
|
-
!form.object.errors.has_key?(name)
|
5
|
-
end
|
6
|
-
|
3
|
+
# TODO: cleanup after input field refactoring
|
7
4
|
def form_field_validation_id(form, name)
|
8
|
-
[form.object_name, name.to_s,
|
5
|
+
[form.object_name, name.to_s, "validation"].join("_").parameterize.underscore
|
9
6
|
end
|
10
7
|
|
8
|
+
# TODO: cleanup after input field refactoring
|
11
9
|
def form_field_validation_class(form, name)
|
12
10
|
return nil if request.get?
|
13
|
-
form.object.errors.has_key?(name) ?
|
14
|
-
end
|
15
|
-
|
16
|
-
def human_attribute_name(attribute)
|
17
|
-
attribute.to_s.humanize
|
11
|
+
form.object.errors.has_key?(name) ? "is-invalid" : "is-valid"
|
18
12
|
end
|
19
13
|
|
20
14
|
# Outputs currently present query parameters as hidden fields for a given form
|
@@ -37,4 +31,4 @@ module Headmin
|
|
37
31
|
test.join.html_safe
|
38
32
|
end
|
39
33
|
end
|
40
|
-
end
|
34
|
+
end
|
@@ -2,30 +2,30 @@ module Headmin
|
|
2
2
|
module NotificationHelper
|
3
3
|
def notification_color(name)
|
4
4
|
color = {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
notice: {
|
6
|
+
background: "bg-success",
|
7
|
+
text: "text-white"
|
8
|
+
},
|
9
|
+
error: {
|
10
|
+
text: "text-dark",
|
11
|
+
background: "bg-danger"
|
12
|
+
},
|
13
|
+
alert: {
|
14
|
+
text: "text-dark",
|
15
|
+
background: "bg-warning"
|
16
|
+
},
|
17
|
+
timedout: {
|
18
|
+
text: "text-dark",
|
19
|
+
background: "bg-warning"
|
20
|
+
},
|
21
|
+
fallback: {
|
22
|
+
text: "text-light",
|
23
|
+
background: "bg-info"
|
24
|
+
}
|
25
25
|
}
|
26
26
|
|
27
27
|
name = name.to_sym
|
28
28
|
color.key?(name) ? color[name] : color[:fallback]
|
29
29
|
end
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
@@ -3,7 +3,7 @@ module Headmin
|
|
3
3
|
def current_url?(url)
|
4
4
|
uri = URI(url)
|
5
5
|
path = uri.path
|
6
|
-
query_string = uri.query ||
|
6
|
+
query_string = uri.query || ""
|
7
7
|
matches_path = request.path.include?(path)
|
8
8
|
matches_query = request.query_string.include?(query_string)
|
9
9
|
matches_path && matches_query
|
@@ -28,7 +28,7 @@ module Headmin
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def is_sort_param_key?(key)
|
31
|
-
key.to_s.include?(
|
31
|
+
key.to_s.include?("sort_")
|
32
32
|
end
|
33
33
|
end
|
34
|
-
end
|
34
|
+
end
|
@@ -24,27 +24,27 @@ module Headmin
|
|
24
24
|
when Hash
|
25
25
|
fields.build(
|
26
26
|
name: key,
|
27
|
-
field_type:
|
27
|
+
field_type: "group",
|
28
28
|
fields: parse_fields_hash(value)
|
29
29
|
)
|
30
30
|
when Array
|
31
31
|
fields.build(
|
32
32
|
name: key,
|
33
|
-
field_type:
|
33
|
+
field_type: "list",
|
34
34
|
fields: value.map do |item|
|
35
|
-
fields.new(name:
|
35
|
+
fields.new(name: "item", field_type: "group", fields: parse_fields_hash(item))
|
36
36
|
end
|
37
37
|
)
|
38
38
|
when String
|
39
39
|
fields.build(
|
40
40
|
name: key,
|
41
|
-
field_type:
|
41
|
+
field_type: "text",
|
42
42
|
value: value
|
43
43
|
)
|
44
44
|
else
|
45
45
|
fields.build(
|
46
46
|
name: key,
|
47
|
-
field_type:
|
47
|
+
field_type: "file",
|
48
48
|
file: value
|
49
49
|
)
|
50
50
|
end
|
@@ -52,7 +52,7 @@ module Headmin
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def parse_hash_tree(hash_tree)
|
55
|
-
|
55
|
+
hash_tree.map do |field, children|
|
56
56
|
case field.field_type.to_sym
|
57
57
|
when :group
|
58
58
|
children = children.any? ? children : field.hash_tree
|
@@ -67,8 +67,8 @@ module Headmin
|
|
67
67
|
else
|
68
68
|
[field.name, field.value]
|
69
69
|
end
|
70
|
-
end
|
70
|
+
end.to_h
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
-
end
|
74
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module Autocompletable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def autocomplete?
|
8
|
+
collection.is_a?(String) || collection.is_a?(Array)
|
9
|
+
end
|
10
|
+
|
11
|
+
def autocomplete_options
|
12
|
+
{
|
13
|
+
collection: collection.is_a?(Array) ? collection : []
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def autocomplete_input_options
|
18
|
+
{
|
19
|
+
data: {
|
20
|
+
autocomplete_target: autocomplete? ? "input" : nil
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def autocomplete_input_group_options
|
26
|
+
options = {
|
27
|
+
data: {
|
28
|
+
controller: autocomplete? ? "autocomplete" : nil,
|
29
|
+
autocomplete_url_value: collection.is_a?(String) ? collection : nil
|
30
|
+
}
|
31
|
+
}
|
32
|
+
options = options.merge(bypass: false) if autocomplete?
|
33
|
+
options
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module InputGroupable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def input_group_options
|
8
|
+
default_input_group_options.merge(@input_group || {})
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def default_input_group_options
|
14
|
+
{
|
15
|
+
bypass: !(prepend || append || @input_group),
|
16
|
+
prepend: prepend,
|
17
|
+
append: append
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module Labelable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
def label?
|
7
|
+
label != false
|
8
|
+
end
|
9
|
+
|
10
|
+
def prepend_label?
|
11
|
+
label != false && !float
|
12
|
+
end
|
13
|
+
|
14
|
+
def append_label?
|
15
|
+
label != false && float
|
16
|
+
end
|
17
|
+
|
18
|
+
def label_input_group_options
|
19
|
+
float ? {bypass: true} : {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def label_options
|
23
|
+
{
|
24
|
+
attribute: attribute,
|
25
|
+
form: form,
|
26
|
+
required: required,
|
27
|
+
text: label
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module Listable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def list
|
8
|
+
datalist_id if @list
|
9
|
+
end
|
10
|
+
|
11
|
+
def datalist?
|
12
|
+
@list.present?
|
13
|
+
end
|
14
|
+
|
15
|
+
def datalist_options
|
16
|
+
{
|
17
|
+
collection: @list,
|
18
|
+
id: datalist_id
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def datalist_id
|
23
|
+
"#{attribute}_list"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module Validatable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def validation_options
|
8
|
+
{
|
9
|
+
id: validation_id,
|
10
|
+
message: validation_message,
|
11
|
+
valid: valid?
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate?
|
16
|
+
form.object&.errors&.any?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def valid?
|
22
|
+
!form.object&.errors&.has_key?(attribute)
|
23
|
+
end
|
24
|
+
|
25
|
+
def validation_message
|
26
|
+
form.object&.errors&.full_messages_for(attribute)&.join(", ")
|
27
|
+
end
|
28
|
+
|
29
|
+
def validation_id
|
30
|
+
[attribute.to_s, "validation"].join("_").parameterize.underscore
|
31
|
+
end
|
32
|
+
|
33
|
+
def validation_class
|
34
|
+
return unless validate?
|
35
|
+
valid? ? "is-valid" : "is-invalid"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
module Wrappable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def wrapper_options
|
8
|
+
default_wrapper_options.merge(@wrapper || {})
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def default_wrapper_options
|
14
|
+
{
|
15
|
+
bypass: @wrapper == false
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
class BlocksView < ViewModel
|
4
|
+
def repeater_options
|
5
|
+
keys = %i[form attribute names label]
|
6
|
+
options = to_h.slice(*keys)
|
7
|
+
default_repeater_options.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def paths
|
11
|
+
@paths || []
|
12
|
+
end
|
13
|
+
|
14
|
+
def prefixes
|
15
|
+
paths + ["admin/blocks", "blocks", ""]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def default_repeater_options
|
21
|
+
{
|
22
|
+
attribute: "blocks",
|
23
|
+
label: false,
|
24
|
+
templates: names
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
class CheckboxView < ViewModel
|
4
|
+
include Headmin::Form::Hintable
|
5
|
+
include Headmin::Form::Labelable
|
6
|
+
include Headmin::Form::Validatable
|
7
|
+
include Headmin::Form::Wrappable
|
8
|
+
|
9
|
+
def checked_value
|
10
|
+
@checked_value || "1"
|
11
|
+
end
|
12
|
+
|
13
|
+
def unchecked_value
|
14
|
+
@unchecked_value || "0"
|
15
|
+
end
|
16
|
+
|
17
|
+
def input_options
|
18
|
+
keys = attributes - %i[attribute form label validate wrapper checked_value unchecked_value]
|
19
|
+
options = to_h.slice(*keys)
|
20
|
+
default_input_options.merge(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def label_options
|
24
|
+
{
|
25
|
+
class: ["form-check-label"],
|
26
|
+
attribute: attribute,
|
27
|
+
form: form,
|
28
|
+
required: required,
|
29
|
+
text: label
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def wrapper_options
|
34
|
+
default_wrapper_options.merge(
|
35
|
+
{
|
36
|
+
class: %w[form-check mb-3]
|
37
|
+
}
|
38
|
+
).merge(@wrapper || {})
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def default_input_options
|
44
|
+
{
|
45
|
+
aria: {describedby: validation_id},
|
46
|
+
class: ["form-check-input", validation_class],
|
47
|
+
placeholder: placeholder
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
class DateRangeView < ViewModel
|
4
|
+
def start_options
|
5
|
+
default_start_options.merge(@start || {})
|
6
|
+
end
|
7
|
+
|
8
|
+
def end_options
|
9
|
+
default_end_options.merge(@end || {})
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def default_start_options
|
15
|
+
keys = attributes - %i[start]
|
16
|
+
to_h.slice(*keys)
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_end_options
|
20
|
+
keys = attributes - %i[end]
|
21
|
+
to_h.slice(*keys)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|