headmin 0.2.4 → 0.2.8

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/app/helpers/headmin/admin_helper.rb +3 -59
  4. data/app/helpers/headmin/bootstrap_helper.rb +9 -0
  5. data/app/helpers/headmin/filter_helper.rb +7 -3
  6. data/app/helpers/headmin/form_helper.rb +36 -0
  7. data/app/helpers/headmin/request_helper.rb +39 -0
  8. data/app/models/concerns/headmin/fieldable.rb +3 -1
  9. data/app/services/block_service.rb +8 -4
  10. data/app/views/examples/admin.html.erb +1 -1
  11. data/app/views/headmin/_blocks.html.erb +1 -1
  12. data/app/views/headmin/_card.html.erb +3 -1
  13. data/app/views/headmin/_filters.html.erb +3 -3
  14. data/app/views/headmin/_pagination.html.erb +2 -1
  15. data/app/views/headmin/_table.html.erb +9 -3
  16. data/app/views/headmin/dropdown/_devise.html.erb +20 -10
  17. data/app/views/headmin/dropdown/_list.html.erb +17 -7
  18. data/app/views/headmin/filters/_date.html.erb +5 -3
  19. data/app/views/headmin/filters/_flatpickr.html.erb +57 -0
  20. data/app/views/headmin/forms/_base.html.erb +12 -11
  21. data/app/views/headmin/forms/_blocks.html.erb +11 -4
  22. data/app/views/headmin/forms/_date.html.erb +24 -12
  23. data/app/views/headmin/forms/_date_range.html.erb +84 -0
  24. data/app/views/headmin/forms/_flatpickr.html.erb +55 -0
  25. data/app/views/headmin/forms/_flatpickr_range.html.erb +61 -0
  26. data/app/views/headmin/forms/_hidden.html.erb +23 -0
  27. data/app/views/headmin/forms/_label.html.erb +4 -2
  28. data/app/views/headmin/forms/_repeater.html.erb +5 -8
  29. data/app/views/headmin/forms/_select.html.erb +14 -11
  30. data/app/views/headmin/forms/_text.html.erb +7 -9
  31. data/app/views/headmin/layout/_main.html.erb +11 -5
  32. data/app/views/headmin/table/_actions.html.erb +35 -11
  33. data/app/views/headmin/table/body/_row.html.erb +14 -6
  34. data/app/views/headmin/views/devise/confirmations/_new.html.erb +1 -1
  35. data/app/views/headmin/views/devise/passwords/_edit.html.erb +2 -2
  36. data/app/views/headmin/views/devise/passwords/_new.html.erb +1 -1
  37. data/app/views/headmin/views/devise/registrations/_edit.html.erb +4 -4
  38. data/app/views/headmin/views/devise/registrations/_new.html.erb +3 -3
  39. data/app/views/headmin/views/devise/shared/_links.html.erb +7 -7
  40. data/app/views/headmin/views/devise/unlocks/_new.html.erb +1 -1
  41. data/config/locales/activerecord/en.yml +9 -0
  42. data/config/locales/activerecord/nl.yml +9 -0
  43. data/config/locales/headmin/table/en.yml +5 -1
  44. data/config/locales/headmin/table/nl.yml +5 -1
  45. data/config/locales/headmin/views/en.yml +1 -1
  46. data/config/locales/headmin/views/nl.yml +14 -14
  47. data/dist/css/headmin.css +57 -13
  48. data/dist/js/headmin.js +81 -514
  49. data/docs/blocks.md +0 -7
  50. data/lib/generators/headmin/blocks_generator.rb +4 -1
  51. data/lib/generators/headmin/devise_generator.rb +6 -2
  52. data/lib/generators/headmin/fields_generator.rb +4 -1
  53. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +31 -0
  54. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +31 -0
  55. data/lib/generators/templates/controllers/auth/passwords_controller.rb +35 -0
  56. data/lib/generators/templates/controllers/auth/registrations_controller.rb +63 -0
  57. data/lib/generators/templates/controllers/auth/sessions_controller.rb +28 -0
  58. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +31 -0
  59. data/lib/headmin/version.rb +1 -1
  60. data/package.json +3 -2
  61. data/src/js/headmin/controllers/blocks_controller.js +1 -1
  62. data/src/js/headmin/controllers/date_range_controller.js +34 -0
  63. data/src/js/headmin/controllers/filter_controller.js +1 -1
  64. data/src/js/headmin/controllers/filters_controller.js +1 -1
  65. data/src/js/headmin/controllers/flatpickr_controller.js +38 -0
  66. data/src/js/headmin/controllers/popup_controller.js +1 -1
  67. data/src/js/headmin/controllers/repeater_controller.js +8 -9
  68. data/src/js/headmin/controllers/table_actions_controller.js +74 -9
  69. data/src/js/headmin/controllers/table_controller.js +49 -58
  70. data/src/js/headmin/headmin.js +38 -21
  71. data/src/scss/headmin/form.scss +4 -0
  72. data/src/scss/headmin/table.scss +1 -0
  73. data/yarn.lock +940 -1058
  74. metadata +20 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ade465655c1e8e80dd864856e0f0cb26ab1f731bfd518b3ad976bbb317420aa1
