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.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.gitignore +14 -0
  4. data/.nvmrc +1 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +24 -0
  7. data/Gemfile +8 -5
  8. data/Gemfile.lock +197 -25
  9. data/README.md +9 -1
  10. data/Rakefile +1 -7
  11. data/app/assets/images/document.docx +0 -0
  12. data/app/assets/images/document.pdf +0 -0
  13. data/app/assets/images/image.jpg +0 -0
  14. data/app/assets/images/spreadsheet.xls +0 -0
  15. data/app/assets/images/video.mp4 +0 -0
  16. data/app/assets/javascripts/headmin/config/i18n.js +9 -9
  17. data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +255 -0
  18. data/app/assets/javascripts/headmin/controllers/blocks_controller.js +74 -79
  19. data/app/assets/javascripts/headmin/controllers/date_range_controller.js +24 -24
  20. data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +23 -25
  21. data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +237 -237
  22. data/app/assets/javascripts/headmin/controllers/filter_controller.js +44 -44
  23. data/app/assets/javascripts/headmin/controllers/filters_controller.js +57 -61
  24. data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +29 -29
  25. data/app/assets/javascripts/headmin/controllers/hello_controller.js +3 -3
  26. data/app/assets/javascripts/headmin/controllers/notification_controller.js +7 -6
  27. data/app/assets/javascripts/headmin/controllers/popup_controller.js +51 -52
  28. data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +36 -9
  29. data/app/assets/javascripts/headmin/controllers/repeater_controller.js +122 -125
  30. data/app/assets/javascripts/headmin/controllers/select_controller.js +40 -39
  31. data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +88 -77
  32. data/app/assets/javascripts/headmin/controllers/table_controller.js +103 -89
  33. data/app/assets/javascripts/headmin/index.js +38 -39
  34. data/app/assets/javascripts/headmin.js +287 -732
  35. data/app/assets/stylesheets/headmin/forms/autocomplete.scss +21 -0
  36. data/app/assets/stylesheets/headmin/forms/file.scss +46 -0
  37. data/app/assets/stylesheets/headmin/forms/repeater.scss +62 -0
  38. data/app/assets/stylesheets/headmin/forms/search.scss +12 -0
  39. data/app/assets/stylesheets/headmin/forms.scss +11 -0
  40. data/app/assets/stylesheets/headmin/general.scss +5 -0
  41. data/app/assets/stylesheets/headmin/overrides/bootstrap.scss +5 -3
  42. data/app/assets/stylesheets/headmin/overrides/redactorx.scss +74 -0
  43. data/app/assets/stylesheets/headmin/popup.scss +1 -0
  44. data/app/assets/stylesheets/headmin/syntax.scss +36 -349
  45. data/app/assets/stylesheets/headmin/table.scss +1 -1
  46. data/app/assets/stylesheets/headmin/utilities/buttons.scss +19 -0
  47. data/app/assets/stylesheets/headmin/utilities/dropzone.scss +72 -0
  48. data/app/assets/stylesheets/headmin/utilities.scss +2 -68
  49. data/app/assets/stylesheets/headmin/vendor/tom-select-bootstrap.css +1 -2
  50. data/app/assets/stylesheets/headmin.css +206 -206
  51. data/app/assets/stylesheets/headmin.scss +1 -1
  52. data/app/controllers/concerns/headmin/authentication.rb +1 -1
  53. data/app/controllers/concerns/headmin/searchable.rb +1 -1
  54. data/app/controllers/concerns/headmin/sortable.rb +7 -7
  55. data/app/helpers/headmin/admin_helper.rb +1 -2
  56. data/app/helpers/headmin/bootstrap_helper.rb +2 -24
  57. data/app/helpers/headmin/filter_helper.rb +1 -1
  58. data/app/helpers/headmin/form_helper.rb +5 -11
  59. data/app/helpers/headmin/notification_helper.rb +21 -21
  60. data/app/helpers/headmin/request_helper.rb +3 -3
  61. data/app/models/concerns/headmin/block.rb +1 -2
  62. data/app/models/concerns/headmin/blockable.rb +2 -2
  63. data/app/models/concerns/headmin/field.rb +2 -1
  64. data/app/models/concerns/headmin/fieldable.rb +8 -8
  65. data/app/models/concerns/headmin/form/autocompletable.rb +38 -0
  66. data/app/models/concerns/headmin/form/hintable.rb +19 -0
  67. data/app/models/concerns/headmin/form/input_groupable.rb +23 -0
  68. data/app/models/concerns/headmin/form/labelable.rb +33 -0
  69. data/app/models/concerns/headmin/form/listable.rb +28 -0
  70. data/app/models/concerns/headmin/form/placeholderable.rb +13 -0
  71. data/app/models/concerns/headmin/form/validatable.rb +40 -0
  72. data/app/models/concerns/headmin/form/wrappable.rb +21 -0
  73. data/app/models/headmin/.DS_Store +0 -0
  74. data/app/models/headmin/blocks_view.rb +15 -0
  75. data/app/models/headmin/form/blocks_view.rb +29 -0
  76. data/app/models/headmin/form/checkbox_view.rb +52 -0
  77. data/app/models/headmin/form/date_range_view.rb +25 -0
  78. data/app/models/headmin/form/date_view.rb +45 -0
  79. data/app/models/headmin/form/email_view.rb +48 -0
  80. data/app/models/headmin/form/file_view.rb +116 -0
  81. data/app/models/headmin/form/flatpickr_range_view.rb +102 -0
  82. data/app/models/headmin/form/flatpickr_view.rb +37 -0
  83. data/app/models/headmin/form/hidden_view.rb +10 -0
  84. data/app/models/headmin/form/hint_view.rb +6 -0
  85. data/app/models/headmin/form/input_group_view.rb +19 -0
  86. data/app/models/headmin/form/label_view.rb +24 -0
  87. data/app/models/headmin/form/number_view.rb +49 -0
  88. data/app/models/headmin/form/password_view.rb +44 -0
  89. data/app/models/headmin/form/redactorx_view.rb +59 -0
  90. data/app/models/headmin/form/search_view.rb +48 -0
  91. data/app/models/headmin/form/select_view.rb +62 -0
  92. data/app/models/headmin/form/switch_view.rb +23 -0
  93. data/app/models/headmin/form/text_view.rb +48 -0
  94. data/app/models/headmin/form/textarea_view.rb +44 -0
  95. data/app/models/headmin/form/url_view.rb +48 -0
  96. data/app/models/headmin/form/wrapper_view.rb +19 -0
  97. data/app/models/headmin/form/wysiwyg_view.rb +17 -0
  98. data/app/models/headmin/thumbnail_view.rb +66 -0
  99. data/app/models/view_model.rb +58 -0
  100. data/app/views/headmin/_blocks.html.erb +13 -9
  101. data/app/views/headmin/_heading.html.erb +7 -1
  102. data/app/views/headmin/_thumbnail.html.erb +5 -39
  103. data/app/views/headmin/dropdown/_item.html.erb +1 -1
  104. data/app/views/headmin/forms/_autocomplete.html.erb +11 -0
  105. data/app/views/headmin/forms/_blocks.html.erb +16 -17
  106. data/app/views/headmin/forms/_checkbox.html.erb +24 -29
  107. data/app/views/headmin/forms/_datalist.html.erb +3 -0
  108. data/app/views/headmin/forms/_date.html.erb +24 -24
  109. data/app/views/headmin/forms/_date_range.html.erb +19 -21
  110. data/app/views/headmin/forms/_email.html.erb +27 -32
  111. data/app/views/headmin/forms/_errors.html.erb +2 -3
  112. data/app/views/headmin/forms/_file.html.erb +84 -181
  113. data/app/views/headmin/forms/_flatpickr.html.erb +19 -20
  114. data/app/views/headmin/forms/_flatpickr_range.html.erb +28 -37
  115. data/app/views/headmin/forms/_hidden.html.erb +9 -10
  116. data/app/views/headmin/forms/_hint.html.erb +16 -0
  117. data/app/views/headmin/forms/_input_group.html.erb +21 -0
  118. data/app/views/headmin/forms/_label.html.erb +5 -13
  119. data/app/views/headmin/forms/_number.html.erb +23 -35
  120. data/app/views/headmin/forms/_password.html.erb +21 -30
  121. data/app/views/headmin/forms/_redactorx.html.erb +21 -40
  122. data/app/views/headmin/forms/_repeater.html.erb +55 -60
  123. data/app/views/headmin/forms/_search.html.erb +43 -0
  124. data/app/views/headmin/forms/_select.html.erb +24 -49
  125. data/app/views/headmin/forms/_switch.html.erb +29 -0
  126. data/app/views/headmin/forms/_text.html.erb +42 -96
  127. data/app/views/headmin/forms/_textarea.html.erb +21 -32
  128. data/app/views/headmin/forms/_url.html.erb +26 -31
  129. data/app/views/headmin/forms/_validation.html.erb +10 -13
  130. data/app/views/headmin/forms/_wrapper.html.erb +9 -0
  131. data/app/views/headmin/forms/_wysiwyg.html.erb +28 -0
  132. data/app/views/headmin/forms/autocomplete/_item.html.erb +3 -0
  133. data/app/views/headmin/forms/autocomplete/_list.html.erb +3 -0
  134. data/app/views/headmin/forms/fields/_group.html.erb +6 -4
  135. data/app/views/headmin/forms/repeater/_row.html.erb +4 -4
  136. data/app/views/headmin/nav/item/_devise.html.erb +1 -1
  137. data/app/views/headmin/table/_actions.html.erb +1 -1
  138. data/app/views/headmin/table/actions/_action.html.erb +2 -1
  139. data/app/views/headmin/table/actions/_delete.html.erb +1 -1
  140. data/app/views/headmin/views/devise/registrations/_edit.html.erb +2 -2
  141. data/bin/console +0 -1
  142. data/config/initializers/customize_input_error.rb +4 -4
  143. data/config/locales/headmin/forms/en.yml +0 -11
  144. data/config/locales/headmin/forms/nl.yml +0 -11
  145. data/esbuild-css.js +18 -18
  146. data/esbuild-js.js +8 -8
  147. data/headmin.gemspec +1 -3
  148. data/lib/generators/headmin/blocks_generator.rb +8 -8
  149. data/lib/generators/headmin/devise_generator.rb +4 -4
  150. data/lib/generators/headmin/fields_generator.rb +9 -9
  151. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +1 -3
  152. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +1 -3
  153. data/lib/generators/templates/controllers/auth/passwords_controller.rb +1 -3
  154. data/lib/generators/templates/controllers/auth/registrations_controller.rb +1 -3
  155. data/lib/generators/templates/controllers/auth/sessions_controller.rb +1 -3
  156. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +1 -3
  157. data/lib/generators/templates/models/block.rb +1 -1
  158. data/lib/headmin/engine.rb +6 -6
  159. data/lib/headmin/version.rb +1 -3
  160. data/lib/headmin.rb +0 -2
  161. data/package-lock.json +5359 -0
  162. data/package.json +13 -7
  163. data/view_model_benchmark.rb +74 -0
  164. data/yarn-error.log +367 -0
  165. data/yarn.lock +1448 -161
  166. metadata +69 -25
  167. data/.rubocop.yml +0 -13
  168. data/app/assets/stylesheets/headmin/form.scss +0 -132
  169. data/app/assets/stylesheets/headmin/overrides/redactorx.css +0 -3
  170. data/app/helpers/headmin/documentation_helper.rb +0 -35
  171. data/app/models/headmin/documentation_renderer.rb +0 -32
  172. data/app/models/headmin/form/base.rb +0 -79
  173. data/app/models/headmin/form/text.rb +0 -53
  174. data/app/services/block_service.rb +0 -72
  175. data/app/views/headmin/_card.html.erb +0 -52
  176. data/app/views/headmin/forms/_actions.html.erb +0 -28
  177. data/app/views/headmin/forms/_base.html.erb +0 -114
  178. data/app/views/headmin/forms/_image.html.erb +0 -21
  179. data/app/views/headmin/forms/_video.html.erb +0 -21
  180. data/app/views/headmin/forms/actions/_destroy.html.erb +0 -13
  181. data/app/views/headmin/forms/actions/_save.html.erb +0 -12
  182. data/app/views/headmin/forms/actions/_view.html.erb +0 -15
  183. data/docs/blocks-and-fields.md +0 -54
  184. data/docs/blocks.md +0 -48
  185. data/docs/devise.md +0 -41
  186. data/docs/fields.md +0 -79
