headmin 0.2.9 → 0.3.1

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 (237) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -3
  3. data/Gemfile.lock +12 -1
  4. data/README.md +64 -57
  5. data/app/assets/config/headmin_manifest.js +2 -0
  6. data/app/assets/javascripts/headmin/config/i18n.js +11 -0
  7. data/{src/js → app/assets/javascripts}/headmin/controllers/blocks_controller.js +0 -1
  8. data/{src/js → app/assets/javascripts}/headmin/controllers/date_range_controller.js +0 -2
  9. data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +33 -0
  10. data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +244 -0
  11. data/{src/js → app/assets/javascripts}/headmin/controllers/filter_controller.js +12 -6
  12. data/{src/js → app/assets/javascripts}/headmin/controllers/flatpickr_controller.js +2 -1
  13. data/app/assets/javascripts/headmin/controllers/hello_controller.js +7 -0
  14. data/app/assets/javascripts/headmin/controllers/notification_controller.js +8 -0
  15. data/{src/js → app/assets/javascripts}/headmin/controllers/popup_controller.js +0 -1
  16. data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +13 -0
  17. data/app/assets/javascripts/headmin/controllers/select_controller.js +48 -0
  18. data/{src/js → app/assets/javascripts}/headmin/controllers/table_controller.js +1 -1
  19. data/app/assets/javascripts/headmin/index.js +41 -0
  20. data/app/assets/javascripts/headmin.js +15934 -0
  21. data/{src/scss → app/assets/stylesheets}/headmin/form.scss +51 -2
  22. data/app/assets/stylesheets/headmin/syntax.scss +349 -0
  23. data/app/assets/stylesheets/headmin/thumbnail.scss +20 -0
  24. data/app/assets/stylesheets/headmin/utilities.scss +68 -0
  25. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_accordion.scss +118 -0
  26. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_alert.scss +57 -0
  27. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_badge.scss +29 -0
  28. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_breadcrumb.scss +28 -0
  29. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_button-group.scss +139 -0
  30. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_buttons.scss +111 -0
  31. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_card.scss +216 -0
  32. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_carousel.scss +229 -0
  33. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_close.scss +40 -0
  34. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_containers.scss +41 -0
  35. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_dropdown.scss +240 -0
  36. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_forms.scss +9 -0
  37. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_functions.scss +302 -0
  38. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_grid.scss +33 -0
  39. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_helpers.scss +9 -0
  40. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_images.scss +42 -0
  41. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_list-group.scss +174 -0
  42. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_mixins.scss +43 -0
  43. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_modal.scss +209 -0
  44. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_nav.scss +139 -0
  45. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_navbar.scss +335 -0
  46. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_offcanvas.scss +83 -0
  47. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_pagination.scss +64 -0
  48. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_placeholders.scss +51 -0
  49. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_popover.scss +158 -0
  50. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_progress.scss +48 -0
  51. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_reboot.scss +625 -0
  52. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_root.scss +54 -0
  53. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_spinners.scss +69 -0
  54. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_tables.scss +155 -0
  55. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_toasts.scss +51 -0
  56. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_tooltip.scss +115 -0
  57. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_transitions.scss +27 -0
  58. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_type.scss +104 -0
  59. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_utilities.scss +630 -0
  60. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/_variables.scss +1641 -0
  61. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/bootstrap-grid.scss +67 -0
  62. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/bootstrap-reboot.scss +13 -0
  63. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/bootstrap-utilities.scss +18 -0
  64. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/bootstrap.scss +53 -0
  65. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_floating-labels.scss +63 -0
  66. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_form-check.scss +152 -0
  67. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_form-control.scss +219 -0
  68. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_form-range.scss +91 -0
  69. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_form-select.scss +72 -0
  70. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_form-text.scss +11 -0
  71. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_input-group.scss +121 -0
  72. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_labels.scss +36 -0
  73. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/forms/_validation.scss +12 -0
  74. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_clearfix.scss +3 -0
  75. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_colored-links.scss +12 -0
  76. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_position.scss +30 -0
  77. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_ratio.scss +26 -0
  78. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_stacks.scss +15 -0
  79. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_stretched-link.scss +15 -0
  80. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_text-truncation.scss +7 -0
  81. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
  82. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/helpers/_vr.scss +8 -0
  83. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_alert.scss +11 -0
  84. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_backdrop.scss +14 -0
  85. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_border-radius.scss +78 -0
  86. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_box-shadow.scss +18 -0
  87. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_breakpoints.scss +127 -0
  88. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_buttons.scss +133 -0
  89. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_caret.scss +64 -0
  90. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_clearfix.scss +9 -0
  91. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_color-scheme.scss +7 -0
  92. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_container.scss +9 -0
  93. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_deprecate.scss +10 -0
  94. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_forms.scss +144 -0
  95. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_gradients.scss +47 -0
  96. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_grid.scss +151 -0
  97. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_image.scss +16 -0
  98. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_list-group.scss +24 -0
  99. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_lists.scss +7 -0
  100. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_pagination.scss +31 -0
  101. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_reset-text.scss +17 -0
  102. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_resize.scss +6 -0
  103. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_table-variants.scss +21 -0
  104. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_text-truncate.scss +8 -0
  105. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_transition.scss +26 -0
  106. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_utilities.scss +89 -0
  107. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/mixins/_visually-hidden.scss +29 -0
  108. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/utilities/_api.scss +47 -0
  109. data/app/assets/stylesheets/headmin/vendor/bootstrap/scss/vendor/_rfs.scss +354 -0
  110. data/app/assets/stylesheets/headmin/vendor/flatpickr.css +903 -0
  111. data/app/assets/stylesheets/headmin/vendor/tom-select-bootstrap.css +537 -0
  112. data/app/assets/stylesheets/headmin.css +13454 -0
  113. data/app/assets/stylesheets/headmin.scss +65 -0
  114. data/app/helpers/headmin/admin_helper.rb +1 -0
  115. data/app/helpers/headmin/bootstrap_helper.rb +25 -3
  116. data/app/helpers/headmin/documentation_helper.rb +35 -0
  117. data/app/helpers/headmin/form_helper.rb +4 -0
  118. data/app/helpers/headmin/request_helper.rb +3 -8
  119. data/app/models/headmin/documentation_renderer.rb +32 -0
  120. data/app/models/headmin/form/base.rb +79 -0
  121. data/app/models/headmin/form/text.rb +53 -0
  122. data/app/services/block_service.rb +1 -1
  123. data/app/views/examples/admin.html.erb +1 -1
  124. data/app/views/headmin/_blocks.html.erb +2 -2
  125. data/app/views/headmin/_breadcrumbs.html.erb +1 -1
  126. data/app/views/headmin/_card.html.erb +8 -6
  127. data/app/views/headmin/_dropdown.html.erb +1 -1
  128. data/app/views/headmin/_filters.html.erb +20 -8
  129. data/app/views/headmin/_form.html.erb +14 -14
  130. data/app/views/headmin/_heading.html.erb +1 -1
  131. data/app/views/headmin/_notifications.html.erb +1 -1
  132. data/app/views/headmin/_pagination.html.erb +1 -1
  133. data/app/views/headmin/_popup.html.erb +10 -4
  134. data/app/views/headmin/_table.html.erb +2 -2
  135. data/app/views/headmin/_thumbnail.html.erb +47 -0
  136. data/app/views/headmin/dropdown/_devise.html.erb +2 -2
  137. data/app/views/headmin/dropdown/_list.html.erb +3 -6
  138. data/app/views/headmin/filters/_date.html.erb +4 -10
  139. data/app/views/headmin/filters/_flatpickr.html.erb +5 -5
  140. data/app/views/headmin/filters/_search.html.erb +5 -5
  141. data/app/views/headmin/filters/_select.html.erb +6 -6
  142. data/app/views/headmin/filters/filter/_button.html.erb +7 -7
  143. data/app/views/headmin/filters/filter/_template.html.erb +1 -1
  144. data/app/views/headmin/forms/_actions.html.erb +1 -1
  145. data/app/views/headmin/forms/_base.html.erb +98 -45
  146. data/app/views/headmin/forms/_blocks.html.erb +4 -4
  147. data/app/views/headmin/forms/_checkbox.html.erb +3 -3
  148. data/app/views/headmin/forms/_date.html.erb +29 -45
  149. data/app/views/headmin/forms/_date_range.html.erb +24 -66
  150. data/app/views/headmin/forms/_email.html.erb +35 -26
  151. data/app/views/headmin/forms/_file.html.erb +186 -34
  152. data/app/views/headmin/forms/_flatpickr.html.erb +18 -39
  153. data/app/views/headmin/forms/_flatpickr_range.html.erb +34 -45
  154. data/app/views/headmin/forms/_hidden.html.erb +13 -12
  155. data/app/views/headmin/forms/_image.html.erb +11 -45
  156. data/app/views/headmin/forms/_label.html.erb +18 -14
  157. data/app/views/headmin/forms/_number.html.erb +40 -37
  158. data/app/views/headmin/forms/_password.html.erb +37 -58
  159. data/app/views/headmin/forms/_redactorx.html.erb +8 -7
  160. data/app/views/headmin/forms/_repeater.html.erb +6 -6
  161. data/app/views/headmin/forms/_select.html.erb +43 -48
  162. data/app/views/headmin/forms/_text.html.erb +95 -58
  163. data/app/views/headmin/forms/_textarea.html.erb +37 -26
  164. data/app/views/headmin/forms/_url.html.erb +35 -26
  165. data/app/views/headmin/forms/_validation.html.erb +3 -3
  166. data/app/views/headmin/forms/_video.html.erb +21 -0
  167. data/app/views/headmin/forms/fields/_base.html.erb +3 -3
  168. data/app/views/headmin/forms/fields/_file.html.erb +2 -2
  169. data/app/views/headmin/forms/fields/_group.html.erb +3 -3
  170. data/app/views/headmin/forms/fields/_image.html.erb +2 -2
  171. data/app/views/headmin/forms/fields/_list.html.erb +3 -3
  172. data/app/views/headmin/forms/fields/_text.html.erb +2 -2
  173. data/app/views/headmin/forms/repeater/_row.html.erb +1 -1
  174. data/app/views/headmin/heading/_title.html.erb +1 -1
  175. data/app/views/headmin/layout/_body.html.erb +1 -1
  176. data/app/views/headmin/layout/_content.html.erb +1 -1
  177. data/app/views/headmin/layout/_footer.html.erb +1 -1
  178. data/app/views/headmin/layout/_header.html.erb +1 -1
  179. data/app/views/headmin/layout/_main.html.erb +1 -1
  180. data/app/views/headmin/layout/_sidebar.html.erb +3 -3
  181. data/app/views/headmin/layout/sidebar/_bottom.html.erb +1 -1
  182. data/app/views/headmin/layout/sidebar/_nav.html.erb +1 -1
  183. data/app/views/headmin/nav/_dropdown.html.erb +34 -0
  184. data/app/views/headmin/nav/_item.html.erb +22 -13
  185. data/app/views/headmin/table/_actions.html.erb +1 -1
  186. data/app/views/headmin/table/_body.html.erb +1 -1
  187. data/app/views/headmin/table/_foot.html.erb +1 -1
  188. data/app/views/headmin/table/_footer.html.erb +1 -1
  189. data/app/views/headmin/table/_head.html.erb +1 -1
  190. data/app/views/headmin/table/_header.html.erb +1 -1
  191. data/app/views/headmin/table/actions/_action.html.erb +4 -4
  192. data/app/views/headmin/table/actions/_delete.html.erb +1 -1
  193. data/app/views/headmin/table/actions/_export.html.erb +1 -1
  194. data/app/views/headmin/table/body/_row.html.erb +2 -2
  195. data/config/importmap.rb +2 -0
  196. data/config/locales/en.yml +0 -3
  197. data/config/locales/headmin/forms/en.yml +5 -0
  198. data/config/locales/headmin/forms/nl.yml +5 -0
  199. data/config/locales/headmin/popup/en.yml +4 -0
  200. data/config/locales/headmin/popup/nl.yml +4 -0
  201. data/config/locales/headmin/thumbnail/en.yml +4 -0
  202. data/config/locales/headmin/thumbnail/nl.yml +4 -0
  203. data/config/locales/nl.yml +0 -3
  204. data/esbuild-css.js +25 -0
  205. data/esbuild-js.js +11 -0
  206. data/headmin.gemspec +4 -1
  207. data/lib/headmin/engine.rb +15 -0
  208. data/lib/headmin/version.rb +1 -1
  209. data/lib/headmin.rb +1 -1
  210. data/package.json +18 -34
  211. data/src/js/headmin.js +1 -1
  212. data/src/scss/headmin.scss +1 -61
  213. data/yarn.lock +393 -5177
  214. metadata +183 -33
  215. data/.nvmrc +0 -1
  216. data/app/controllers/concerns/headmin/ckeditor.rb +0 -27
  217. data/app/views/headmin/forms/_ckeditor.html.erb +0 -42
  218. data/dist/css/headmin.css +0 -12357
  219. data/dist/js/headmin.js +0 -1115
  220. data/src/js/headmin/headmin.js +0 -158
  221. data/src/scss/headmin/utilities.scss +0 -19
  222. data/webpack.config.js +0 -30
  223. /data/{src/js → app/assets/javascripts}/headmin/controllers/filters_controller.js +0 -0
  224. /data/{src/js → app/assets/javascripts}/headmin/controllers/repeater_controller.js +0 -0
  225. /data/{src/js → app/assets/javascripts}/headmin/controllers/table_actions_controller.js +0 -0
  226. /data/{src/scss → app/assets/stylesheets}/headmin/filter.scss +0 -0
  227. /data/{src/scss → app/assets/stylesheets}/headmin/filters.scss +0 -0
  228. /data/{src/scss → app/assets/stylesheets}/headmin/general.scss +0 -0
  229. /data/{src/scss → app/assets/stylesheets}/headmin/layout/body.scss +0 -0
  230. /data/{src/scss → app/assets/stylesheets}/headmin/layout/sidebar.scss +0 -0
  231. /data/{src/scss → app/assets/stylesheets}/headmin/layout.scss +0 -0
  232. /data/{src/scss → app/assets/stylesheets}/headmin/login.scss +0 -0
  233. /data/{src/scss/vendor/bootstrap/variables.scss → app/assets/stylesheets/headmin/overrides/bootstrap.scss} +0 -0
  234. /data/{src/scss/vendor/redactorx/override.css → app/assets/stylesheets/headmin/overrides/redactorx.css} +0 -0
  235. /data/{src/scss → app/assets/stylesheets}/headmin/popup.scss +0 -0
  236. /data/{src/scss → app/assets/stylesheets}/headmin/table.scss +0 -0
  237. /data/{src/scss/vendor/redactorx → app/assets/stylesheets/headmin/vendor}/redactorx.css +0 -0