4
- data.tar.gz: 2dc85e50e4840a186b996ec165f296dd8b234292172f58e1be74cf378adf7f3f
3
+ metadata.gz: 97d58b9cf116a2017929bd0460593bedc48a2be8e8d53011b6db46fc3ee1df5f
4
+ data.tar.gz: 379caa2715bb6c22efe961996420ce9fe0c8a6dc17ee88847d0d9661da768328
5
5
  SHA512:
6
- metadata.gz: bfa03386ea283e4d45180d69d04c226459ce494ed6a004215d1b4ba028dd5e1eb4c87e6027016743deab25baa103a239ed2933b0786dbdb0af727a1d16e90de2
7
- data.tar.gz: a86486191d491de2585fe647644812f6c2e813473821d89bea6be44c0a7d71b42cdc0293d2117094946ba5bbd4415dea85e7cd5dc3c7249a72d68b2e8a15a9bd
6
+ metadata.gz: 5d0452d83d31e5ac38ce1d75fc3d189d0400343d1f0ca82690e9d4c284a5acdae9dba36862b0a2aeba0784ca1c6cb1241970752de836b03cf62a08cbedf32b23
7
+ data.tar.gz: 01e9857909d763690fbf63ab0efe901f49894594060e3945b777b025414a5c294c2a5af475f47d1cc21ac9757cd5341610ee555a197eb30340e949219ac1accf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- headmin (0.2.3)
4
+ headmin (0.2.7)
5
5
  closure_tree
6
6
 
7
7
  GEM
@@ -23,7 +23,7 @@ GEM
23
23
  activerecord (>= 4.2.10)
24
24
  with_advisory_lock (>= 4.0.0)
25
25
  concurrent-ruby (1.1.9)
26
- i18n (1.8.10)
26
+ i18n (1.8.11)
27
27
  concurrent-ruby (~> 1.0)
28
28
  minitest (5.14.4)
29
29
  parallel (1.20.1)
@@ -1,65 +1,9 @@
1
1
  module Headmin
2
2
  module AdminHelper
3
+ include Headmin::BootstrapHelper
3
4
  include Headmin::FilterHelper
5
+ include Headmin::FormHelper
4
6
  include Headmin::NotificationHelper