@@ -0,0 +1,48 @@
1
+ module Headmin
2
+ module Form
3
+ class TextView < ViewModel
4
+ include Headmin::Form::Autocompletable
5
+ include Headmin::Form::Hintable
6
+ include Headmin::Form::InputGroupable
7
+ include Headmin::Form::Labelable
8
+ include Headmin::Form::Listable
9
+ include Headmin::Form::Placeholderable
10
+ include Headmin::Form::Validatable
11
+ include Headmin::Form::Wrappable
12
+
13
+ def input_options
14
+ keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
15
+ options = to_h.slice(*keys)
16
+ options = default_input_options.merge(options)
17
+ options.merge(autocomplete_input_options)
18
+ end
19
+
20
+ def input_group_options
21
+ default_input_group_options
22
+ .merge(autocomplete_input_group_options)
23
+ .merge(label_input_group_options)
24
+ .merge(@input_group || {})
25
+ end
26
+
27
+ def wrapper_options
28
+ default_wrapper_options.merge({
29
+ class: ["mb-3", ("form-floating" if float)]
30
+ }).merge(@wrapper || {})
31
+ end
32
+
33
+ private
34
+
35
+ def default_input_options
36
+ {
37
+ aria: {describedby: validation_id},
38
+ class: [form_control_class, validation_class],
39
+ placeholder: placeholder
40
+ }
41
+ end
42
+
43
+ def form_control_class
44
+ plaintext ? "form-control-plaintext" : "form-control"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ module Headmin
2
+ module Form
3
+ class TextareaView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::InputGroupable
6
+ include Headmin::Form::Labelable
7
+ include Headmin::Form::Placeholderable
8
+ include Headmin::Form::Validatable
9
+ include Headmin::Form::Wrappable
10
+
11
+ def input_options
12
+ keys = attributes - %i[attribute float form input_group label validate wrapper]
13
+ options = to_h.slice(*keys)
14
+ default_input_options.merge(options)
15
+ end
16
+
17
+ def input_group_options
18
+ default_input_group_options
19
+ .merge(label_input_group_options)
20
+ .merge(@input_group || {})
21
+ end
22
+
23
+ def wrapper_options
24
+ default_wrapper_options.merge({
25
+ class: ["mb-3", ("form-floating" if float)]
26
+ }).merge(@wrapper || {})
27
+ end
28
+
29
+ private
30
+
31
+ def default_input_options
32
+ {
33
+ aria: {describedby: validation_id},
34
+ class: [form_control_class, validation_class],
35
+ placeholder: placeholder
36
+ }
37
+ end
38
+
39
+ def form_control_class
40
+ plaintext ? "form-control-plaintext" : "form-control"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ module Headmin
2
+ module Form
3
+ class UrlView < ViewModel
4
+ include Headmin::Form::Autocompletable
5
+ include Headmin::Form::Hintable
6
+ include Headmin::Form::InputGroupable
7
+ include Headmin::Form::Labelable
8
+ include Headmin::Form::Listable
9
+ include Headmin::Form::Placeholderable
10
+ include Headmin::Form::Validatable
11
+ include Headmin::Form::Wrappable
12
+
13
+ def input_options
14
+ keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
15
+ options = to_h.slice(*keys)
16
+ options = default_input_options.merge(options)
17
+ options.merge(autocomplete_input_options)
18
+ end
19
+
20
+ def input_group_options
21
+ default_input_group_options
22
+ .merge(autocomplete_input_group_options)
23
+ .merge(label_input_group_options)
24
+ .merge(@input_group || {})
25
+ end
26
+
27
+ def wrapper_options
28
+ default_wrapper_options.merge({
29
+ class: ["mb-3", ("form-floating" if float)]
30
+ }).merge(@wrapper || {})
31
+ end
32
+
33
+ private
34
+
35
+ def default_input_options
36
+ {
37
+ aria: {describedby: validation_id},
38
+ class: [form_control_class, validation_class],
39
+ placeholder: placeholder
40
+ }
41
+ end
42
+
43
+ def form_control_class
44
+ plaintext ? "form-control-plaintext" : "form-control"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module Headmin
2
+ module Form
3
+ class WrapperView < ViewModel
4
+ def options
5
+ keys = attributes - %i[bypass]
6
+ options = to_h.slice(*keys)
7
+ default_options.merge(options)
8
+ end
9
+
10
+ private
11
+
12
+ def default_options
13
+ {
14
+ class: ["mb-3"]
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Headmin
2
+ module Form
3
+ class WysiwygView < ViewModel
4
+ def options
5
+ default_options.merge(to_h)
6
+ end
7
+
8
+ private
9
+
10
+ def default_options
11
+ {
12
+ hybrid: toolbar == false
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,66 @@
1
+ module Headmin
2
+ class ThumbnailView
3
+ def initialize(local_assigns)
4
+ @local_assigns = local_assigns
5
+ end
6
+
7
+ def class_names
8
+ class_names = [@local_assigns[:class]]
9
+ class_names << "img-thumbnail h-thumbnail"
10
+ class_names.join(" ")
11
+ end
12
+
13
+ def width
14
+ @local_assigns[:width] || 150
15
+ end
16
+
17
+ def height
18
+ @local_assigns[:height] || 150
19
+ end
20
+
21
+ def src
22
+ @local_assigns[:src]
23
+ end
24
+
25
+ def icon
26
+ @local_assigns[:icon]
27
+ end
28
+
29
+ def mime_type
30
+ if src
31
+ stripped_path = URI.parse(src).path
32
+ extension = File.extname(stripped_path)
33
+ Rack::Mime.mime_type(extension)
34
+ end
35
+ end
36
+
37
+ def image?
38
+ mime_type&.match?(/^image/)
39
+ end
40
+
41
+ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
42
+ def icon_name
43
+ return icon if icon
44
+ type_map = {
45
+ image: %w[image/bmp image/gif image/vnd.microsoft.icon image/jpeg image/png image/svg+xml image/tiff image/webp],
46
+ play: %w[video/mp4 video/mpeg video/ogg video/mp2t video/webm video/3gpp video/3gpp2],
47
+ music: %w[audio/aac audio/midi audio/x-midi audio/mpeg audio/ogg audio/opus audio/wav audio/webm audio/3gpp audio/3gpp2],
48
+ word: %w[application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document],
49
+ ppt: %w[application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation],
50
+ excel: %w[application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet],
51
+ slides: %w[application/vnd.oasis.opendocument.presentation],
52
+ spreadsheet: %w[application/vnd.oasis.opendocument.spreadsheet],
53
+ richtext: %w[application/vnd.oasis.opendocument.text],
54
+ zip: %w[application/zip application/x-7z-compressed application/x-bzip application/x-bzip2 application/gzip application/vnd.rar],
55
+ pdf: %w[application/pdf]
56
+ }
57
+
58
+ type = type_map.find { |key, mime_types| mime_types.include?(mime_type) }
59
+ if type
60
+ ["file", "earmark", type.first].compact.join("-")
61
+ else
62
+ "question"
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ViewModel
4
+ # = View Model
5
+ #
6
+ # A View Model is a class that allows you to set an arbitrary hash of attributes and access all values by calling
7
+ # attribute methods.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # model = ViewModel.new(a: 1, b: {b1: 1, b2: 2}, c: 3)
12
+ #
13
+ # model.a # => 1
14
+ # model.b # => {b1: 1, b2: 2}
15
+ # model.c # => 3
16
+ #
17
+ # Reserved methods or attributes are left untouched. If you want to access an attribute that collides with a reserved
18
+ # method, you can do it via the +to_hash+ method.
19
+ #
20
+ # model = ViewModel.new(class: "test")
21
+ #
22
+ # model.class # => ViewModel
23
+ # model.to_hash[:class] # => "test"
24
+
25
+ def initialize(hash = {})
26
+ hash.each do |key, value|
27
+ instance_variable_set("@#{key}", value)
28
+ end
29
+ end
30
+
31
+ def attributes
32
+ instance_variables.map { |instance_variable| instance_variable.to_s.delete("@").to_sym }
33
+ end
34
+
35
+ def to_hash
36
+ attributes.map { |attribute| {attribute => value_for(attribute)} }.inject(:merge)
37
+ end
38
+
39
+ alias_method :to_h, :to_hash
40
+
41
+ private
42
+
43
+ def value_for(attribute)
44
+ reserved_methods.include?(attribute) ? instance_variable_get("@#{attribute}") : send(attribute)
45
+ end
46
+
47
+ def method_missing(m, *args, &block)
48
+ instance_variable_get("@#{m}")
49
+ end
50
+
51
+ def respond_to_missing?
52
+ true
53
+ end
54
+
55
+ def reserved_methods
56
+ Class.methods + Class.private_methods
57
+ end
58
+ end
@@ -1,24 +1,28 @@
1
1
  <%
2
2
  # headmin/blocks
3
3
  #
4
- # ==== Options
4
+ # ==== Required parameters
5
5
  # * +blockable</tt> - Object with blocks association
6
- # * +path</tt> - Directory where to look for block templates
6
+ #
7
+ # ==== Optional parameters
8
+ # * +paths</tt> - Directories where to look for block templates
7
9
  #
8
10
  # ==== Examples
9
- # Basic version. This will only look for blocks in 'website/blocks'
11
+ # Basic version. (looks in views/website/blocks, views/blocks or views directory )
10
12
  # <%= render "headmin/blocks", blockable: @page %#>
11
13
  #
12
- # Define the path to look for block templates like this:
13
- # <%= render "headmin/blocks", blockable: @page, path: 'website/pages/blocks' %#>
14
+ # Define one ore more path where the templates could be located:
15
+ # <%= render "headmin/blocks", blockable: @page, paths: %w(website/pages/blocks) %#>
14
16
 
15
- blockable = local_assigns.has_key?(:blockable) ? blockable : nil
16
- path = local_assigns.has_key?(:path) ? path : nil
17
+ blocks = Headmin::BlocksView.new(local_assigns)
18
+ @lookup_context.prefixes = @lookup_context.prefixes + blocks.prefixes
17
19
  %>
18
20
 
19
21
  <% if blockable && blockable.respond_to?(:blocks) %>
20
22
  <% blockable.blocks.order(:position).each do |block| %>
21
- <% view_path = BlockService.frontend_view(block.name, path: path).gsub('/_', '/').split('.').first %>
22
- <%= render view_path, block: block %>
23
+
24
+ <!-- <%= block.name %> -->
25
+ <%= render block.name, block: block %>
26
+
23
27
  <% end %>
24
28
  <% end %>
@@ -1,10 +1,16 @@
1
1
  <%
2
2
  # headmin/heading
3
3
  #
4
+ # Accepts a block
5
+ #
6
+ # ==== References
7
+ # https://headmin.dev/docs/heading
8
+ # https://headmin.dev/preview/heading
9
+ #
4
10
  # ==== Examples
5
11
  # Basic version
6
12
  # <%= render "headmin/heading" do %#>
7
- # Your content
13
+ # Title
8
14
  # <% end %#>
9
15
  %>
10
16
 
@@ -1,45 +1,11 @@
1
- <%
2
- # name: headmin/thumbnail
3
- #
4
- # ==== Required parameters
5
- # * +src+ - Sourch path for the file
6
- #
7
- # ==== Optional parameters
8
- # * +width+ - Width of the thumbnail
9
- # * +height+ - Height of the thumbnail
10
- #
11
- # ==== References
12
- # https://getbootstrap.com/docs/5.1/content/images/#image-thumbnails
13
- #
14
- # ==== Examples
15
- # Basic version
16
- # <%= render 'headmin/thumbnail', src: file %#>
17
- #
18
- # Custom width and height
19
- # <%= render 'headmin/thumbnail', src: file, width: 300, height: 100 %#>
1
+ <% thumbnail = Headmin::ThumbnailView.new(local_assigns) %>
20
2
 
21
- width = local_assigns[:width] || 150
22
- height = local_assigns[:height] || 150
23
- class_names = ['img-thumbnail h-thumbnail', local_assigns[:class]].join(' ')
24
-
25
- mime_type = nil
26
- if src
27
- stripped_path = URI.parse(src).path
28
- extension = File.extname(stripped_path)
29
- mime_type = Rack::Mime.mime_type(extension)
30
- end
31
- %>
32
-
33
- <div class="<%= class_names %>" style="width: <%= width %>px; height: <%= height %>px;">
34
- <% if mime_type&.match?(/^image/) %>
35
- <div class="h-thumbnail-bg" style="background-image: url('<%= src %>');"></div>
3
+ <div class="<%= thumbnail.class_names %>" style="width: <%= thumbnail.width %>px; height: <%= thumbnail.height %>px;">
4
+ <% if thumbnail.image? %>
5
+ <div class="h-thumbnail-bg" style="background-image: url('<%= thumbnail.src %>');"></div>
36
6
  <% else %>
37
7
  <div class="h-thumbnail-bg">
38
- <% if mime_type %>
39
- <%= bootstrap_icon_for_mime_type(mime_type, class: 'h-thumbnail-icon') %>
40
- <% else %>
41
- <%= bootstrap_icon('question', class: 'h-thumbnail-icon') %>
42
- <% end %>
8
+ <%= bootstrap_icon(thumbnail.icon_name, class: 'h-thumbnail-icon') %>
43
9
  </div>
44
10
  <% end %>
45
11
  </div>
@@ -12,7 +12,7 @@
12
12
  <% name = local_assigns.has_key?(:name) ? name : '' %>
13
13
 
14
14
  <li>
15
- <a class="dropdown-item" href="<%= url %>" <%= "data-method=#{method}" if method %>>
15
+ <a class="dropdown-item" href="<%= url %>" <%= "data-turbo-method=#{method}" if method %>>
16
16
  <%= name %>
17
17
  </a>
18
18
  </li>
@@ -0,0 +1,11 @@
1
+ <div class="h-autocomplete d-none" data-autocomplete-target="dropdown">
2
+ <% if collection.any? %>
3
+ <%= render "headmin/forms/autocomplete/list" do %>
4
+ <% collection.each do |value, name| %>
5
+ <%= render "headmin/forms/autocomplete/item", value: value do %>
6
+ <%= name %>
7
+ <% end %>
8
+ <% end %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
@@ -1,39 +1,38 @@
1
1
  <%
2
2
  # headmin/forms/blocks
3
3
  #
4
- # ==== Options
4
+ # ==== Required parameters
5
5
  # * +form</tt> - Form object
6
- # * +path</tt> - Directory where to look for block templates
7
- # * +allow</tt> - Names of block templates that can be added
6
+ # * +names</tt> - Names of block templates that can be added
7
+ #
8
+ # ==== Optional parameters
9
+ # * +paths</tt> - Directories where to look for block templates
8
10
  #
9
11
  # ==== Examples
10
- # Basic version. This will only look for blocks in 'admin/blocks'
11
- # <%= render "headmin/forms/blocks", form: form %#>
12
+ # Basic version. (looks in views/admin/blocks, views/blocks or views directory )
13
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text image button) %#>
12
14
  #
13
- # Define the path to look for block templates like this:
14
- # <%= render "headmin/forms/blocks", form: form, path: 'admin/pages/blocks' %#>
15
+ # Define one ore more path where the templates could be located:
16
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text image button), paths: %w(admin/pages/blocks) %#>
15
17
  #
