headmin 0.5.1 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -2
- data/Gemfile +14 -0
- data/Gemfile.lock +79 -2
- data/app/assets/javascripts/headmin/controllers/media_controller.js +237 -0
- data/app/assets/javascripts/headmin/controllers/media_modal_controller.js +110 -0
- data/app/assets/javascripts/headmin/controllers/remote_modal_controller.js +9 -0
- data/app/assets/javascripts/headmin/controllers/textarea_controller.js +34 -0
- data/app/assets/javascripts/headmin/index.js +8 -0
- data/app/assets/javascripts/headmin.js +294 -0
- data/app/assets/stylesheets/headmin/forms/file.scss +40 -5
- data/app/assets/stylesheets/headmin/forms/media.scss +10 -0
- data/app/assets/stylesheets/headmin/forms.scss +1 -0
- data/app/assets/stylesheets/headmin/layout/sidebar.scss +0 -1
- data/app/assets/stylesheets/headmin/media/index.scss +9 -0
- data/app/assets/stylesheets/headmin/media.scss +1 -0
- data/app/assets/stylesheets/headmin/overrides/redactorx.scss +1 -1
- data/app/assets/stylesheets/headmin/table.scss +8 -0
- data/app/assets/stylesheets/headmin/vendor/{tom-select-bootstrap.css → tom-select-bootstrap.scss} +0 -1
- data/app/assets/stylesheets/headmin.css +61 -8
- data/app/assets/stylesheets/headmin.scss +1 -0
- data/app/controllers/headmin/media_controller.rb +52 -0
- data/app/controllers/headmin_controller.rb +2 -0
- data/app/helpers/headmin/form_helper.rb +2 -2
- data/app/models/concerns/headmin/field.rb +2 -2
- data/app/models/concerns/headmin/fieldable.rb +19 -10
- data/app/models/concerns/headmin/form/hintable.rb +6 -1
- data/app/models/headmin/filter/association.rb +86 -0
- data/app/models/headmin/filter/association_view.rb +74 -0
- data/app/models/headmin/filter/base.rb +5 -2
- data/app/models/headmin/filter/boolean_view.rb +1 -0
- data/app/models/headmin/filter/date.rb +49 -1
- data/app/models/headmin/filter/date_view.rb +1 -0
- data/app/models/headmin/filter/flatpickr_view.rb +1 -0
- data/app/models/headmin/filter/number_view.rb +1 -0
- data/app/models/headmin/filter/operator_view.rb +3 -1
- data/app/models/headmin/filter/options_view.rb +1 -0
- data/app/models/headmin/filter/text_view.rb +1 -0
- data/app/models/headmin/form/association_view.rb +102 -0
- data/app/models/headmin/form/blocks_view.rb +4 -1
- data/app/models/headmin/form/file_view.rb +0 -8
- data/app/models/headmin/form/flatpickr_view.rb +2 -1
- data/app/models/headmin/form/media_item_view.rb +39 -0
- data/app/models/headmin/form/media_view.rb +137 -0
- data/app/models/headmin/form/select_view.rb +2 -1
- data/app/models/headmin/form/textarea_view.rb +6 -1
- data/app/models/headmin/thumbnail_view.rb +40 -19
- data/app/models/view_model.rb +4 -0
- data/app/views/examples/admin.html.erb +8 -8
- data/app/views/examples/auth.html.erb +2 -2
- data/app/views/headmin/_breadcrumbs.html.erb +2 -2
- data/app/views/headmin/_dropdown.html.erb +1 -1
- data/app/views/headmin/_filters.html.erb +12 -7
- data/app/views/headmin/_pagination.html.erb +2 -2
- data/app/views/headmin/_popup.html.erb +4 -4
- data/app/views/headmin/_table.html.erb +1 -1
- data/app/views/headmin/_thumbnail.html.erb +33 -9
- data/app/views/headmin/dropdown/_button.html.erb +2 -2
- data/app/views/headmin/dropdown/_item.html.erb +2 -2
- data/app/views/headmin/dropdown/_list.html.erb +3 -3
- data/app/views/headmin/dropdown/_locale.html.erb +5 -5
- data/app/views/headmin/filters/_association.html.erb +24 -0
- data/app/views/headmin/filters/_options.html.erb +1 -1
- data/app/views/headmin/filters/filter/_button.html.erb +2 -2
- data/app/views/headmin/filters/filter/_null_select.html.erb +2 -2
- data/app/views/headmin/forms/_association.html.erb +30 -0
- data/app/views/headmin/forms/_errors.html.erb +1 -1
- data/app/views/headmin/forms/_file.html.erb +10 -11
- data/app/views/headmin/forms/_hint.html.erb +6 -1
- data/app/views/headmin/forms/_media.html.erb +60 -0
- data/app/views/headmin/forms/_repeater.html.erb +18 -16
- data/app/views/headmin/forms/_textarea.html.erb +1 -1
- data/app/views/headmin/forms/_wrapper.html.erb +0 -1
- data/app/views/headmin/forms/fields/_list.html.erb +6 -4
- data/app/views/headmin/forms/media/_item.html.erb +38 -0
- data/app/views/headmin/forms/media/_validation.html.erb +10 -0
- data/app/views/headmin/forms/repeater/_row.html.erb +17 -15
- data/app/views/headmin/heading/_title.html.erb +2 -2
- data/app/views/headmin/layout/_main.html.erb +2 -0
- data/app/views/headmin/layout/_remote_modal.html.erb +1 -0
- data/app/views/headmin/layout/_sidebar.html.erb +1 -1
- data/app/views/headmin/media/_item.html.erb +16 -0
- data/app/views/headmin/media/_media_item_modal.html.erb +51 -0
- data/app/views/headmin/media/_modal.html.erb +35 -0
- data/app/views/headmin/media/create.turbo_stream.erb +5 -0
- data/app/views/headmin/media/index.html.erb +3 -0
- data/app/views/headmin/media/show.html.erb +9 -0
- data/app/views/headmin/media/update.turbo_stream.erb +3 -0
- data/app/views/headmin/nav/_dropdown.html.erb +7 -7
- data/app/views/headmin/nav/_item.html.erb +5 -5
- data/app/views/headmin/nav/item/_locale.html.erb +6 -6
- data/app/views/headmin/pagination/_per_page.html.erb +7 -7
- data/app/views/headmin/pagination/kaminari/_first_page.html.erb +2 -2
- data/app/views/headmin/pagination/kaminari/_gap.html.erb +1 -1
- data/app/views/headmin/pagination/kaminari/_last_page.html.erb +2 -2
- data/app/views/headmin/pagination/kaminari/_next_page.html.erb +3 -3
- data/app/views/headmin/pagination/kaminari/_page.html.erb +2 -2
- data/app/views/headmin/pagination/kaminari/_paginator.html.erb +1 -1
- data/app/views/headmin/pagination/kaminari/_prev_page.html.erb +2 -2
- data/app/views/headmin/table/_actions.html.erb +9 -9
- data/app/views/headmin/table/_body.html.erb +1 -1
- data/app/views/headmin/table/actions/_action.html.erb +4 -4
- data/app/views/headmin/table/actions/_export.html.erb +1 -1
- data/app/views/headmin/table/body/_association.html.erb +17 -3
- data/app/views/headmin/table/body/_boolean.erb +4 -4
- data/app/views/headmin/table/body/_date.html.erb +2 -2
- data/app/views/headmin/table/body/_image.html.erb +18 -0
- data/app/views/headmin/table/body/_string.html.erb +1 -1
- data/app/views/headmin/table/head/_cell.html.erb +1 -1
- data/app/views/headmin/table/head/cell/_asc.html.erb +2 -2
- data/app/views/headmin/table/head/cell/_default.html.erb +1 -1
- data/app/views/headmin/table/head/cell/_desc.html.erb +1 -1
- data/app/views/headmin/views/devise/confirmations/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/passwords/_edit.html.erb +1 -1
- data/app/views/headmin/views/devise/passwords/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/registrations/_edit.html.erb +5 -5
- data/app/views/headmin/views/devise/registrations/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/sessions/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/shared/_links.html.erb +14 -20
- data/app/views/headmin/views/devise/unlocks/_new.html.erb +1 -1
- data/config/locales/activerecord/en.yml +1 -0
- data/config/locales/activerecord/nl.yml +1 -0
- data/config/locales/devise/nl.yml +1 -1
- data/config/locales/headmin/filters/en.yml +3 -1
- data/config/locales/headmin/filters/nl.yml +2 -0
- data/config/locales/headmin/forms/en.yml +8 -0
- data/config/locales/headmin/forms/nl.yml +8 -0
- data/config/locales/headmin/media/en.yml +23 -0
- data/config/locales/headmin/media/nl.yml +23 -0
- data/config/locales/headmin/table/en.yml +2 -0
- data/config/locales/headmin/table/nl.yml +2 -0
- data/config/routes.rb +10 -0
- data/lib/generators/templates/views/layouts/auth.html.erb +2 -2
- data/lib/headmin/version.rb +1 -1
- data/package.json +1 -1
- metadata +34 -3
@@ -0,0 +1,137 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
class MediaView < ViewModel
|
4
|
+
include Rails.application.routes.url_helpers
|
5
|
+
include Headmin::Form::Hintable
|
6
|
+
include Headmin::Form::Labelable
|
7
|
+
include Headmin::Form::Placeholderable
|
8
|
+
include Headmin::Form::Validatable
|
9
|
+
include Headmin::Form::Wrappable
|
10
|
+
|
11
|
+
def input_group_options
|
12
|
+
default_input_group_options
|
13
|
+
.deep_merge(label_input_group_options)
|
14
|
+
.deep_merge(@input_group || {})
|
15
|
+
end
|
16
|
+
|
17
|
+
def wrapper_options
|
18
|
+
default_wrapper_options.deep_merge({
|
19
|
+
class: ["mb-3", ("form-floating" if float)],
|
20
|
+
data: {
|
21
|
+
controller: "media",
|
22
|
+
name: name,
|
23
|
+
min: min,
|
24
|
+
max: max,
|
25
|
+
sort: sort,
|
26
|
+
required: required.nil? ? 0 : required
|
27
|
+
}
|
28
|
+
}).deep_merge(@wrapper || {})
|
29
|
+
end
|
30
|
+
|
31
|
+
def item_options
|
32
|
+
options = {
|
33
|
+
sort: sort
|
34
|
+
}
|
35
|
+
|
36
|
+
# Don't pass width or height if it was not defined
|
37
|
+
options = options.merge(width: width) if is_defined?(:width)
|
38
|
+
options = options.merge(height: height) if is_defined?(:height)
|
39
|
+
|
40
|
+
options
|
41
|
+
end
|
42
|
+
|
43
|
+
def custom_validation_options
|
44
|
+
{
|
45
|
+
form: form,
|
46
|
+
attribute: attribute,
|
47
|
+
min: min,
|
48
|
+
max: max
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def thumbnail_options
|
53
|
+
options = {
|
54
|
+
icon: "plus"
|
55
|
+
}
|
56
|
+
|
57
|
+
# Don't pass width or height if it was not defined
|
58
|
+
options = options.merge(width: width) unless is_defined?(:width)
|
59
|
+
options = options.merge(height: height) unless is_defined?(:height)
|
60
|
+
|
61
|
+
options
|
62
|
+
end
|
63
|
+
|
64
|
+
def association_object
|
65
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
66
|
+
result = form.object.send(nested_attribute)
|
67
|
+
result = result.order(position: :asc) if sort
|
68
|
+
result
|
69
|
+
else
|
70
|
+
form.object.send(nested_attribute)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def attachments
|
75
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
76
|
+
result = form.object.send(nested_attribute)
|
77
|
+
result = result.order(position: :asc) if sort
|
78
|
+
result.to_a.compact
|
79
|
+
else
|
80
|
+
[form.object.send(nested_attribute)].compact
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def attached
|
85
|
+
form.object.send(attribute)
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_nested_attribute
|
89
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
90
|
+
form.object.send(nested_attribute).build
|
91
|
+
else
|
92
|
+
form.object.send("build_#{nested_attribute}")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def nested_attribute
|
97
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
98
|
+
:"#{attribute}_attachments"
|
99
|
+
else
|
100
|
+
:"#{attribute}_attachment"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def min
|
105
|
+
if @required
|
106
|
+
@min.to_i < 1 ? 1 : @min.to_i
|
107
|
+
else
|
108
|
+
@min.to_i < 1 ? 0 : @min.to_i
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def max
|
113
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
114
|
+
@max
|
115
|
+
else
|
116
|
+
1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def required
|
121
|
+
@required ? 1 : nil
|
122
|
+
end
|
123
|
+
|
124
|
+
def blob_ids
|
125
|
+
attachments.map { |attachment| attachment.blob_id }
|
126
|
+
end
|
127
|
+
|
128
|
+
def name
|
129
|
+
"#{attribute}_#{object_id}"
|
130
|
+
end
|
131
|
+
|
132
|
+
def sort
|
133
|
+
@sort == true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -22,7 +22,8 @@ module Headmin
|
|
22
22
|
|
23
23
|
def wrapper_options
|
24
24
|
default_wrapper_options.deep_merge({
|
25
|
-
class: ["mb-3", ("form-floating" if float)]
|
25
|
+
class: ["mb-3", ("form-floating" if float)],
|
26
|
+
data: {controller: :textarea}
|
26
27
|
}).deep_merge(@wrapper || {})
|
27
28
|
end
|
28
29
|
|
@@ -32,6 +33,10 @@ module Headmin
|
|
32
33
|
{
|
33
34
|
aria: {describedby: validation_id},
|
34
35
|
class: [form_control_class, validation_class],
|
36
|
+
data: {
|
37
|
+
textarea_target: :textarea,
|
38
|
+
action: "input->textarea#update"
|
39
|
+
},
|
35
40
|
placeholder: placeholder
|
36
41
|
}
|
37
42
|
end
|
@@ -1,41 +1,62 @@
|
|
1
1
|
module Headmin
|
2
|
-
class ThumbnailView
|
3
|
-
def initialize(local_assigns)
|
4
|
-
@local_assigns = local_assigns
|
5
|
-
end
|
6
|
-
|
2
|
+
class ThumbnailView < ViewModel
|
7
3
|
def class_names
|
8
|
-
class_names = [@
|
4
|
+
class_names = [@class]
|
9
5
|
class_names << "img-thumbnail h-thumbnail"
|
10
6
|
class_names.join(" ")
|
11
7
|
end
|
12
8
|
|
13
9
|
def width
|
14
|
-
|
10
|
+
if is_defined?(:width)
|
11
|
+
@width
|
12
|
+
else
|
13
|
+
@width || 100
|
14
|
+
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def height
|
18
|
-
|
18
|
+
if is_defined?(:height)
|
19
|
+
@height
|
20
|
+
else
|
21
|
+
@height || 100
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
|
-
def
|
22
|
-
|
25
|
+
def blob
|
26
|
+
file.is_a?(ActiveStorage::Blob) ? file : file&.blob
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def mime_type
|
30
|
+
blob&.content_type
|
27
31
|
end
|
28
32
|
|
29
|
-
def
|
30
|
-
if
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
def variant_options
|
34
|
+
if width.nil? || height.nil?
|
35
|
+
default_variant_options.merge({
|
36
|
+
resize_to_fit: [width, height]
|
37
|
+
})
|
38
|
+
else
|
39
|
+
default_variant_options.merge({
|
40
|
+
resize_to_fill: [width, height, crop: :attention]
|
41
|
+
})
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
37
|
-
def
|
38
|
-
|
45
|
+
def default_variant_options
|
46
|
+
{
|
47
|
+
saver: {
|
48
|
+
quality: 80
|
49
|
+
}
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
# Is it possible to create a ActiveStorage::Variant?
|
54
|
+
def variable?
|
55
|
+
blob&.variable?
|
56
|
+
end
|
57
|
+
|
58
|
+
def icon?
|
59
|
+
is_defined?(:icon)
|
39
60
|
end
|
40
61
|
|
41
62
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
data/app/models/view_model.rb
CHANGED
@@ -6,15 +6,15 @@
|
|
6
6
|
<%= csrf_meta_tags %>
|
7
7
|
<%= csp_meta_tag %>
|
8
8
|
|
9
|
-
<%= stylesheet_pack_tag
|
10
|
-
<%= javascript_pack_tag
|
9
|
+
<%= stylesheet_pack_tag "admin", media: "all", "data-turbo-track": "reload" %>
|
10
|
+
<%= javascript_pack_tag "admin", "data-turbo-track": "reload" %>
|
11
11
|
</head>
|
12
12
|
|
13
13
|
<body>
|
14
14
|
<%= render "headmin/layout/main" do %>
|
15
|
-
<%= render "headmin/layout/sidebar", logo: inline_svg_tag(
|
15
|
+
<%= render "headmin/layout/sidebar", logo: inline_svg_tag("logo.svg") do %>
|
16
16
|
<%= render "headmin/layout/sidebar/menu" do %>
|
17
|
-
<%= render "headmin/layout/sidebar/menu/item", name: t(
|
17
|
+
<%= render "headmin/layout/sidebar/menu/item", name: t(".dashboard"), link: admin_root_path, icon: "speedometer" %>
|
18
18
|
<div class="d-block d-md-none">
|
19
19
|
<%= render "headmin/layout/sidebar/menu/locale" do end %>
|
20
20
|
<%= render "headmin/layout/sidebar/menu/account" do end %>
|
@@ -30,10 +30,10 @@
|
|
30
30
|
<%= render "headmin/notifications" %>
|
31
31
|
<%= yield %>
|
32
32
|
<% end %>
|
33
|
-
<%= render "headmin/layout/footer", class:
|
34
|
-
<%= bootstrap_icon(
|
35
|
-
<a class="text-secondary" href="mailto:info@insiting.com" title="<%= t(
|
36
|
-
<%= t(
|
33
|
+
<%= render "headmin/layout/footer", class: "text-secondary" do %>
|
34
|
+
<%= bootstrap_icon("question-circle") %>
|
35
|
+
<a class="text-secondary" href="mailto:info@insiting.com" title="<%= t(".help") %>">
|
36
|
+
<%= t(".help") %>
|
37
37
|
</a>
|
38
38
|
<% end %>
|
39
39
|
<% end %>
|
@@ -5,8 +5,8 @@
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
6
|
<%= csrf_meta_tags %>
|
7
7
|
<%= csp_meta_tag %>
|
8
|
-
<%= stylesheet_pack_tag
|
9
|
-
<%= javascript_pack_tag
|
8
|
+
<%= stylesheet_pack_tag "admin", media: "all", "data-turbolinks-track": "reload" %>
|
9
|
+
<%= javascript_pack_tag "admin", "data-turbolinks-track": "reload" %>
|
10
10
|
</head>
|
11
11
|
<body class="bg-light w-100 vh-100">
|
12
12
|
|
@@ -14,11 +14,11 @@
|
|
14
14
|
<% breadcrumb_count = breadcrumbs.count %>
|
15
15
|
<% breadcrumbs.each_with_index do |breadcrumb, index| %>
|
16
16
|
<% last = (index == breadcrumb_count - 1) %>
|
17
|
-
<li class="breadcrumb-item text-muted" aria-current="<%= last ?
|
17
|
+
<li class="breadcrumb-item text-muted" aria-current="<%= last ? "page" : nil %>">
|
18
18
|
<% if last %>
|
19
19
|
<%= breadcrumb.name %>
|
20
20
|
<% else %>
|
21
|
-
<%= link_to_unless_current(breadcrumb.name, breadcrumb.path, class:
|
21
|
+
<%= link_to_unless_current(breadcrumb.name, breadcrumb.path, class: "text-muted text-decoration-none") %>
|
22
22
|
<% end %>
|
23
23
|
</li>
|
24
24
|
<% end %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# Your content
|
11
11
|
# <% end %#>
|
12
12
|
|
13
|
-
class_names = local_assigns.has_key?(:class) ? local_assigns[:class] :
|
13
|
+
class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : "btn-group"
|
14
14
|
%>
|
15
15
|
|
16
16
|
<div class="dropdown <%= class_names %>">
|
@@ -7,22 +7,27 @@
|
|
7
7
|
# ==== Examples
|
8
8
|
# Basic version
|
9
9
|
# <%= render "headmin/filters" do %#>
|
10
|
-
# <%= render "headmin/filters/select", name:
|
10
|
+
# <%= render "headmin/filters/select", name: "color", options: ["red", "green", "blue"] %#>
|
11
11
|
# <% end %#>
|
12
12
|
#
|
13
13
|
# With custom URL
|
14
14
|
# <%= render "headmin/filters", url: admin_polls_path %#>
|
15
15
|
|
16
16
|
action = local_assigns.has_key?(:url) ? url : request.path
|
17
|
-
%>
|
18
17
|
|
19
|
-
|
18
|
+
begin
|
19
|
+
model = controller_name.singularize.capitalize.constantize
|
20
|
+
rescue
|
21
|
+
raise "Cannot find class!"
|
22
|
+
end
|
23
|
+
%>
|
20
24
|
|
25
|
+
<%= form_with model: model.new, url: action, method: :get, data: {controller: "filters", filters_target: "form"} do |form| %>
|
21
26
|
<%# Perform yield in order to capture content blocks, pass form so we can use headmin form inputs %>
|
22
27
|
<%= yield(form) %>
|
23
28
|
|
24
29
|
<!-- Default parameters (e.g. sorting, pagination) -->
|
25
|
-
<% default_params.except(
|
30
|
+
<% default_params.except("page").each do |name, value| %>
|
26
31
|
<%= form.hidden_field name.to_sym, value: value %>
|
27
32
|
<% end %>
|
28
33
|
|
@@ -44,8 +49,8 @@
|
|
44
49
|
<% if content_for?(:filters_menu) %>
|
45
50
|
<div class="btn-group">
|
46
51
|
<button type="button" class="btn h-btn-outline-light dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
47
|
-
<%= bootstrap_icon(
|
48
|
-
<%= t(
|
52
|
+
<%= bootstrap_icon("funnel") %>
|
53
|
+
<%= t(".button") %>
|
49
54
|
</button>
|
50
55
|
<ul class="dropdown-menu">
|
51
56
|
<%= content_for :filters_menu %>
|
@@ -53,7 +58,7 @@
|
|
53
58
|
<hr class="dropdown-divider">
|
54
59
|
</li>
|
55
60
|
<li>
|
56
|
-
<a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t(
|
61
|
+
<a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t(".remove_all") %></a>
|
57
62
|
</li>
|
58
63
|
</ul>
|
59
64
|
</div>
|
@@ -12,7 +12,7 @@
|
|
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
13
|
<% content_for :collection_total_count, collection.total_count.to_s unless content_for?(:collection_total_count) %>
|
14
14
|
<div class="ms-2 me-md-2 text-secondary flex-grow-1 flex-shrink-0">
|
15
|
-
<%= t(
|
15
|
+
<%= t(".items", count: content_for(:collection_total_count).to_i) %>
|
16
16
|
</div>
|
17
|
-
<%= paginate collection, views_prefix:
|
17
|
+
<%= paginate collection, views_prefix: "headmin/pagination" %>
|
18
18
|
</div>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
# To trigger this popup create an element with a data attribute like this
|
9
9
|
#
|
10
10
|
# <button data-popup-id="popupId">open Popup</button>
|
11
|
-
# <%= render "headmin/popup", id:
|
11
|
+
# <%= render "headmin/popup", id: "popupId" do %#>
|
12
12
|
# popup Content
|
13
13
|
# <% end %#>
|
14
14
|
#
|
@@ -16,14 +16,14 @@
|
|
16
16
|
# "data-popup-pass-thru" attribute.
|
17
17
|
#
|
18
18
|
# <button data-popup-id="popupId" data-popup-pass-thru="#link">open Popup</button>
|
19
|
-
# <%= render "headmin/popup", id:
|
19
|
+
# <%= render "headmin/popup", id: "popupId" do %#>
|
20
20
|
# <a href="https://example.com" id="link">
|
21
21
|
# <% end %#>
|
22
22
|
data = local_assigns.has_key?(:data) ? data : {}
|
23
23
|
|
24
24
|
options = {
|
25
|
-
class: [
|
26
|
-
data: data.merge(
|
25
|
+
class: ["h-popup", "closed"],
|
26
|
+
data: data.merge("popup-target": "popup", "popup-id": id)
|
27
27
|
}
|
28
28
|
%>
|
29
29
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
total_count = content_for(:collection_total_count).to_i || nil
|
14
14
|
%>
|
15
15
|
|
16
|
-
<div class="h-table card my-2 shadow-sm <%=
|
16
|
+
<div class="h-table card my-2 shadow-sm <%= "table-drag-sort" if sort_url %>" data-sort-url="<%= sort_url %>">
|
17
17
|
<div class="table-responsive">
|
18
18
|
<table class="table table-hover m-0"
|
19
19
|
data-controller="table"
|
@@ -1,11 +1,35 @@
|
|
1
|
-
<%
|
1
|
+
<%
|
2
|
+
# headmin/thumbnail
|
3
|
+
#
|
4
|
+
# ==== Required parameters
|
5
|
+
# * +file+ - Name of the attribute of the form model
|
6
|
+
#
|
7
|
+
# ==== Optional parameters
|
8
|
+
# * +width+ - Width of the thumbnail. Set to nil to fill according to the original aspect ratio
|
9
|
+
# * +height+ - Height of the thumbnail. Set to nil to fill according to the original aspect ratio
|
10
|
+
# * +icon+ - Force icon to be shown instead of a thumbnail
|
11
|
+
#
|
12
|
+
# ==== References
|
13
|
+
# https://headmin.dev/docs/thumbnail
|
14
|
+
#
|
15
|
+
# ==== Examples
|
16
|
+
# Basic version
|
17
|
+
# <%= render "headmin/thumbnail", file: file %#>
|
18
|
+
#
|
19
|
+
# Custom size (200px x 100px)
|
20
|
+
# <%= render "headmin/thumbnail", file: file, width: 200, height: 100 %#>
|
21
|
+
#
|
22
|
+
# Custom (bootstrap) icon
|
23
|
+
# <%= render "headmin/thumbnail", file: file, icon: "file-earmark-excel" %#>
|
24
|
+
thumbnail = Headmin::ThumbnailView.new(local_assigns)
|
25
|
+
%>
|
2
26
|
|
3
|
-
<div class="<%= thumbnail.class_names %>"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<%= bootstrap_icon(thumbnail.icon_name, class:
|
9
|
-
|
10
|
-
|
27
|
+
<div class="<%= thumbnail.class_names %>">
|
28
|
+
<div class="h-thumbnail-bg" style="min-width: <%= thumbnail.width || 100 %>px; min-height: <%= thumbnail.height || 100 %>px;">
|
29
|
+
<% if thumbnail.variable? && !thumbnail.icon? %>
|
30
|
+
<%= image_tag(thumbnail.file.variant(thumbnail.variant_options)) %>
|
31
|
+
<% else %>
|
32
|
+
<%= bootstrap_icon(thumbnail.icon_name, class: "h-thumbnail-icon") %>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
11
35
|
</div>
|
@@ -5,8 +5,8 @@
|
|
5
5
|
id: unique identifier for the dropdown
|
6
6
|
class: css class names as string
|
7
7
|
%>
|
8
|
-
<% id = local_assigns.has_key?(:id) ? id :
|
9
|
-
<% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] :
|
8
|
+
<% id = local_assigns.has_key?(:id) ? id : "dropdown-1" %>
|
9
|
+
<% class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : "btn" %>
|
10
10
|
|
11
11
|
<a class="dropdown-toggle d-flex align-items-center <%= class_names %>" type="button" id="<%= id %>" data-bs-toggle="dropdown" aria-expanded="false">
|
12
12
|
<%= yield %>
|
@@ -8,8 +8,8 @@
|
|
8
8
|
%>
|
9
9
|
|
10
10
|
<% method = local_assigns.has_key?(:method) ? method : nil %>
|
11
|
-
<% url = local_assigns.has_key?(:url) ? url :
|
12
|
-
<% name = local_assigns.has_key?(:name) ? name :
|
11
|
+
<% url = local_assigns.has_key?(:url) ? url : "" %>
|
12
|
+
<% name = local_assigns.has_key?(:name) ? name : "" %>
|
13
13
|
|
14
14
|
<li>
|
15
15
|
<a class="dropdown-item" href="<%= url %>" <%= "data-turbo-method=#{method}" if method %>>
|
@@ -7,10 +7,10 @@
|
|
7
7
|
#
|
8
8
|
# ==== Examples
|
9
9
|
# Basic version
|
10
|
-
# <%= render "headmin/dropdown/list", id:
|
10
|
+
# <%= render "headmin/dropdown/list", id: "dropdown-1" %#>
|
11
11
|
|
12
|
-
class_names = local_assigns.has_key?(:class) ? local_assigns[:class] :
|
13
|
-
id = local_assigns.has_key?(:id) ? id :
|
12
|
+
class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : ""
|
13
|
+
id = local_assigns.has_key?(:id) ? id : "dropdown-1"
|
14
14
|
%>
|
15
15
|
|
16
16
|
<ul class="dropdown-menu <%= class_names %>" aria-labelledby="<%= id %>">
|
@@ -5,13 +5,13 @@
|
|
5
5
|
%>
|
6
6
|
|
7
7
|
<%= render "headmin/dropdown" do %>
|
8
|
-
<%= render "headmin/dropdown/button", id:
|
9
|
-
<%= bootstrap_icon(
|
10
|
-
<%= t(
|
8
|
+
<%= render "headmin/dropdown/button", id: "locale-dropdown" do %>
|
9
|
+
<%= bootstrap_icon("globe", class: "me-2") %>
|
10
|
+
<%= t("language_name", locale: ::I18n.locale) %>
|
11
11
|
<% end %>
|
12
|
-
<%= render "headmin/dropdown/list", id:
|
12
|
+
<%= render "headmin/dropdown/list", id: "locale-dropdown" do %>
|
13
13
|
<% I18n.available_locales.each do |locale| %>
|
14
|
-
<%= render "headmin/dropdown/item", name: t(
|
14
|
+
<%= render "headmin/dropdown/item", name: t("language_name", locale: locale), url: url_for({locale: locale.to_s}) %>
|
15
15
|
<% end %>
|
16
16
|
<% end %>
|
17
17
|
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/filters/association
|
3
|
+
#
|
4
|
+
# ==== Required parameters
|
5
|
+
# * +attribute+ - Name of the attribute to be filtered
|
6
|
+
# * +collection+ - Values to create option tags for
|
7
|
+
# * +form+ - Form object
|
8
|
+
#
|
9
|
+
# ==== Optional parameters
|
10
|
+
# * +label+ - Display label
|
11
|
+
# * +name+ - Name of the filter parameter
|
12
|
+
#
|
13
|
+
# ==== Examples
|
14
|
+
# Basic version
|
15
|
+
# <%= render "headmin/filters", url: admin_orders_path do |form| %#>
|
16
|
+
# <%= render "headmin/filters/association", form: form, attribute: :product %#>
|
17
|
+
# <% end %#>
|
18
|
+
|
19
|
+
association = Headmin::Filter::AssociationView.new(local_assigns.merge(params: params))
|
20
|
+
%>
|
21
|
+
|
22
|
+
<%= render "headmin/filters/base", association.base_options do |value| %>
|
23
|
+
<%= render "headmin/forms/select", association.input_options.merge(selected: value) %>
|
24
|
+
<% end %>
|
@@ -19,11 +19,11 @@
|
|
19
19
|
>
|
20
20
|
<%= raw("#{button_view.label} #{button_view.filter&.string(display_values: button_view.display_values)}") %>
|
21
21
|
<span class="h-filter-remove" data-action="click->filters#remove">
|
22
|
-
<%= bootstrap_icon(
|
22
|
+
<%= bootstrap_icon("x-lg") %>
|
23
23
|
</span>
|
24
24
|
</button>
|
25
25
|
|
26
|
-
<%= render "headmin/popup", id: "#{button_view.id}", data: {
|
26
|
+
<%= render "headmin/popup", id: "#{button_view.id}", data: {"filter-target": "popup"} do %>
|
27
27
|
<%= yield %>
|
28
28
|
<% end %>
|
29
29
|
</div>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<select class="form-select" data-filter-row-target="null" data-action="change->filter#updateHiddenValue" data-filter-target="value">
|
2
2
|
<option value="1" <%= value == 1 ? "selected" : "" %>>
|
3
|
-
<%= t(
|
3
|
+
<%= t("headmin.filters.values.yes") %>
|
4
4
|
</option>
|
5
5
|
<option value="0" <%= value == 0 ? "selected" : "" %>>
|
6
|
-
<%= t(
|
6
|
+
<%= t("headmin.filters.values.no") %>
|
7
7
|
</option>
|
8
8
|
</select>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/forms/association
|
3
|
+
#
|
4
|
+
# ==== Required parameters
|
5
|
+
# * +attribute+ - Name of the association
|
6
|
+
# * +form+ - Form object
|
7
|
+
#
|
8
|
+
# ==== Optional parameters
|
9
|
+
# * +collection+ - Values to create option tags for
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# ==== Examples
|
13
|
+
# Basic version
|
14
|
+
# <%= form_with do |form| %#>
|
15
|
+
# <%= render "headmin/forms/association", form: form, attribute: :product %#>
|
16
|
+
# <% end %#>
|
17
|
+
|
18
|
+
association = Headmin::Form::AssociationView.new(local_assigns)
|
19
|
+
|
20
|
+
%>
|
21
|
+
|
22
|
+
<%= render "headmin/forms/wrapper", association.wrapper_options do %>
|
23
|
+
<%= render "headmin/forms/label", association.label_options if association.prepend_label? %>
|
24
|
+
<%= render "headmin/forms/input_group", association.input_group_options do %>
|
25
|
+
<%= form.select(association.attribute_with_id, association.collection, association.select_options, association.input_options) %>
|
26
|
+
<% end %>
|
27
|
+
<%= render "headmin/forms/validation", association.validation_options if association.validate? %>
|
28
|
+
<%= render "headmin/forms/hint", association.hint_options if association.hint? %>
|
29
|
+
<%= render "headmin/forms/label", association.label_options if association.append_label? %>
|
30
|
+
<% end %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<% if form.object.errors.any? %>
|
9
9
|
<div class="alert alert-danger" role="alert">
|
10
10
|
<h5 class="alert-heading d-flex align-items-center">
|
11
|
-
<%= t(
|
11
|
+
<%= t("errors.template.header", count: form.object.errors.size, model: form.object.model_name.human) %>
|
12
12
|
</h5>
|
13
13
|
<ul class="mb-0">
|
14
14
|
<% form.object.errors.full_messages.each do |message| %>
|