5
-
6
- def current_model
7
- controller_name.classify.constantize
8
- end
9
-
10
- def bootstrap_icon(icon, options = {})
11
- data = options.has_key?(:data) ? options[:data] : nil
12
- klass = options.has_key?(:class) ? options[:class] : nil
13
- content_tag(:i, class: "bi bi-#{icon} #{klass}", data: data) {}
14
- end
15
-
16
- def current_url?(url)
17
- uri = URI(url)
18
- path = uri.path
19
- query_string = uri.query
20
- matches_path = request.path.include?(path)
21
- matches_query = uri.query ? request.query_string.include?(query_string) : true
22
- is_root = request.fullpath == url
23
- if url == admin_root_path
24
- is_root
25
- else
26
- matches_path && matches_query
27
- end
28
- end
29
-
30
- def form_field_valid?(form, name)
31
- !form.object.errors.has_key?(name)
32
- end
33
-
34
- def form_field_validation_id(form, name)
35
- [form.object_name, name.to_s, 'validation'].join('_').parameterize.underscore
36
- end
37
-
38
- def form_field_validation_class(form, name)
39
- return nil if request.get?
40
- form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
41
- end
42
-
43
- def default_params
44
- params.select { |key, value| is_default_param?(key) }
45
- end
46
-
47
- def add_default_param_key(key)
48
- keys = default_param_keys || []
49
- keys.push(key)
50
- @default_param_keys = keys
51
- end
52
-
53
- def default_param_keys
54
- @default_param_keys ||= [:page, :start, :length, :per_page]
55
- end
56
-
57
- def is_default_param?(key)
58
- default_param_keys.include?(key.to_sym) || is_sort_param_key?(key)
59
- end
60
-
61
- def is_sort_param_key?(key)
62
- key.to_s.include?('sort_')
63
- end
7
+ include Headmin::RequestHelper
64
8
  end
65
9
  end
@@ -0,0 +1,9 @@
1
+ module Headmin
2
+ module BootstrapHelper
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) {}
7
+ end
8
+ end
9
+ end
@@ -1,11 +1,15 @@
1
1
  module Headmin
2
2
  module FilterHelper
3
3
  def filter_param_exists?(name)
4
- return false unless params.has_key?(name)
4
+ filter_param(name).present?
5
+ end
6
+
7
+ def filter_param(name)
8
+ return nil unless params.has_key?(name)
5
9
  if params[name].is_a?(Array)
6
- params[name].reject { |c| c.empty? }.present?
10
+ params[name].reject { |c| c.empty? }
7
11
  else
8
- params[name].present?
12
+ params[name]
9
13
  end
10
14
  end
11
15
  end
@@ -0,0 +1,36 @@
1
+ module Headmin
2
+ module FormHelper
3
+ def form_field_valid?(form, name)
4
+ !form.object.errors.has_key?(name)
5
+ end
6
+
7
+ def form_field_validation_id(form, name)
8
+ [form.object_name, name.to_s, 'validation'].join('_').parameterize.underscore
9
+ end
10
+
11
+ def form_field_validation_class(form, name)
12
+ return nil if request.get?
13
+ form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
14
+ end
15
+
16
+ # Outputs currently present query parameters as hidden fields for a given form
17
+ #
18
+ # https://example.com/products?amount=1&type[]=food&type[]=beverage
19
+ #
20
+ # <%= form.hidden_input :amount, value: 1 %>
21
+ # <%= form.hidden_input :'type[]', value: 'food' %>
22
+ # <%= form.hidden_input :'type[]', value: 'beverage' %>
23
+ def query_parameter_fields(form)
24
+ test = request.query_parameters.map do |name, value|
25
+ if value.is_a?(Array)
26
+ value.map do |value_element|
27
+ form.hidden_field "#{name}[]", value: value_element
28
+ end.join
29
+ else
30
+ form.hidden_field name, value: value
31
+ end
32
+ end
33
+ test.join.html_safe
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ module Headmin
2
+ module RequestHelper
3
+ def current_url?(url)
4
+ uri = URI(url)
5
+ path = uri.path
6
+ query_string = uri.query
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
15
+ end
16
+
17
+ def default_params
18
+ params.select { |key, value| is_default_param?(key) }
19
+ end
20
+
21
+ def add_default_param_key(key)
22
+ keys = default_param_keys || []
23
+ keys.push(key)
24
+ @default_param_keys = keys
25
+ end
26
+
27
+ def default_param_keys
28
+ @default_param_keys ||= [:page, :start, :length, :per_page]
29
+ end
30
+
31
+ def is_default_param?(key)
32
+ default_param_keys.include?(key.to_sym) || is_sort_param_key?(key)
33
+ end
34
+
35
+ def is_sort_param_key?(key)
36
+ key.to_s.include?('sort_')
37
+ end
38
+ end
39
+ end
@@ -7,7 +7,9 @@ module Headmin
7
7
  accepts_nested_attributes_for :fields, allow_destroy: true
