headmin 0.1.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 (175) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.nvmrc +1 -0
  4. data/.rubocop.yml +13 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +43 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +166 -0
  12. data/Rakefile +16 -0
  13. data/app/assets/images/avatar.jpg +0 -0
  14. data/app/controllers/admin/users/confirmations_controller.rb +31 -0
  15. data/app/controllers/admin/users/omniauth_callbacks_controller.rb +31 -0
  16. data/app/controllers/admin/users/passwords_controller.rb +35 -0
  17. data/app/controllers/admin/users/registrations_controller.rb +63 -0
  18. data/app/controllers/admin/users/sessions_controller.rb +28 -0
  19. data/app/controllers/admin/users/unlocks_controller.rb +31 -0
  20. data/app/controllers/concerns/headmin/acts_as_list.rb +16 -0
  21. data/app/controllers/concerns/headmin/authentication.rb +17 -0
  22. data/app/controllers/concerns/headmin/ckeditor.rb +27 -0
  23. data/app/controllers/concerns/headmin/filter.rb +5 -0
  24. data/app/controllers/concerns/headmin/pagination.rb +23 -0
  25. data/app/controllers/concerns/headmin/searchable.rb +15 -0
  26. data/app/controllers/concerns/headmin/sortable.rb +44 -0
  27. data/app/helpers/headmin/admin_helper.rb +65 -0
  28. data/app/helpers/headmin/filter_helper.rb +12 -0
  29. data/app/helpers/headmin/notification_helper.rb +31 -0
  30. data/app/views/admin/users/confirmations/new.html.erb +9 -0
  31. data/app/views/admin/users/mailer/confirmation_instructions.html.erb +5 -0
  32. data/app/views/admin/users/mailer/email_changed.html.erb +7 -0
  33. data/app/views/admin/users/mailer/password_change.html.erb +3 -0
  34. data/app/views/admin/users/mailer/reset_password_instructions.html.erb +8 -0
  35. data/app/views/admin/users/mailer/unlock_instructions.html.erb +7 -0
  36. data/app/views/admin/users/passwords/edit.html.erb +12 -0
  37. data/app/views/admin/users/passwords/new.html.erb +9 -0
  38. data/app/views/admin/users/registrations/edit.html.erb +24 -0
  39. data/app/views/admin/users/registrations/new.html.erb +11 -0
  40. data/app/views/admin/users/sessions/new.html.erb +13 -0
  41. data/app/views/admin/users/shared/_error_messages.html.erb +7 -0
  42. data/app/views/admin/users/shared/_links.html.erb +27 -0
  43. data/app/views/admin/users/unlocks/new.html.erb +10 -0
  44. data/app/views/headmin/_breadcrumbs.html.erb +23 -0
  45. data/app/views/headmin/_filters.html.erb +47 -0
  46. data/app/views/headmin/_form.html.erb +11 -0
  47. data/app/views/headmin/_heading.html.erb +9 -0
  48. data/app/views/headmin/_index.html.erb +12 -0
  49. data/app/views/headmin/_notifications.html.erb +12 -0
  50. data/app/views/headmin/_pagination.html.erb +13 -0
  51. data/app/views/headmin/_table.html.erb +13 -0
  52. data/app/views/headmin/filters/_date.html.erb +46 -0
  53. data/app/views/headmin/filters/_search.html.erb +22 -0
  54. data/app/views/headmin/filters/_select.html.erb +39 -0
  55. data/app/views/headmin/filters/filter/_button.html.erb +22 -0
  56. data/app/views/headmin/filters/filter/_menu_item.html.erb +12 -0
  57. data/app/views/headmin/filters/filter/_template.html.erb +13 -0
  58. data/app/views/headmin/forms/_actions.html.erb +32 -0
  59. data/app/views/headmin/forms/_errors.html.erb +20 -0
  60. data/app/views/headmin/forms/_group.html.erb +36 -0
  61. data/app/views/headmin/forms/fields/_checkbox.html.erb +23 -0
  62. data/app/views/headmin/forms/fields/_ckeditor.html.erb +28 -0
  63. data/app/views/headmin/forms/fields/_currency.html.erb +24 -0
  64. data/app/views/headmin/forms/fields/_date.html.erb +36 -0
  65. data/app/views/headmin/forms/fields/_email.html.erb +39 -0
  66. data/app/views/headmin/forms/fields/_file.html.erb +24 -0
  67. data/app/views/headmin/forms/fields/_image.html.erb +37 -0
  68. data/app/views/headmin/forms/fields/_label.html.erb +9 -0
  69. data/app/views/headmin/forms/fields/_multiple_select.html.erb +37 -0
  70. data/app/views/headmin/forms/fields/_password.html.erb +39 -0
  71. data/app/views/headmin/forms/fields/_repeater.html.erb +48 -0
  72. data/app/views/headmin/forms/fields/_select.html.erb +36 -0
  73. data/app/views/headmin/forms/fields/_select_tags.html.erb +32 -0
  74. data/app/views/headmin/forms/fields/_text.html.erb +39 -0
  75. data/app/views/headmin/forms/fields/_textarea.html.erb +29 -0
  76. data/app/views/headmin/forms/fields/_url.html.erb +38 -0
  77. data/app/views/headmin/forms/fields/_validation.html.erb +12 -0
  78. data/app/views/headmin/forms/fields/repeater/_row.html.erb +16 -0
  79. data/app/views/headmin/heading/_title.html.erb +24 -0
  80. data/app/views/headmin/kaminari/_first_page.html.erb +11 -0
  81. data/app/views/headmin/kaminari/_gap.html.erb +12 -0
  82. data/app/views/headmin/kaminari/_last_page.html.erb +12 -0
  83. data/app/views/headmin/kaminari/_next_page.html.erb +13 -0
  84. data/app/views/headmin/kaminari/_page.html.erb +12 -0
  85. data/app/views/headmin/kaminari/_paginator.html.erb +25 -0
  86. data/app/views/headmin/kaminari/_prev_page.html.erb +11 -0
  87. data/app/views/headmin/layout/_body.html.erb +9 -0
  88. data/app/views/headmin/layout/_content.html.erb +9 -0
  89. data/app/views/headmin/layout/_footer.html.erb +17 -0
  90. data/app/views/headmin/layout/_header.html.erb +13 -0
  91. data/app/views/headmin/layout/_main.html.erb +13 -0
  92. data/app/views/headmin/layout/_sidebar.html.erb +20 -0
  93. data/app/views/headmin/layout/dropdown/_divider.html.erb +9 -0
  94. data/app/views/headmin/layout/dropdown/_item.html.erb +17 -0
  95. data/app/views/headmin/layout/header/_account.html.erb +25 -0
  96. data/app/views/headmin/layout/header/_locale.html.erb +19 -0
  97. data/app/views/headmin/layout/sidebar/_bottom.html.erb +4 -0
  98. data/app/views/headmin/layout/sidebar/_menu.html.erb +9 -0
  99. data/app/views/headmin/layout/sidebar/menu/_account.html.erb +25 -0
  100. data/app/views/headmin/layout/sidebar/menu/_item.html.erb +16 -0
  101. data/app/views/headmin/layout/sidebar/menu/_locale.html.erb +18 -0
  102. data/app/views/headmin/table/_actions.html.erb +19 -0
  103. data/app/views/headmin/table/_body.html.erb +19 -0
  104. data/app/views/headmin/table/_foot.html.erb +15 -0
  105. data/app/views/headmin/table/_footer.html.erb +13 -0
  106. data/app/views/headmin/table/_head.html.erb +15 -0
  107. data/app/views/headmin/table/_header.html.erb +13 -0
  108. data/app/views/headmin/table/actions/_action.html.erb +10 -0
  109. data/app/views/headmin/table/actions/_delete.html.erb +8 -0
  110. data/app/views/headmin/table/actions/_export.html.erb +8 -0
  111. data/app/views/headmin/table/body/_association.html.erb +11 -0
  112. data/app/views/headmin/table/body/_boolean.erb +16 -0
  113. data/app/views/headmin/table/body/_currency.html.erb +10 -0
  114. data/app/views/headmin/table/body/_date.html.erb +11 -0
  115. data/app/views/headmin/table/body/_id.html.erb +3 -0
  116. data/app/views/headmin/table/body/_row.html.erb +9 -0
  117. data/app/views/headmin/table/body/_sort.html.erb +3 -0
  118. data/app/views/headmin/table/body/_string.html.erb +16 -0
  119. data/app/views/headmin/table/body/_text.html.erb +10 -0
  120. data/app/views/headmin/table/foot/_cell.html.erb +10 -0
  121. data/app/views/headmin/table/foot/_id.html.erb +9 -0
  122. data/app/views/headmin/table/head/_cell.html.erb +13 -0
  123. data/app/views/headmin/table/head/_empty.html.erb +1 -0
  124. data/app/views/headmin/table/head/_id.html.erb +9 -0
  125. data/app/views/headmin/table/head/_sort.html.erb +3 -0
  126. data/app/views/headmin/table/head/cell/_asc.html.erb +4 -0
  127. data/app/views/headmin/table/head/cell/_default.html.erb +7 -0
  128. data/app/views/headmin/table/head/cell/_desc.html.erb +4 -0
  129. data/app/views/layouts/admin/auth.html.erb +20 -0
  130. data/app/views/layouts/admin.html.erb +42 -0
  131. data/bin/console +15 -0
  132. data/bin/setup +8 -0
  133. data/config/locales/defaults/en.yml +215 -0
  134. data/config/locales/defaults/nl.yml +213 -0
  135. data/config/locales/devise/nl.yml +85 -0
  136. data/config/locales/en.yml +137 -0
  137. data/config/locales/nl.yml +138 -0
  138. data/dist/css/headmin.css +9874 -0
  139. data/dist/js/headmin.js +852 -0
  140. data/docs/README.md +4 -0
  141. data/docs/blocks.md +116 -0
  142. data/docs/devise.md +62 -0
  143. data/headmin.gemspec +35 -0
  144. data/lib/headmin/engine.rb +10 -0
  145. data/lib/headmin/version.rb +5 -0
  146. data/lib/headmin.rb +4 -0
  147. data/package.json +62 -0
  148. data/src/js/headmin/controllers/filter_controller.js +47 -0
  149. data/src/js/headmin/controllers/filters_controller.js +53 -0
  150. data/src/js/headmin/controllers/index_controller.js +79 -0
  151. data/src/js/headmin/controllers/repeater_controller.js +35 -0
  152. data/src/js/headmin/controllers/repeater_row_controller.js +54 -0
  153. data/src/js/headmin/controllers/table_actions_controller.js +22 -0
  154. data/src/js/headmin/controllers/table_controller.js +36 -0
  155. data/src/js/headmin/headmin.js +168 -0
  156. data/src/js/headmin.js +1 -0
  157. data/src/scss/headmin/filter.scss +33 -0
  158. data/src/scss/headmin/filters.scss +14 -0
  159. data/src/scss/headmin/form.scss +39 -0
  160. data/src/scss/headmin/general.scss +3 -0
  161. data/src/scss/headmin/layout/body.scss +6 -0
  162. data/src/scss/headmin/layout/sidebar.scss +22 -0
  163. data/src/scss/headmin/layout.scss +2 -0
  164. data/src/scss/headmin/login.scss +35 -0
  165. data/src/scss/headmin/table.scss +32 -0
  166. data/src/scss/headmin/utilities.scss +19 -0
  167. data/src/scss/headmin.scss +58 -0
  168. data/src/scss/vendor/bootstrap/variables.scss +71 -0
  169. data/src/scss/vendor/choices/cross-inverse.svg +6 -0
  170. data/src/scss/vendor/choices/cross.svg +6 -0
  171. data/src/scss/vendor/choices/custom.scss +28 -0
  172. data/src/scss/vendor/choices/variables.scss +16 -0
  173. data/webpack.config.js +30 -0
  174. data/yarn.lock +7512 -0
  175. metadata +220 -0