@@ -0,0 +1,65 @@
1
+ // Bootstrap icons
2
+ @import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css");
3
+
4
+ // Bootstrap
5
+ @import "headmin/vendor/bootstrap/scss/functions";
6
+ @import "headmin/vendor/bootstrap/scss/functions";
7
+ @import "headmin/vendor/bootstrap/scss/functions";
8
+ @import "headmin/vendor/bootstrap/scss/variables";
9
+ @import "headmin/vendor/bootstrap/scss/mixins";
10
+ @import "headmin/vendor/bootstrap/scss/utilities";
11
+ @import "headmin/overrides/bootstrap";
12
+ @import "headmin/vendor/bootstrap/scss/root";
13
+ @import "headmin/vendor/bootstrap/scss/reboot";
14
+ @import "headmin/vendor/bootstrap/scss/type";
15
+ @import "headmin/vendor/bootstrap/scss/images";
16
+ @import "headmin/vendor/bootstrap/scss/containers";
17
+ @import "headmin/vendor/bootstrap/scss/grid";
18
+ @import "headmin/vendor/bootstrap/scss/tables";
19
+ @import "headmin/vendor/bootstrap/scss/forms";
20
+ @import "headmin/vendor/bootstrap/scss/buttons";
21
+ @import "headmin/vendor/bootstrap/scss/transitions";
22
+ @import "headmin/vendor/bootstrap/scss/dropdown";
23
+ @import "headmin/vendor/bootstrap/scss/button-group";
24
+ @import "headmin/vendor/bootstrap/scss/nav";
25
+ @import "headmin/vendor/bootstrap/scss/navbar";
26
+ @import "headmin/vendor/bootstrap/scss/card";
27
+ @import "headmin/vendor/bootstrap/scss/accordion";
28
+ @import "headmin/vendor/bootstrap/scss/breadcrumb";
29
+ @import "headmin/vendor/bootstrap/scss/pagination";
30
+ @import "headmin/vendor/bootstrap/scss/badge";
31
+ @import "headmin/vendor/bootstrap/scss/alert";
32
+ @import "headmin/vendor/bootstrap/scss/progress";
33
+ @import "headmin/vendor/bootstrap/scss/list-group";
34
+ @import "headmin/vendor/bootstrap/scss/close";
35
+ @import "headmin/vendor/bootstrap/scss/toasts";
36
+ @import "headmin/vendor/bootstrap/scss/modal";
37
+ @import "headmin/vendor/bootstrap/scss/tooltip";
38
+ @import "headmin/vendor/bootstrap/scss/popover";
39
+ @import "headmin/vendor/bootstrap/scss/carousel";
40
+ @import "headmin/vendor/bootstrap/scss/spinners";
41
+ @import "headmin/vendor/bootstrap/scss/helpers";
42
+ @import "headmin/vendor/bootstrap/scss/utilities/api";
43
+
44
+ // Tom select
45
+ @import "headmin/vendor/tom-select-bootstrap";
46
+
47
+ // Flatpickr
48
+ @import "headmin/vendor/flatpickr";
49
+
50
+ // Redactor
51
+ @import "headmin/vendor/redactorx";
52
+ @import "headmin/overrides/redactorx";
53
+
54
+ // Headmin
55
+ @import "headmin/filters";
56
+ @import "headmin/form";
57
+ @import "headmin/general";
58
+ @import "headmin/layout";
59
+ @import "headmin/login";
60
+ @import "headmin/table";
61
+ @import "headmin/utilities";
62
+ @import "headmin/filter";
63
+ @import "headmin/popup";
64
+ @import "headmin/thumbnail";
65
+ @import "headmin/syntax";
@@ -5,5 +5,6 @@ module Headmin
5
5
  include Headmin::FormHelper