8
8
 
9
9
  def fields_hash
10
- parse_hash_tree(fields.hash_tree)
10
+ fields.order(position: :asc).map do |field|
11
+ parse_hash_tree(field.hash_tree)
12
+ end.reduce({}, :merge)
11
13
  end
12
14
 
13
15
  def fields_hash=(hash)
@@ -1,10 +1,7 @@
1
1
  class BlockService
2
2
  def self.block_names(path:)
3
3
  form_views(path: path).map do |view|
4
- filename = File.basename(view, '.html.erb')
5
-
6
- # Removes leading _ if exists
7
- filename.sub!(/^_/, '')
4
+ view_name(view)
8
5
  end
9
6
  end
10
7
 
@@ -24,6 +21,13 @@ class BlockService
24
21
  views(form_view_paths(path))
25
22
  end
26
23
 
24
+ def self.view_name(view)
25
+ filename = File.basename(view, '.html.erb')
26
+
27
+ # Removes leading _ if exists
28
+ filename.sub(/^_/, '')
29
+ end
30
+
27
31
  private
28
32
 
29
33
  # Looks for a block view by its name.
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="<%= I18n.locale %>">
3
3
  <head>
4
4
  <title>Admin</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
@@ -18,7 +18,7 @@
18
18
 
19
19
  <% if blockable && blockable.respond_to?(:blocks) %>
20
20
  <% blockable.blocks.order(:position).each do |block| %>
21
- <% view_path = BlockService.frontend_view(block.name, path: path).gsub('/_', '/') %>
21
+ <% view_path = BlockService.frontend_view(block.name, path: path).gsub('/_', '/').split('.').first %>
22
22
  <%= render view_path, block: block %>
23
23
  <% end %>
24
24
  <% end %>
@@ -4,6 +4,7 @@
4
4
  # ==== Options
5
5
  # * <tt>title</tt> - Title for card
6
6
  # * <tt>description</tt> - Description for card
7
+ # * <tt>id</tt> - HTML Id Attribute
7
8
  # * <tt>padded</tt> - Set to true if you want to render the block content inside the card-body element
8
9
  #
9
10
  # ==== Examples
@@ -17,12 +18,13 @@
17
18
  # Your content
18
19
  # <% end %#>
19
20
 
21
+ id = local_assigns.has_key?(:id) ? id : nil
20
22
  title = local_assigns.has_key?(:title) ? title : nil
21
23
  description = local_assigns.has_key?(:description) ? description : nil
22
24
  padded = local_assigns.has_key?(:padded) ? padded : true
23
25
  %>
24
26
 
25
- <div class="card mb-3 shadow-sm">
27
+ <div class="card mb-3 shadow-sm" id="<%= id %>">
26
28
 
27
29
  <% if padded || title || description %>
28
30
  <div class="card-body">
@@ -11,7 +11,7 @@
11
11
  # With custom URL
12
12
  # <%= render "headmin/filters", url: admin_polls_path %#>
13
13
 
14
- action = local_assigns.has_key?(:url) ? url : request.url
14
+ action = local_assigns.has_key?(:url) ? url : request.path
15
15
  %>
16
16
 
17
17
  <form action="<%= action %>" data-controller="filters" data-filters-target="form">
@@ -31,14 +31,14 @@
31
31
  <%= content_for :filters_search %>
32
32
 
33
33
  <!-- Separator -->
34
- <% if content_for(:filters_menu) && content_for(:filters_search) %>
34
+ <% if content_for?(:filters_menu) && content_for?(:filters_search) %>
35
35
  <div class="vr mx-2"></div>