16
18
  # Limit the types of blocks
17
- # <%= render "headmin/forms/blocks", form: form, allow: ['text', 'text-image'] %#>
18
-
19
- path = local_assigns.has_key?(:path) ? path : nil
20
- allowed_block_names = local_assigns.has_key?(:allow) ? allow.map(&:to_s) : BlockService.block_names(path: path)
19
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text text_image list) %#>
21
20
 
22
- templates = allowed_block_names.map { |name| BlockService.form_view(name, path: path) }
21
+ blocks = Headmin::Form::BlocksView.new(local_assigns)
22
+ @lookup_context.prefixes = @lookup_context.prefixes + blocks.prefixes
23
23
  %>
24
24
 
25
- <%= render 'headmin/forms/repeater', form: form, attribute: :blocks, templates: templates, label: false do |block_form, template| %>
26
- <% name = template ? BlockService.view_name(template) : block_form.object.name %>
25
+ <%= render 'headmin/forms/repeater', blocks.repeater_options do |block_form, template| %>
26
+ <% name = template || block_form.object.name %>
27
27
 
28
28
  <!-- Name input of the block -->
29
29
  <%= block_form.hidden_field :name, value: name %>
30
30
 
31
31
  <!-- Render block form fields -->
32
- <% view_path = BlockService.form_view(name, path: path).gsub('/_', '/').split('.')[0] %>
33
- <%= render view_path, form: block_form %>
32
+ <%= render name, form: block_form %>
34
33
 