6
6
  include Headmin::NotificationHelper
7
7
  include Headmin::RequestHelper
8
+ include Headmin::DocumentationHelper
8
9
  end
9
10
  end
@@ -1,9 +1,31 @@
1
1
  module Headmin
2
2
  module BootstrapHelper
3
3
  def bootstrap_icon(icon, options = {})
4
- data = options.has_key?(:data) ? options[:data] : nil
5
- klass = options.has_key?(:class) ? options[:class] : nil
6
- content_tag(:i, class: "bi bi-#{icon} #{klass}", data: data) {}
4
+ tag_name = options.extract!(:tag_name).fetch(:tag_name, :i)
5
+ options[:class] = ['bi', "bi-#{icon}", options.dig(:class)].compact.join(' ')
6
+ content_tag(tag_name, options) {}
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)
7
29
  end
8
30
  end
9
31
  end
@@ -0,0 +1,35 @@
1
+ module Headmin
2
+ module DocumentationHelper
3
+ def extract_documentation(text)
4
+ # Get content inside documentation block
5
+ starts_with = '<% documentation do %>\n'
6
+ ends_with = '\n<% end %>'
7
+ between = text[/#{starts_with}(.*?)#{ends_with}/m, 1]
8
+
9
+ # Remove leading whitespaces from each line
10
+ between.lines.map { |line| line.sub(' ', '') }.join
11
+ end
12
+
13
+ def markdown_to_html(text)
14
+ renderer = Headmin::DocumentationRenderer.new(escape_html: true)
15
+ markdown = Redcarpet::Markdown.new(renderer, tables: true, fenced_code_blocks: true)
16
+ markdown.render(text)
17
+ end
18
+
19
+ def documentation(template = nil)
20
+ # Disable rendering inside block
21
+ return if block_given?
22
+
23
+ # Read contents of template
24
+ content = @lookup_context.find_template(template, nil, true).encode!
25
+
26
+ # Extract documentation
27
+ content = extract_documentation(content)
28
+
29
+ # Convert markdown into HTML
30
+ html = markdown_to_html(content)
31
+
32
+ raw html
33
+ end
34
+ end
35
+ end
@@ -13,6 +13,10 @@ module Headmin
13
13
  form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
14
14
  end
15
15
 
16
+ def human_attribute_name(attribute)
17
+ attribute.to_s.humanize
18
+ end
19
+
16
20
  # Outputs currently present query parameters as hidden fields for a given form
17
21
  #
18
22
  # https://example.com/products?amount=1&type[]=food&type[]=beverage
@@ -3,15 +3,10 @@ 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
- matches_query = uri.query ? request.query_string.include?(query_string) : true
9
- is_root = request.fullpath == url
10
- if url == admin_root_path
11
- is_root
12
- else
13
- matches_path && matches_query
14
- end
8
+ matches_query = request.query_string.include?(query_string)
9
+ matches_path && matches_query
15
10
  end
16
11
 
17
12
  def default_params
@@ -0,0 +1,32 @@
1
+ module Headmin
2
+ class DocumentationRenderer < Redcarpet::Render::HTML
3
+ def block_code(code, language)
4
+ if language == "erbx"
5
+ "<div class=\"card mb-3\"><div class=\"card-body\">#{render_code(code)}</div><div class=\"card-footer\"><pre><code class=\"h-syntax\">#{highlight_syntax(code, 'erb')}</code></pre></div></div>"
6
+ else
7
+ "<pre><code class=\"h-syntax\">#{highlight_syntax(code, language)}</code></pre></div>"
8
+ end
9
+ end
10
+
11
+ def table(header, body)
12
+ "<table class=\"table table-sm\">#{header}#{body}</table>"
13
+ end
14
+
15
+ private
16
+
17
+ def highlight_syntax(code, language)
18
+ formatter = Rouge::Formatters::HTML.new
19
+ lexer = Rouge::Lexer.find(language)
20
+ formatter.format(lexer.lex(code))
21
+ end
22
+
23
+ def render_code(code)
24
+ ApplicationController.renderer.new(
25
+ 'action_dispatch.request.path_parameters' => {
26
+ controller: 'main',
27
+ action: 'index'
28
+ }
29
+ ).render(inline: code)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,79 @@
1
+ module Headmin
2
+ module Form
3
+ class Base
4
+ def initialize(local_assigns)
5
+ @local_assigns = local_assigns
6
+ end
7
+
8
+ def class_names
9
+ class_names = [@local_assigns[:class]]
10
+ class_names << "form-floating" if float
11
+ class_names << "mb-3 text-start"
12
+ class_names.join(" ")
13
+ end
14
+
15
+ def data
16
+ @local_assigns[:data]
17
+ end
18
+
19
+ def label_options
20
+ {
21
+ attribute: attribute,
22
+ class: "d-block",
23
+ for: id,
24
+ form: form,
25
+ required: required,
26
+ text: label
27
+ }
28
+ end
29
+
30
+ def required
31
+ @local_assigns[:required]
32
+ end
33
+
34
+ def form
35
+ @local_assigns[:form]
36
+ end
37
+
38
+ def id
39
+ @local_assigns[:id]
40
+ end
41
+
42
+ def validation_options
43
+ {
44
+ attribute: attribute,
45
+ form: form
46
+ }
47
+ end
48
+
49
+ def attribute
50
+ @local_assigns[:attribute]
51
+ end
52
+
53
+ def list
54
+ @local_assigns[:list]
55
+ end
56
+
57
+ def list_id
58
+ list ? "#{attribute}_list" : nil
59
+ end
60
+
61
+ def append
62
+ @local_assigns[:append]
63
+
64
+ end
65
+
66
+ def prepend
67
+ @local_assigns[:prepend]
68
+ end
69
+
70
+ def float
71
+ @local_assigns[:float] || false
72
+ end
73
+
74
+ def label
75
+ @local_assigns[:label]
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,53 @@
1
+ module Headmin
2
+ module Form
3
+ class Text
4
+ def initialize(local_assigns)
5
+ @local_assigns = local_assigns
6
+ end
7
+
8
+ def placeholder
9
+ @local_assigns[:float] ? @local_assigns[:placeholder] || attribute : @local_assigns[:placeholder]
10
+ end
11
+
12
+ def attribute
13
+ @local_assigns[:attribute]
14
+ end
15
+
16
+ def form
17
+ @local_assigns[:form]
18
+ end
19
+
20
+ def options
21
+ option_keys = %i(aria autocomplete autofocus data disabled id maxlength minlength list pattern placeholder readonly required spellcheck size value)
22
+ @local_assigns.slice(*option_keys).merge(
23
+ aria: { describedby: form_field_validation_id(form, attribute) },
24
+ class: ["form-control", form_field_validation_class(form, attribute)].join(" "),
25
+ list: @local_assigns[:list] ? "#{attribute}_list" : nil,
26
+ placeholder: placeholder
27
+ )
28
+ end
29
+
30
+ def local_assigns
31
+ @local_assigns
32
+ end
33
+
34
+ def form_field_valid?(form, name)
35
+ return unless form.object
36
+
37
+ !form.object.errors.has_key?(name)
38
+ end
39
+
40
+ def form_field_validation_id(form, name)
41
+ return unless form.object
42
+
43
+ [form.object_name, name.to_s, "validation"].join("_").parameterize.underscore
44
+ end
45
+
46
+ def form_field_validation_class(form, name)
47
+ return unless form.object
48
+
49
+ "is-invalid" if form.object.errors.has_key?(name)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -22,7 +22,7 @@ class BlockService
22
22
  end
23
23
 
24
24
  def self.view_name(view)
25
- filename = File.basename(view, '.html.erb')
25
+ filename = File.basename(view.split('.')[0])
26
26
 
27
27
  # Removes leading _ if exists
28
28
  filename.sub(/^_/, '')
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="<%= I18n.locale %>">
2
+ <html lang="<%= I18n.locale %>" data-controller="headmin">
3
3
  <head>
4
4
  <title>Admin</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
@@ -2,8 +2,8 @@
2
2
  # headmin/blocks
3
3
  #
4
4
  # ==== Options
5
- # * <tt>blockable</tt> - Object with blocks association
6
- # * <tt>path</tt> - Directory where to look for block templates
5
+ # * +blockable</tt> - Object with blocks association
6
+ # * +path</tt> - Directory where to look for block templates
7
7
  #
8
8
  # ==== Examples
9
9
  # Basic version. This will only look for blocks in 'website/blocks'
@@ -2,7 +2,7 @@
2
2
  # headmin/breadcrumbs
3
3
  #
4
4
  # ==== Options
5
- # * <tt>breadcrumbs</tt> - Object with blocks association
5
+ # * +breadcrumbs</tt> - Object with blocks association
6
6
  #
7
7
  # ==== Examples
8
8
  # Basic version. This will use the publicly available `breadcrumbs` variable
@@ -1,11 +1,13 @@
1
+ <% warn "[DEPRECATION] `headmin/card` is deprecated. Please use plain Bootstrap markup." %>
1
2
  <%
3
+ # DEPRECATED in 0.3
2
4
  # headmin/card
3
5
  #
4
6
  # ==== Options
5
- # * <tt>title</tt> - Title for card
6
- # * <tt>description</tt> - Description for card
7
- # * <tt>id</tt> - HTML Id Attribute
8
- # * <tt>padded</tt> - Set to true if you want to render the block content inside the card-body element
7
+ # * +title</tt> - Title for card
8
+ # * +description</tt> - Description for card
9
+ # * +id</tt> - HTML Id Attribute
10
+ # * +padded</tt> - Set to true if you want to render the block content inside the card-body element
9
11
  #
10
12
  # ==== Examples
11
13
  # Basic version.
@@ -38,13 +40,13 @@
38
40
 
39
41
  <!-- Render inside body-->
40
42
  <% if padded %>
41
- <%= yield if block_given? %>
43
+ <%= yield %>
42
44
  <% end %>
43
45
  </div>
44
46
  <% end %>
45
47
 
46
48
  <!-- Render outside body-->
47
49
  <% unless padded %>
48
- <%= yield if block_given? %>
50
+ <%= yield %>
49
51
  <% end %>
50
52
  </div>
@@ -2,7 +2,7 @@
2
2
  # headmin/dropdown
3
3
  #
4
4
  # ==== Options
5
- # * <tt>class</tt> - Custom class names to put on the dropdown
5
+ # * +class</tt> - Custom class names to put on the dropdown
6
6
  #
7
7
  # ==== Examples
8
8
  # Basic version
@@ -2,16 +2,21 @@
2
2
  # headmin/filters
3
3
  #
4
4
  # ==== Options
5
- # * <tt>url</tt> - Base url to send filter query to. Defaults to current URL
5
+ # * +url</tt> - Base url to send filter query to. Defaults to current URL
6
6
  #
7
7
  # ==== Examples
8
8
  # Basic version
9
- # <%= render "headmin/filters" %#>
9
+ # <%= render "headmin/filters" do %#>
10
+ # <%= render "headmin/filters/select", name: 'color', options: ['red', 'green', 'blue'] %#>
11
+ # <% end %#>
10
12
  #
11
13
  # With custom URL
12
14
  # <%= render "headmin/filters", url: admin_polls_path %#>
13
15
 
14
16
  action = local_assigns.has_key?(:url) ? url : request.path
17
+
18
+ # Perform yield in order to capture content blocks
19
+ yield
15
20
  %>
16
21
 
17
22
  <form action="<%= action %>" data-controller="filters" data-filters-target="form">
@@ -21,14 +26,12 @@
21
26
  <%= hidden_field_tag(name.to_sym, value) %>
22
27
  <% end %>
23
28
 
24
- <%= yield if block_given? %>
25
-
26
- <div class="d-flex flex-column flex-md-row align-content-start align-items-md-center">
29
+ <div class="d-flex flex-column flex-md-row align-content-start align-items-md-start">
27
30
  <div class="d-flex align-items-center">
28
31
 
29
32
  <!-- Search -->
30
33
  <div class="h-filters-search d-flex my-1 w-100">
31
- <%= content_for :filters_search %>
34
+ <%= yield :filters_search %>
32
35
 
33
36
  <!-- Separator -->
34
37
  <% if content_for?(:filters_menu) && content_for?(:filters_search) %>
@@ -60,10 +63,19 @@
60
63
 
61
64
  <!-- Filter list -->
62
65
  <div class="h-filter-list d-flex ms-md-1 flex-wrap" data-filters-target="list">
63
- <%= content_for :filters_buttons %>
66
+ <%= yield :filters_buttons %>
64
67
  </div>
65
68
  </div>
66
69
 
67
70
  <!-- Filter templates -->
68
- <%= content_for :filters_templates %>
71
+ <%= yield :filters_templates %>
69
72
  </form>
73
+
74
+
75
+ <%
76
+ # Clears content blocks to make this view reusable
77
+ content_for(:filters_search, flush: true) { concat(nil) }
78
+ content_for(:filters_menu, flush: true) { concat(nil) }
79
+ content_for(:filters_buttons, flush: true) { concat(nil) }
80
+ content_for(:filters_templates, flush: true) { concat(nil) }
81
+ %>
@@ -2,20 +2,20 @@
2
2
  # headmin/form
3
3
  #
4
4
  # ==== Options
5
- # * <tt>model<tt> - A model to infer :url and :scope
6
- # * <tt>scope<tt> - The scope to prefix input field names with
7
- # * <tt>url<tt> - The URL the form submits to
8
- # * <tt>format<tt> - The format of the route the form submits to
9
- # * <tt>namespace<tt> - A namespace for your form to ensure uniqueness of id attributes on form elements
10
- # * <tt>method<tt> - The method to use when submitting the form
11
- # * <tt>authenticity_token<tt> - Authenticity token to use in the form
12
- # * <tt>local<tt> - By default form submits are remote and unobtrusive XHRs
13
- # * <tt>skip_enforcing_utf8<tt> - If set to true, a hidden input with name utf8 is not output
14
- # * <tt>builder<tt> - Override the object used to build the form
15
- # * <tt>html<tt> - Other optional HTML attributes for the form tag
16
- # * <tt>id<tt> - Optional HTML id attribute
17
- # * <tt>class<tt> - Optional HTML class attribute
18
- # * <tt>data<tt> - Optional HTML data attributes
5
+ # * +model+ - A model to infer :url and :scope
6
+ # * +scope+ - The scope to prefix input field names with
7
+ # * +url+ - The URL the form submits to
8
+ # * +format+ - The format of the route the form submits to
9
+ # * +namespace+ - A namespace for your form to ensure uniqueness of id attributes on form elements
10
+ # * +method+ - The method to use when submitting the form
11
+ # * +authenticity_token+ - Authenticity token to use in the form
12
+ # * +local+ - By default form submits are remote and unobtrusive XHRs
13
+ # * +skip_enforcing_utf8+ - If set to true, a hidden input with name utf8 is not output
14
+ # * +builder+ - Override the object used to build the form
15
+ # * +html+ - Other optional HTML attributes for the form tag
16
+ # * +id+ - Optional HTML id attribute
17
+ # * +class+ - Optional HTML class attribute
18
+ # * +data+ - Optional HTML data attributes
19
19
  #
20
20
  # === Examples
21
21
  # Basic version
@@ -9,5 +9,5 @@
9
9
  %>
10
10
 
11
11
  <div class="h-heading d-flex flex-column flex-md-row align-items-start align-items-md-end justify-content-between">
12
- <%= yield if block_given? %>
12
+ <%= yield %>
13
13
  </div>
@@ -8,7 +8,7 @@
8
8
 
9
9
  <div class="toast-container position-absolute top-0 end-0 p-3">
10
10
  <% flash.each do |name, message| %>
11
- <div class="toast align-items-center text-white show <%= notification_color(name.to_sym)[:background] %>" role="alert" aria-live="assertive" aria-atomic="true">
11
+ <div class="toast align-items-center text-white show <%= notification_color(name.to_sym)[:background] %>" role="alert" aria-live="assertive" aria-atomic="true" data-controller="toast">
12
12
  <div class="d-flex">
13
13
  <div class="toast-body <%= notification_color(name.to_sym)[:text] %>">
14
14
  <%= message %>
@@ -2,7 +2,7 @@
2
2
  # headmin/notifications
3
3
  #
4
4
  # ==== Options
5
- # * <tt>collection</tt> - Kaminari collection that accepts a method .total_count
5
+ # * +collection</tt> - Kaminari collection that accepts a method .total_count
6
6
  #
7
7
  # ==== Examples
8
8
  # Basic version
@@ -2,7 +2,7 @@
2
2
  # headmin/popup
3
3
  #
4
4
  # ==== Options
5
- # * <tt>id</tt> - Identifier for this popup
5
+ # * +id</tt> - Identifier for this popup
6
6
  #
7
7
  # ==== Examples
8
8
  # To trigger this popup create an element with a data attribute like this
@@ -19,8 +19,14 @@
19
19
  # <%= render 'headmin/popup', id: 'popupId' do %#>
20
20
  # <a href="https://example.com" id="link">
21
21
  # <% end %#>
22
+ data = local_assigns.has_key?(:data) ? data : {}
23
+
24
+ options = {
25
+ class: ['h-popup', 'closed'],
26
+ data: data.merge('popup-target': 'popup', 'popup-id': id)
27
+ }
22
28
  %>
23
29
 
24
- <div class="h-popup closed" data-popup-target="popup" data-popup-id="<%= id %>">
25
- <%= yield if block_given? %>
26
- </div>
30
+ <%= content_tag(:div, options) do %>
31
+ <%= yield %>
32
+ <% end %>
@@ -2,7 +2,7 @@
2
2
  # headmin/table
3
3
  #
4
4
  # ==== Options
5
- # * <tt>sort_url</tt> - Url to post object ids to in the order of positions
5
+ # * +sort_url</tt> - Url to post object ids to in the order of positions
6
6
  #
7
7
  # ==== Examples
8
8
  # <%= render 'headmin/table', sort_url: positions_admin_categories_path do %#>
@@ -20,7 +20,7 @@
20
20
  data-table-target="table"
21
21
  data-table-url-value="<%= sort_url %>"
22
22
  data-table-count-value="<%= total_count %>">
23
- <%= yield if block_given? %>
23
+ <%= yield %>
24
24
  </table>
25
25
  </div>
26
26
  </div>
@@ -0,0 +1,47 @@
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 %#>
20
+
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>
36
+ <% else %>
37
+ <div class="h-thumbnail-bg">
38
+ <%= src ? File.extname(src) : 'nil' %>
39
+ <%= mime_type %>
40
+ <% if mime_type %>
41
+ <%= bootstrap_icon_for_mime_type(mime_type, class: 'h-thumbnail-icon') %>
42
+ <% else %>
43
+ <%= bootstrap_icon('question', class: 'h-thumbnail-icon') %>
44
+ <% end %>
45
+ </div>
46
+ <% end %>
47
+ </div>
@@ -2,8 +2,8 @@
2
2
  # headmin/dropdown/devise
3
3
  #
4
4
  # ==== Options
5
- # * <tt>scope</tt> - (symbol) devise scope, i.e. ':users' => current_user
6
- # * <tt>class</tt> - Custom class names to put on the dropdown
5
+ # * +scope</tt> - (symbol) devise scope, i.e. ':users' => current_user
6
+ # * +class</tt> - Custom class names to put on the dropdown
7
7
  #
8
8
  # ==== Examples
9
9
  # Basic version