36
36
  <% end %>
37
37
  </div>
38
38
 
39
39
  <!-- Menu -->
40
40
  <div class="h-filters-menu d-flex align-items-center w-auto my-1">
41
- <% if content_for :filters_menu %>
41
+ <% if content_for?(:filters_menu) %>
42
42
  <div class="btn-group">
43
43
  <button type="button" class="btn h-btn-outline-light dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
44
44
  <%= bootstrap_icon('funnel') %>
@@ -10,8 +10,9 @@
10
10
  %>
11
11
 
12
12
  <div class="d-flex flex-row-reverse flex-md-row align-items-center justify-content-between justify-content-md-end my-1">
13
+ <% content_for :collection_total_count, collection.total_count.to_s unless content_for?(:collection_total_count) %>
13
14
  <div class="ms-2 me-md-2 text-secondary">
14
- <%= t('.items', count: collection.total_count) %>
15
+ <%= t('.items', count: content_for(:collection_total_count).to_i) %>
15
16
  </div>
16
17
  <%= paginate collection, views_prefix: 'headmin/pagination' %>
17
18
  </div>
@@ -2,18 +2,24 @@
2
2
  # headmin/table
3
3
  #
4
4
  # ==== Options
5
- # * <tt>sort_url</tt> - U
5
+ # * <tt>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 %#>
9
9
  # table content here
10
10
  # <% end %#>
11
+
12
+ sort_url = local_assigns.has_key?(:sort_url) ? sort_url : nil
13
+ total_count = content_for(:collection_total_count).to_i || nil
11
14
  %>
12
15
 
13
- <% sort_url = local_assigns.has_key?(:sort_url) ? sort_url : nil %>
14
16
  <div class="h-table card my-2 shadow-sm <%= 'table-drag-sort' if sort_url %>" data-sort-url="<%= sort_url %>">
15
17
  <div class="table-responsive">
16
- <table class="table table-hover m-0" data-controller="table" data-table-target="table" data-table-url-value="<%= sort_url %>">
18
+ <table class="table table-hover m-0"
19
+ data-controller="table"
20
+ data-table-target="table"
21
+ data-table-url-value="<%= sort_url %>"
22
+ data-table-count-value="<%= total_count %>">
17
23
  <%= yield if block_given? %>
18
24
  </table>
19
25
  </div>
@@ -1,19 +1,29 @@
1
- <%#
2
- headmin/dropdown/locale
3
- accepts block: yes
4
- parameters:
5
- scope: (symbol) devise scope, i.e. ':users' => current_user
1
+ <%
2
+ # headmin/dropdown/devise
3
+ #
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
7
+ #
8
+ # ==== Examples
9
+ # Basic version
10
+ # <%= render "headmin/dropdown/devise" %#>
11
+ #
12
+ # Custom scope
13
+ # <%= render "headmin/dropdown/devise", scope: :admins %#>
14
+
15
+ class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : ''
16
+ scope = local_assigns.has_key?(:scope) ? scope : :users
17
+ singular = scope.to_s.singularize.to_sym
18
+ user = send("current_#{singular}")
6
19
  %>
7
20
 
8
- <% scope = local_assigns.has_key?(:scope) ? scope : :users %>
9
- <% singular = scope.to_s.singularize.to_sym %>
10
- <% user = send("current_#{singular}") %>
11
21
 
12
- <%= render 'headmin/dropdown' do %>
22
+ <%= render 'headmin/dropdown', class: class_names do %>
13
23
  <%= render 'headmin/dropdown/button' do %>
14
24
  <%= user.to_s %>
15
25
  <% end %>
16
- <%= render 'headmin/dropdown/list' do %>
26
+ <%= render 'headmin/dropdown/list', class: 'dropdown-menu-end' do %>
17
27
  <%= render 'headmin/dropdown/item', name: t('.edit_profile'), url: polymorphic_path([:edit, singular, :registration]) %>