35
34
  <!-- Label -->
36
35
  <span class="position-absolute top-0 end-0 badge bg-light text-dark">
37
- <%= name.titleize %>
36
+ <%= t("blocks.#{name}", default: name).humanize %>
38
37
  </span>
39
38
  <% end %>
@@ -1,39 +1,34 @@
1
1
  <%
2
2
  # headmin/forms/checkbox
3
3
  #
4
- # ==== Options
5
- # * +form+ - Form object
4
+ # ==== Required parameters
6
5
  # * +attribute+ - Name of the attribute of the form model
7
- # * +label+ - Text to show as label. Label will be hidden if value is false
6
+ # * +form+ - Form object
7
+ #
8
+ # ==== Optional parameters
9
+ # * +checked_value+ - Value for checked state
10
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
11
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
12
+ # * +unchecked_value+ - Value for unchecked state
13
+ # * +wrapper+ - Hash with all options for the surrounding html tag
14
+ #
15
+ # ==== References
16
+ # https://headmin.dev/docs/forms/checkbox
17
+ # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox
18
+ # https://apidock.com/rails/ActionView/Helpers/FormHelper/check_box
8
19
  #
9
20
  # ==== Examples
10
21
  # Basic version
11
- # <%= render 'headmin/forms/image', form: form, attribute: :image %#>
12
-
13
- class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false
14
- data = local_assigns.has_key?(:data) ? data : nil
15
- disabled = local_assigns.has_key?(:disabled) ? disabled : false
16
- label = local_assigns.has_key?(:label) ? label : nil
17
- readonly = local_assigns.has_key?(:readonly) ? readonly : false
18
- required = local_assigns.has_key?(:required) ? required : false
19
-
20
- options = {
21
- 'aria-describedby': form_field_validation_id(form, attribute),
22
- class: "form-checkbox-input #{form_field_validation_class(form, attribute)} #{class_names}",
23
- data: data,
24
- disabled: disabled,
25
- placeholder: attribute,
26
- readonly: readonly,
27
- required: required,
28
- }
22
+ # <%= form_with do |form| %#>
23
+ # <%= render "headmin/forms/checkbox", form: form, attribute: :active %#>
24
+ # <% end %#>
29
25
 