@@ -0,0 +1,22 @@
1
+ <%#
2
+ name: headmin/filters/filter/button
3
+ accepts block: yes
4
+ parameters:
5
+ name: (string) Name of the parameter
6
+ label: (string) Display name
7
+ value: (string) Value of the parameter
8
+ %>
9
+ <% name = local_assigns.has_key?(:name) ? name : nil %>
10
+ <% label = local_assigns.has_key?(:label) ? label : nil %>
11
+ <% value = local_assigns.has_key?(:value) ? value : nil %>
12
+ <% active = local_assigns.has_key?(:active) ? active : false %>
13
+
14
+ <div class="h-filter me-1" data-controller="filter" data-filters-target="button" data-filter-name="<%= name %>">
15
+ <button type="button" class="h-filter-button btn h-btn-outline-transparent ms-1" data-filter-target="button" data-action="click->filter#toggle click@window->filter#close" aria-expanded="<%= active ? 'true' : 'false' %>">
16
+ <%= "#{label}: #{value || t('.all')}" %>
17
+ <span class="h-filter-remove" data-action="click->filters#remove"><%= bootstrap_icon('x-lg') %></span>
18
+ </button>
19
+ <div class="h-filter-popup <%= ('closed' unless active) %>" data-filter-target="popup">
20
+ <%= yield if block_given? %>
21
+ </div>
22
+ </div>
@@ -0,0 +1,12 @@
1
+ <%#
2
+ name: headmin/filters/filter/menu_item
3
+ accepts block: no
4
+ parameters:
5
+ name: (string) Name of the parameter
6
+ label: (string) Display name
7
+ %>
8
+ <li>
9
+ <a class="dropdown-item" href="#" data-action="click->filters#add" data-filter-name="<%= name %>">
10
+ <%= label %>
11
+ </a>
12
+ </li>
@@ -0,0 +1,13 @@
1
+ <%#
2
+ name: headmin/filters/filter/template
3
+ accepts block: yes
4
+ parameters:
5
+ name: (string) Name of the parameter
6
+ label: (string) Display name
7
+ %>
8
+
9
+ <template data-filter-name="<%= name %>" data-filters-target="template">
10
+ <%= render 'headmin/filters/filter/button', name: name, label: label, value: nil, active: true do %>
11
+ <%= yield if block_given? %>
12
+ <% end %>
13
+ </template>
@@ -0,0 +1,32 @@
1
+ <%#
2
+ name: headmin/forms/actions
3
+ accepts block: true
4
+ parameters:
5
+ form: (string) Form object
6
+ %>
7
+
8
+ <div class="card forms-actions shadow-sm mb-3">
9
+ <div class="card-body">
10
+ <h5 class="card-title"><%= t('.title') %></h5>
11
+ <p class="card-text"><%= t('.description') %></p>
12
+
13
+ <% if form.object.persisted? %>
14
+ <dl>
15
+ <dt><%= form.object.class.human_attribute_name(:created_at) %></dt>
16
+ <dd><%= form.object.created_at.strftime(t('.format')) %></dd>
17
+ <dt><%= form.object.class.human_attribute_name(:updated_at) %></dt>
18
+ <dd><%= form.object.updated_at.strftime(t('.format')) %></dd>
19
+ </dl>
20
+ <% end %>
21
+
22
+ <%= yield if block_given? %>
23
+
24
+ <div class="d-grid">
25
+ <%= link_to(t('.delete.title'),[:admin, form.object], class: 'btn btn-outline-danger', method: :delete, data: {confirm: t('.delete.confirm')}) %>
26
+ </div>
27
+ <hr>
28
+ <div class="d-grid">
29
+ <%= form.submit "Opslaan", class: 'btn btn-lg btn-primary' %>
30
+ </div>
31
+ </div>
32
+ </div>
@@ -0,0 +1,20 @@
1
+ <%#
2
+ name: headmin/forms/errors
3
+ accepts block: false
4
+ parameters:
5
+ form: (string) Form object
6
+ %>
7
+
8
+ <% if form.object.errors.any? %>
9
+ <div class="alert alert-danger" role="alert">
10
+ <h5 class="alert-heading d-flex align-items-center">
11
+ <%= bootstrap_icon('exclamation-triangle-fill', class: 'me-2') %>
12
+ <%= t('errors.template.header', count: form.object.errors.size, model: form.object.model_name.human) %>
13
+ </h5>
14
+ <ul>
15
+ <% form.object.errors.full_messages.each do |message| %>
16
+ <li><%= message %></li>
17
+ <% end %>
18
+ </ul>
19
+ </div>
20
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <%#
2
+ name: headmin/forms/group
3
+ accepts block: yes
4
+ parameters:
5
+ title: (string) Title for card
6
+ description: (string) Description for card
7
+ body: (boolean) If true, block contents will be renderd inside the card body
8
+ %>
9
+
10
+ <div class="card forms-group mb-3 shadow-sm">
11
+ <div class="card-body">
12
+ <% if defined?(title) && title.present? %>
13
+ <h5 class="card-title"><%= title %></h5>
14
+ <% end %>
15
+
16
+ <% if defined?(description) && description.present? %>
17
+ <p class="card-text text-secondary"><%= description %></p>
18
+ <% end %>
19
+
20
+ <% # Render inside body %>
21
+ <% if !defined?(body) || body %>
22
+ <%= yield if block_given? %>
23
+ <% end %>
24
+ </div>
25
+
26
+ <% # Render outside body %>
27
+ <% if defined?(body) && !body %>
28
+ <%= yield if block_given? %>
29
+ <% end %>
30
+
31
+ <div class="card-footer">
32
+ <div class="d-flex justify-content-end">
33
+ <%= form.submit "Opslaan", class: 'btn btn-sm btn-primary' %>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,23 @@
1
+ <%#
2
+ name: headmin/fields/checkbox
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% required = local_assigns.has_key?(:required) ? required : false %>
12
+ <div class="<%= ('mb-3 text-start' if label) %>">
13
+ <div class="form-check">
14
+ <%= form.check_box(
15
+ attribute,
16
+ class: "form-check-input #{form_field_validation_class(form, attribute)}",
17
+ required: required,
18
+ 'aria-describedby': form_field_validation_id(form, attribute))
19
+ %>
20
+ <%= form.label attribute, class: 'form-check-label', required: required %>
21
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
22
+ </div>
23
+ </div>
@@ -0,0 +1,28 @@
1
+ <%#
2
+ name: headmin/fields/ckeditor
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ class: (string) Space-separated string of html class names
9
+ toolbar: (Array[]) Array contanining the toolbar items to display
10
+ upload_path: (string) URL to upload images to
11
+ %>
12
+
13
+ <% label = local_assigns.has_key?(:label) ? label : true %>
14
+ <% required = local_assigns.has_key?(:required) ? required : false %>
15
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
16
+ <% toolbar = local_assigns.has_key?(:toolbar) ? toolbar : nil %>
17
+ <% upload_path = local_assigns.has_key?(:upload_path) ? upload_path : admin_wysiwyg_upload_path %>
18
+ <%= render 'headmin/forms/fields/textarea',
19
+ form: form,
20
+ attribute: :content,
21
+ required: required,
22
+ class: "ckeditor #{class_names}",
23
+ label: label,
24
+ data: {
25
+ 'ckeditor-toolbar': toolbar,
26
+ 'ckeditor-upload-path': upload_path
27
+ }
28
+ %>
@@ -0,0 +1,24 @@
1
+ <%#
2
+ name: headmin/fields/currency
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% required = local_assigns.has_key?(:required) ? required : false %>
12
+ <div class="<%= ('mb-3' if label) %>">
13
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
14
+ <div class="input-group">
15
+ <span class="input-group-text">€</span>
16
+ <%= form.text_field(
17
+ attribute,
18
+ class: "form-control #{form_field_validation_class(form, attribute)}",
19
+ required: required,
20
+ 'aria-describedby': form_field_validation_id(form, attribute))
21
+ %>
22
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
23
+ </div>
24
+ </div>
@@ -0,0 +1,36 @@
1
+ <%#
2
+ name: headmin/fields/date
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ min: (string) Earliest available timestamp in options
9
+ max: (string) Last available timestamp in options
10
+ %>
11
+
12
+ <% label = local_assigns.has_key?(:label) ? label : true %>
13
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
14
+ <% required = local_assigns.has_key?(:required) ? required : false %>
15
+ <% readonly = local_assigns.has_key?(:readonly) ? readonly : false %>
16
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
17
+ <% datepicker = local_assigns.has_key?(:datepicker) ? local_assigns[:datepicker] : false %>
18
+ <% datepicker_class = datepicker ? 'flatpickr' : nil %>
19
+ <% validation_class = form_field_validation_class(form, attribute) %>
20
+ <div class="<%= ('mb-3' if label) %>">
21
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
22
+ <div class="input-group">
23
+ <span class="input-group-text"><%= bootstrap_icon('calendar') %></span>
24
+ <%= form.date_field(
25
+ attribute,
26
+ placeholder: 'dd/mm/yyyy',
27
+ class: "form-control #{validation_class} #{datepicker_class} #{class_names}",
28
+ disabled: disabled,
29
+ required: required,
30
+ readonly: readonly,
31
+ 'aria-describedby': form_field_validation_id(form, attribute)
32
+ )
33
+ %>
34
+ </div>
35
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
36
+ </div>
@@ -0,0 +1,39 @@
1
+ <%#
2
+ name: headmin/fields/text
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool | string) Label will not be displayed if value is false or accepts a string 'float' to get a "floating label"
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% float_label = label == :float %>
12
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% readonly = local_assigns.has_key?(:readonly) ? readonly : false %>
15
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
16
+ <% has_list = local_assigns.has_key?(:collection) %>
17
+ <div class="<%= 'form-floating' if float_label %> <%= ('mb-3 text-start' if label) %> ">
18
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && !float_label %>
19
+ <%= form.email_field(
20
+ attribute,
21
+ class: "form-control #{form_field_validation_class(form, attribute)} #{class_names}",
22
+ list: has_list ? attribute : nil,
23
+ disabled: disabled,
24
+ placeholder: attribute,
25
+ required: required,
26
+ readonly: readonly,
27
+ 'aria-describedby': form_field_validation_id(form, attribute)
28
+ )
29
+ %>
30
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && float_label %>
31
+ <% if has_list %>
32
+ <datalist id="<%= attribute %>">
33
+ <% collection.each do |key, value| %>
34
+ <option value="<%= value %>"><%= key %></option>
35
+ <% end %>
36
+ </datalist>
37
+ <% end %>
38
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
39
+ </div>
@@ -0,0 +1,24 @@
1
+ <%#
2
+ name: headmin/fields/file
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
12
+ <% required = local_assigns.has_key?(:required) ? required : false %>
13
+ <div class="<%= ('mb-3' if label) %>">
14
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
15
+ <%= form.file_field(
16
+ attribute,
17
+ class: "form-control #{form_field_validation_class(form, attribute)}",
18
+ disabled: disabled,
19
+ required: required,
20
+ 'aria-describedby': form_field_validation_id(form, attribute)
21
+ )
22
+ %>
23
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
24
+ </div>
@@ -0,0 +1,37 @@
1
+ <%#
2
+ name: headmin/fields/file
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool) Label will not be displayed if value is false
8
+ %>
9
+
10
+ <% has_image = form.object.send(attribute) %>
11
+ <% label = local_assigns.has_key?(:label) ? label : true %>
12
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
13
+ <% required = local_assigns.has_key?(:required) && !has_image ? required : false %>
14
+ <div class="<%= ('mb-3' if label) %>">
15
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
16
+
17
+ <div class="mb-2">
18
+ <% if form.object.send(attribute).attached? %>
19
+ <%= image_tag(form.object.send(attribute).variant(resize_to_limit: [200, 200], quality: 70), class: 'img-thumbnail') %>
20
+ <% else %>
21
+ <svg class="img-thumbnail" width="200" height="200" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera: 200x200" preserveAspectRatio="xMidYMid slice" focusable="false">
22
+ <title>A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera</title>
23
+ <rect width="100%" height="100%" fill="#e9ecef"></rect>
24
+ <text x="35%" y="50%" fill="#212529" dy=".3em">200x200</text>
25
+ </svg>
26
+ <% end %>
27
+ </div>
28
+
29
+ <%= form.file_field(
30
+ attribute,
31
+ class: "form-control #{form_field_validation_class(form, attribute)}",
32
+ disabled: disabled,
33
+ required: required,
34
+ 'aria-describedby': form_field_validation_id(form, attribute))
35
+ %>
36
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
37
+ </div>
@@ -0,0 +1,9 @@
1
+ <%#
2
+ name: headmin/fields/label
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ required: (bool) Field will be set to required if value is true
7
+ %>
8
+
9
+ <%= form.label attribute, class: 'form-label', required: required %>
@@ -0,0 +1,37 @@
1
+ <%#
2
+ name: headmin/fields/multiple_select
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ required: Define if the attribute is required or not
7
+ attribute: (string) Name of the attribute of the form model
8
+ label: (bool) Label will not be displayed if value is false
9
+ collection: (array) List of options to select from
10
+ %>
11
+
12
+ <% label = local_assigns.has_key?(:label) ? label : true %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
15
+ <% include_blank = local_assigns.has_key?(:include_blank) || required ? t('.blank') : nil %>
16
+ <% data_attributes = local_assigns.select { |key, value| key.to_s.include?("data-") } %>
17
+ <% options = options_for_select(collection, form.object.send(attribute)) %>
18
+ <% select_config = { include_blank: include_blank, disabled: disabled } %>
19
+ <% html_attributes = {
20
+ multiple: true,
21
+ class: "multiple-select form-select #{form_field_validation_class(form, attribute)}",
22
+ required: required,
23
+ 'aria-describedby': form_field_validation_id(form, attribute)
24
+ }.merge(data_attributes) %>
25
+
26
+ <div class="<%= ('mb-3' if label) %>">
27
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
28
+ <%= form.select(
29
+ attribute,
30
+ options,
31
+ select_config,
32
+ html_attributes
33
+ )
34
+ %>
35
+ <%= yield if block_given? %>
36
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
37
+ </div>
@@ -0,0 +1,39 @@
1
+ <%#
2
+ name: headmin/fields/text
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool | string) Label will not be displayed if value is false or accepts a string 'float' to get a "floating label"
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% float_label = label == :float %>
12
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% readonly = local_assigns.has_key?(:readonly) ? readonly : false %>
15
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
16
+ <% has_list = local_assigns.has_key?(:collection) %>
17
+ <div class="<%= 'form-floating' if float_label %> <%= ('mb-3 text-start' if label) %>">
18
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && !float_label %>
19
+ <%= form.password_field(
20
+ attribute,
21
+ class: "form-control #{form_field_validation_class(form, attribute)} #{class_names}",
22
+ list: has_list ? attribute : nil,
23
+ disabled: disabled,
24
+ placeholder: attribute,
25
+ required: required,
26
+ readonly: readonly,
27
+ 'aria-describedby': form_field_validation_id(form, attribute)
28
+ )
29
+ %>
30
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && float_label %>
31
+ <% if has_list %>
32
+ <datalist id="<%= attribute %>">
33
+ <% collection.each do |key, value| %>
34
+ <option value="<%= value %>"><%= key %></option>
35
+ <% end %>
36
+ </datalist>
37
+ <% end %>
38
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
39
+ </div>
@@ -0,0 +1,48 @@
1
+ <%#
2
+ name: headmin/fields/repeater
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ title: (string) Title of the field group
8
+ description: (string) Description of the field group
9
+ %>
10
+
11
+ <% object_model = form.object.class %>
12
+ <% association_model = object_model.reflect_on_association(attribute).class_name.constantize %>
13
+ <% repeater_id = form.object_id %>
14
+ <div class="repeater" data-controller="repeater" data-repeater-id-value="<%= repeater_id %>">
15
+
16
+ <% if defined?(title) && title.present? %>
17
+ <h5><%= title %></h5>
18
+ <p><%= description %></p>
19
+ <% end %>
20
+
21
+ <ul class="list-group list-group-flush">
22
+ <template data-repeater-target="template">
23
+ <%= form.fields_for attribute, association_model.new, child_index: repeater_id do |ff| %>
24
+ <%= render 'headmin/forms/fields/repeater/row', form: form do %>
25
+ <%= render template, form: ff %>
26
+ <% end %>
27
+ <% end %>
28
+ </template>
29
+
30
+ <% if defined?(header_template) && header_template.present? %>
31
+ <li class="list-group-item">
32
+ <%= render header_template %>
33
+ </li>
34
+ <% end %>
35
+
36
+ <%= form.fields_for attribute do |ff| %>
37
+ <%= render 'headmin/forms/fields/repeater/row', form: form do %>
38
+ <%= render template, form: ff %>
39
+ <% end %>
40
+ <% end %>
41
+ <li class="list-group-item d-flex justify-content-end" data-repeater-target="links">
42
+ <a href="#" class="btn btn-sm h-btn-outline-light" data-action="click->repeater#add_association">
43
+ <%= bootstrap_icon('plus') %>
44
+ <%= t('.add', name: association_model.model_name.human) %>
45
+ </a>
46
+ </li>
47
+ </ul>
48
+ </div>
@@ -0,0 +1,36 @@
1
+ <%#
2
+ name: headmin/fields/select
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ required: Define if the attribute is required or not
7
+ attribute: (string) Name of the attribute of the form model
8
+ label: (bool) Label will not be displayed if value is false
9
+ collection: (array) List of options to select from
10
+ %>
11
+
12
+ <% label = local_assigns.has_key?(:label) ? label : true %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
15
+ <% include_blank = local_assigns.has_key?(:include_blank) || required ? t('.blank') : nil %>
16
+ <% data_attributes = local_assigns.select { |key, value| key.to_s.include?("data-") } %>
17
+ <% options = options_for_select(collection, form.object.send(attribute)) %>
18
+ <% select_config = { include_blank: include_blank, disabled: disabled } %>
19
+ <% html_attributes = {
20
+ class: "form-select #{form_field_validation_class(form, attribute)}",
21
+ required: required,
22
+ 'aria-describedby': form_field_validation_id(form, attribute)
23
+ }.merge(data_attributes) %>
24
+
25
+ <div class="<%= ('mb-3' if label) %>">
26
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
27
+ <%= form.select(
28
+ attribute,
29
+ options,
30
+ select_config,
31
+ html_attributes
32
+ )
33
+ %>
34
+ <%= yield if block_given? %>
35
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
36
+ </div>
@@ -0,0 +1,32 @@
1
+ <%#
2
+ name: headmin/fields/select_tags
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ required: Define if the attribute is required or not
7
+ attribute: (string) Name of the attribute of the form model
8
+ label: (bool) Label will not be displayed if value is false
9
+ collection: (array) List of options to select from
10
+ %>
11
+
12
+ <% label = local_assigns.has_key?(:label) ? label : true %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
15
+ <% multiple = local_assigns.has_key?(:multiple) ? multiple : true %>
16
+ <% include_blank = local_assigns.has_key?(:include_blank) || required ? t('.blank') : nil %>
17
+ <% data_attributes = local_assigns.select { |key, value| key.to_s.include?("data-") } %>
18
+ <% options = options_for_select(collection, form.object.send(attribute)) %>
19
+ <% select_config = { include_blank: include_blank, disabled: disabled } %>
20
+ <% html_attributes = {
21
+ multiple: multiple,
22
+ class: "select-tags form-select #{form_field_validation_class(form, attribute)}",
23
+ required: required,
24
+ 'aria-describedby': form_field_validation_id(form, attribute)
25
+ }.merge(data_attributes) %>
26
+
27
+ <div class="<%= ('mb-3' if label) %>">
28
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label %>
29
+ <%= form.select attribute, options, select_config, html_attributes %>
30
+ <%= yield if block_given? %>
31
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
32
+ </div>
@@ -0,0 +1,39 @@
1
+ <%#
2
+ name: headmin/fields/text
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool | string) Label will not be displayed if value is false or accepts a string 'float' to get a "floating label"
8
+ %>
9
+
10
+ <% label = local_assigns.has_key?(:label) ? label : true %>
11
+ <% float_label = label == :float %>
12
+ <% disabled = local_assigns.has_key?(:disabled) ? disabled : false %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% readonly = local_assigns.has_key?(:readonly) ? readonly : false %>
15
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
16
+ <% has_list = local_assigns.has_key?(:collection) %>
17
+ <div class="<%= 'form-floating' if float_label %> <%= ('mb-3 text-start' if label) %>">
18
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && !float_label %>
19
+ <%= form.text_field(
20
+ attribute,
21
+ class: "form-control #{form_field_validation_class(form, attribute)} #{class_names}",
22
+ list: has_list ? attribute : nil,
23
+ disabled: disabled,
24
+ required: required,
25
+ placeholder: attribute,
26
+ readonly: readonly,
27
+ 'aria-describedby': form_field_validation_id(form, attribute)
28
+ )
29
+ %>
30
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && float_label %>
31
+ <% if has_list %>
32
+ <datalist id="<%= attribute %>">
33
+ <% collection.each do |key, value| %>
34
+ <option value="<%= value %>"><%= key %></option>
35
+ <% end %>
36
+ </datalist>
37
+ <% end %>
38
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
39
+ </div>
@@ -0,0 +1,29 @@
1
+ <%#
2
+ name: headmin/fields/textarea
3
+ accepts block: no
4
+ parameters:
5
+ form: Form object
6
+ attribute: (string) Name of the attribute of the form model
7
+ label: (bool | string) Label will not be displayed if value is false or accepts a string 'float' to get a "floating label"
8
+
9
+ %>
10
+
11
+ <% label = local_assigns.has_key?(:label) ? label : true %>
12
+ <% float_label = label == :float %>
13
+ <% required = local_assigns.has_key?(:required) ? required : false %>
14
+ <% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false %>
15
+ <% data = local_assigns.has_key?(:data) ? data : nil %>
16
+ <div class="<%= 'form-floating' if float_label %> <%= ('mb-3 text-start' if label) %>">
17
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && !float_label %>
18
+ <%= form.text_area(
19
+ attribute,
20
+ class: "form-control #{class_names} #{form_field_validation_class(form, attribute)}",
21
+ required: required,
22
+ placeholder: attribute,
23
+ 'aria-describedby': form_field_validation_id(form, attribute),
24
+ data: data
25
+ )
26
+ %>
27
+ <%= render 'headmin/forms/fields/label', form: form, attribute: attribute, required: required if label && float_label %>
28
+ <%= render 'headmin/forms/fields/validation', form: form, attribute: attribute %>
29
+ </div>