18
28
  <%= render 'headmin/dropdown/divider' %>
19
29
  <%= render 'headmin/dropdown/item', name: t('.log_out'), url: polymorphic_path([:destroy, singular, :session]), method: :delete %>
@@ -1,11 +1,21 @@
1
- <%#
2
- headmin/dropdown/list
3
- accepts block: yes
4
- parameters:
5
- id: unique identifier for the dropdown
1
+ <%
2
+ # headmin/dropdown/list
3
+ #
4
+ # ==== Options
5
+ # * <tt>id</tt> - unique identifier for the dropdown
6
+ # * <tt>class</tt> - Custom class names to put on the dropdown menu
7
+ #
8
+ # ==== Examples
9
+ # Basic version
10
+ # <%= render "headmin/dropdown/devise" %#>
11
+ #
12
+ # Custom scope
13
+ # <%= render "headmin/dropdown/devise", scope: :admins %#>
14
+
15
+ class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : ''
16
+ id = local_assigns.has_key?(:id) ? id : 'dropdown-1'
6
17
  %>
7
- <% id = local_assigns.has_key?(:id) ? id : 'dropdown-1' %>
8
18
 
9
- <ul class="dropdown-menu" aria-labelledby="<%= id %>">
19
+ <ul class="dropdown-menu <%= class_names %>" aria-labelledby="<%= id %>">
10
20
  <%= yield %>
11
21
  </ul>
@@ -14,10 +14,12 @@
14
14
 
15
15
  input_options = {
16
16
  placeholder: 'dd/mm/yyyy',
17
- class: "form-control flatpickr",
17
+ class: "form-control",
18
18
  required: true,
19
- 'data-filters-target': 'input',
20
- 'data-action': "change->filters#update"
19
+ data: {
20
+ 'filters-target': 'input',
21
+ 'action': 'change->filters#update',
22
+ }
21
23
  }
22
24
  %>
23
25
 
@@ -0,0 +1,57 @@
1
+ <%
2
+ # headmin/filters/flatpickr
3
+ #
4
+ # ==== Options
5
+ # * <tt>name</tt> - Name of the filter parameter
6
+ # * <tt>label</tt> - Display name
7
+ #
8
+ # ==== Examples
9
+ # Basic version
10
+ # <%= render "headmin/filters/flatpickr", name: :created_at, label: 'Created at' %#>
11
+
12
+ label = local_assigns.has_key?(:label) ? label : nil
13
+ name = local_assigns.has_key?(:name) ? name : nil
14
+
15
+ input_options = {
16
+ placeholder: 'dd/mm/yyyy',
17
+ class: "form-control",
18
+ required: true,
19
+ data: {
20
+ 'filters-target': 'input',
21
+ 'flatpickr-target': 'input',
22
+ 'action': 'change->filters#update',
23
+ 'flatpickr-options': {
24
+ defaultDate: params[name]
25
+ }
26
+ }
27
+ }
28
+ %>
29
+
30
+ <%= content_for :filters_menu do %>
31
+ <%= render 'headmin/filters/filter/menu_item', name: name, label: label %>
32
+ <% end %>
33
+
34
+ <%= content_for :filters_templates do %>
35
+ <%= render 'headmin/filters/filter/template', name: name, label: label do %>
36
+ <div class="input-group" data-controller="flatpickr">
37
+ <span class="input-group-text">
38
+ <%= bootstrap_icon('calendar') %>
39
+ </span>
40
+ <%= date_field_tag(name, nil, input_options) %>
41
+ </div>
42
+ <% end %>
43
+ <% end %>
44
+
45
+ <%= content_for :filters_buttons do %>
46
+ <% if filter_param_exists?(name) %>
47
+ <% value_formatted = Date.parse(params[name]).strftime('%d/%m/%Y') %>
48
+ <%= render 'headmin/filters/filter/button', id: "filter-#{name}", name: name, label: label, value: value_formatted do %>
49
+ <div class="input-group" data-controller="flatpickr">
50
+ <span class="input-group-text">
51
+ <%= bootstrap_icon('calendar') %>
52
+ </span>
53
+ <%= date_field_tag(name, params[name], input_options) %>
54
+ </div>
55
+ <% end %>
56
+ <% end %>
57
+ <% end %>
@@ -2,14 +2,14 @@
2
2
  # headmin/forms/base