30
- show_label = label != false
26
+ checkbox = Headmin::Form::CheckboxView.new(local_assigns)
31
27
  %>
32
28
 
33
- <div class="<%= ('mb-3 text-start' if show_label) %>">
34
- <%= form.check_box(attribute, options) %>
35
- <% if show_label %>
36
- <%= render 'headmin/forms/label', form: form, attribute: attribute, name: label, required: required %>
37
- <% end %>
38
- <%= render 'headmin/forms/validation', form: form, attribute: attribute %>
39
- </div>
29
+ <%= render "headmin/forms/wrapper", checkbox.wrapper_options do %>
30
+ <%= form.check_box(checkbox.attribute, checkbox.input_options, checkbox.checked_value, checkbox.unchecked_value) %>
31
+ <%= render "headmin/forms/label", checkbox.label_options if checkbox.label? %>
32
+ <%= render "headmin/forms/validation", checkbox.validation_options if checkbox.validate? %>
33
+ <%= render "headmin/forms/hint", checkbox.hint_options if checkbox.hint? %>
34
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <datalist id="<%= id %>">
2
+ <%= options_for_select(collection) %>
3
+ </datalist>
@@ -2,40 +2,40 @@
2
2
  # headmin/forms/date
3
3
  #
4
4
  # ==== Required parameters