3
3
  #
4
4
  # ==== Options
5
- # * <tt>form<tt> - Form object
5
+ # * <tt>append<tt> - Text or icon to be shown on the left hand side of the input, Doesn't work with float
6
6
  # * <tt>attribute<tt> - Name of the attribute of the form model
7
- # * <tt>options<tt> - Hash with all HTML options to pass to
8
- # * <tt>label<tt> - Text to show as label. Label will be hidden if value is false
9
- # * <tt>required<tt> - Set to true to mark as required
10
7
  # * <tt>float<tt> - Set to true if you want to show floating labels
11
- # * <tt>append<tt> - Text or icon to be shown on the left hand side of the input, Doesn't work with float
8
+ # * <tt>form<tt> - Form object
9
+ # * <tt>label<tt> - Text to show as label. Label will be hidden if value is false
10
+ # * <tt>options<tt> - Hash with all HTML options to pass to
12
11
  # * <tt>prepend<tt> - Text or icon to be shown on the right hand side of the input, Doesn't work with float
12
+ # * <tt>required<tt> - Set to true to mark as required
13
13
  #
14
14
  # ==== Examples
15
15
  # Basic version
@@ -19,9 +19,10 @@
19
19
  # <%= render 'headmin/forms/text', form: form, attribute: :title, datepicker: true %#>
20
20
 
21
21
  append = local_assigns.has_key?(:append) ? append : nil
22
+ prepend = local_assigns.has_key?(:prepend) ? prepend : nil
23
+ group = append || prepend
22
24
  float = local_assigns.has_key?(:float) ? float : false
23
25
  label = local_assigns.has_key?(:label) ? label : nil
24
- prepend = local_assigns.has_key?(:prepend) ? prepend : nil
25
26
  required = local_assigns.has_key?(:required) ? required : false
26
27
 
27
28
  show_label = label != false
@@ -32,10 +33,7 @@
32
33
  <%= render 'headmin/forms/label', form: form, attribute: attribute, name: label, required: required %>
33
34
  <% end %>
34
35
 
35
- <% if float %>
36
- <%= yield form %>
37
- <%= render 'headmin/forms/validation', form: form, attribute: attribute %>
38
- <% else %>
36
+ <% if group %>
39
37
  <div class="input-group w-100">
40
38
  <% if prepend %>
41
39
  <span class="input-group-text">
@@ -44,7 +42,7 @@
44
42
  <% end %>
45
43
 
46
44
  <%= yield form %>
47
- <%= render 'headmin/forms/validation', form: form, attribute: attribute %>
45
+ <%= render 'headmin/forms/validation', form: form, attribute: attribute if form.object.respond_to?(:errors) %>
48
46
 
49
47
  <% if append %>
50
48
  <span class="input-group-text">
@@ -52,6 +50,9 @@
52
50
  </span>
53
51
  <% end %>
54
52
  </div>
53
+ <% else %>
54
+ <%= yield form %>
55
+ <%= render 'headmin/forms/validation', form: form, attribute: attribute if form.object.respond_to?(:errors) %>
55
56
  <% end %>
56
57
 
57
58
  <% if show_label && float %>
@@ -22,11 +22,18 @@
22
22
  templates = allowed_block_names.map { |name| BlockService.form_view(name, path: path) }
23
23
  %>
24
24
 
25
- <%= render 'headmin/forms/repeater', form: form, attribute: :blocks, templates: templates, label: false do |block| %>
26
- <% view_path = BlockService.form_view(block.object.name, path: path).gsub('/_', '/') %>
27
- <%= render view_path, form: block, name: block.object.name %>
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 %>
28
27
 
28
+ <!-- Name input of the block -->
29
+ <%= block_form.hidden_field :name, value: name %>
30
+
31
+ <!-- Render block form fields -->
32
+ <% view_path = BlockService.form_view(name, path: path).gsub('/_', '/') %>
33
+ <%= render view_path, form: block_form %>
34
+
35
+ <!-- Label -->
29
36
  <span class="position-absolute top-0 end-0 badge bg-light text-dark">
30
- <%= block.object.name.titleize %>
37
+ <%= name.titleize %>
31
38
  </span>
32
39
  <% end %>
@@ -2,19 +2,22 @@
2
2
  # headmin/forms/date
3
3
  #
4
4
  # ==== Options
5
- # * <tt>form<tt> - Form object
5
+ # * <tt>append<tt> - Text or icon to be shown on the left hand side of the input, Doesn't work with float
6
6
  # * <tt>attribute<tt> - Name of the attribute of the form model
7
- # * <tt>label<tt> - Text to show as label. Label will be hidden if value is false
7
+ # * <tt>class<tt> - Optional HTML class attribute
8
+ # * <tt>data<tt> - Optional HTML data attributes
9
+ # * <tt>disabled<tt> - Set to true if the input should be shown as disabled
8
10
  # * <tt>float<tt> - Set to true if you want to show floating labels
9
- # * <tt>append<tt> - Text or icon to be shown on the left hand side of the input, Doesn't work with float
11
+ # * <tt>form<tt> - Form object
12
+ # * <tt>label<tt> - Text to show as label. Label will be hidden if value is false
13
+ # * <tt>name<tt> - The name of the field
10
14
  # * <tt>prepend<tt> - Text or icon to be shown on the right hand side of the input, Doesn't work with float
15
+ # * <tt>readonly<tt> - Set to true if the value of the field can only be read and not be modified
16
+ # * <tt>required<tt> - Set to true to show a HTML5 validation message when left blank
11
17
  #
12
18
  # ==== Examples
13
19
  # Basic version
14
- # <%= render 'headmin/forms/date', form: form, attribute: :title %#>
15
- #
16
- # With datepicker
17
- # <%= render 'headmin/forms/text', form: form, attribute: :title, datepicker: true %#>
20
+ # <%= render 'headmin/forms/date', form: form, attribute: :date %#>
18
21
 
19
22
  append = local_assigns.has_key?(:append) ? append : nil
20
23
  class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false
@@ -25,21 +28,30 @@
25
28
  prepend = local_assigns.has_key?(:prepend) ? prepend : nil
26
29
  readonly = local_assigns.has_key?(:readonly) ? readonly : false
27
30
  required = local_assigns.has_key?(:required) ? required : false
28
- datepicker = local_assigns.has_key?(:datepicker) ? local_assigns[:datepicker] : false
29
-
30
- class_names = "#{class_names} flatpicker" if datepicker
31
31
 
32
32
  options = {
33
33
  'aria-describedby': form_field_validation_id(form, attribute),
34
34
  class: "form-control #{form_field_validation_class(form, attribute)} #{class_names}",
35
35
  data: data,
36
36
  disabled: disabled,
37
- placeholder: attribute,
37
+ placeholder: label ? label.to_s.humanize : nil,
38
38
  readonly: readonly,
39
39
  required: required,
40
40
  }
41
+
42
+ options[:name] = name if local_assigns.has_key?(:name)
43
+
44
+ template_locals = {
45
+ append: append,
46
+ attribute: attribute,
47
+ float: float,
48
+ form: form,
49
+ label: label,
50
+ prepend: prepend,
51
+ required: required
52
+ }
41
53
  %>
42
54
 
43
- <%= render 'headmin/forms/base', form: form, attribute: attribute, append: append, prepend: prepend, float: float, label: label, required: required do |form| %>
55
+ <%= render 'headmin/forms/base', template_locals do |form| %>
44
56
  <%= form.date_field(attribute, options) %>
45
57
  <% end %>