5
- # * +form+ - Form object
6
5
  # * +attribute+ - Name of the attribute of the form model
6
+ # * +form+ - Form object
7
7
  #
8
8
  # ==== Optional parameters
9
- # * +aria+ - Provide a hash to define all aria attributes
10
- # * +autocomplete+ - Value to be autofilled by the browser
11
- # * +autofocus+ - Set to true to focus on this field when the page renders
12
- # * +data+ - Optional HTML data attributes
13
- # * +disabled+ - Set to true if the input should be shown as disabled
14
- # * +id+ - Input identifier
15
- # * +list+ - Add array of options to show in a data list
16
- # * +readonly+ - Set to true if the value of the field can only be read and not be modified
17
- # * +required+ - Set to true to mark as required
18
- # * +step+ - The acceptable value granularity
19
- # * +value+ - Overrides the value of the form
20
- #
21
- # ==== Extra parameters
22
- # Listed in 'headmin/forms/base'
9
+ # * +append+ - Display as input group with text on the right-hand side
10
+ # * +float+ - Use floating labels. Defaults to false
11
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
12
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
13
+ # * +list+ - Options are passed through options_for_select
14
+ # * +plaintext+ - Render input as plain text.
15
+ # * +prepend+ - Display as input group with text on the left-hand side
16
+ # * +wrapper+ - Hash with all options for the surrounding html tag
23
17
  #
24
18
  # ==== References
19
+ # https://headmin.dev/docs/forms/date
25
20
  # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date
26
21
  # https://apidock.com/rails/ActionView/Helpers/FormHelper/date_field
27
22
  #
28
23
  # ==== Examples
29
24
  # Basic version
30
- # <%= render 'headmin/forms/date', form: form, attribute: :date %#>
25
+ # <%= form_with do |form| %#>
26
+ # <%= render "headmin/forms/date", form: form, attribute: :date_of_birth %#>
27
+ # <% end %#>
31
28
 
32
- option_keys = %i(aria autocomplete autofocus data disabled id list readonly required step value)
33
- options = local_assigns.slice(*option_keys).merge(
34
- aria: { describedby: form_field_validation_id(form, attribute) },
35
- class: ['form-control', form_field_validation_class(form, attribute)].join(' '),
36
- )
29
+ date = Headmin::Form::DateView.new(local_assigns)
37
30
  %>
38
31
 
39
- <%= render 'headmin/forms/base', local_assigns do |form| %>
40
- <%= form.date_field(attribute, options) %>
41
- <% end %>
32
+ <%= render "headmin/forms/wrapper", date.wrapper_options do %>
33
+ <%= render "headmin/forms/label", date.label_options if date.prepend_label? %>
34
+ <%= render "headmin/forms/input_group", date.input_group_options do %>
35
+ <%= form.date_field(date.attribute, date.input_options) %>
36
+ <%= render "headmin/forms/datalist", date.datalist_options if date.datalist? %>
37
+ <% end %>
38
+ <%= render "headmin/forms/validation", date.validation_options if date.validate? %>
39
+ <%= render "headmin/forms/hint", date.hint_options if date.hint? %>
40
+ <%= render "headmin/forms/label", date.label_options if date.append_label? %>
41
+ <% end %>