headmin 0.5.0 → 0.5.3
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 +10 -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/repeater.scss +4 -0
- data/app/assets/stylesheets/headmin/forms.scss +7 -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/table.scss +15 -0
- data/app/assets/stylesheets/headmin.css +70 -7
- 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 +1 -1
- data/app/models/concerns/headmin/fieldable.rb +19 -10
- data/app/models/concerns/headmin/form/hintable.rb +6 -1
- data/app/models/headmin/blocks_view.rb +1 -1
- data/app/models/headmin/filter/date.rb +49 -1
- data/app/models/headmin/form/color_view.rb +48 -0
- data/app/models/headmin/form/media_view.rb +113 -0
- data/app/models/headmin/form/textarea_view.rb +6 -1
- data/app/views/examples/admin.html.erb +8 -8
- data/app/views/examples/auth.html.erb +2 -2
- data/app/views/headmin/_blocks.html.erb +1 -1
- 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 +5 -5
- 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 +1 -1
- 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/filter/_button.html.erb +2 -2
- data/app/views/headmin/filters/filter/_null_select.html.erb +2 -2
- data/app/views/headmin/forms/_color.html.erb +32 -0
- data/app/views/headmin/forms/_errors.html.erb +1 -1
- data/app/views/headmin/forms/_file.html.erb +7 -7
- data/app/views/headmin/forms/_hint.html.erb +6 -1
- data/app/views/headmin/forms/_media.html.erb +58 -0
- data/app/views/headmin/forms/_repeater.html.erb +9 -9
- data/app/views/headmin/forms/_textarea.html.erb +1 -1
- data/app/views/headmin/forms/media/_item.html.erb +32 -0
- data/app/views/headmin/forms/media/_validation.html.erb +10 -0
- data/app/views/headmin/forms/repeater/_row.html.erb +15 -14
- 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 +17 -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 +1 -1
- data/app/views/headmin/table/body/_boolean.erb +4 -4
- data/app/views/headmin/table/body/_color.html.erb +10 -0
- 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 +11 -11
- data/app/views/headmin/views/devise/unlocks/_new.html.erb +1 -1
- data/config/locales/devise/nl.yml +1 -1
- 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 +22 -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 +30 -2
@@ -17,10 +17,19 @@ module Headmin
|
|
17
17
|
@fields_hash = hash
|
18
18
|
end
|
19
19
|
|
20
|
+
def include_tables
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_include_tables
|
25
|
+
[files_attachments: :blob]
|
26
|
+
end
|
27
|
+
|
20
28
|
private
|
21
29
|
|
22
30
|
def parse_fields
|
23
|
-
fields.
|
31
|
+
hash_tree = fields.includes(default_include_tables | include_tables).hash_tree
|
32
|
+
parse_hash_tree(hash_tree)
|
24
33
|
end
|
25
34
|
|
26
35
|
def build_fields
|
@@ -95,10 +104,11 @@ module Headmin
|
|
95
104
|
name: name,
|
96
105
|
field_type: "file",
|
97
106
|
value: nil,
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
107
|
+
files_attachments_attributes: [
|
108
|
+
{
|
109
|
+
blob: ActiveStorage::Blob.create_and_upload!(io: file, filename: File.basename(file.path))
|
110
|
+
}
|
111
|
+
]
|
102
112
|
)
|
103
113
|
end
|
104
114
|
|
@@ -108,11 +118,10 @@ module Headmin
|
|
108
118
|
name: name,
|
109
119
|
field_type: "files",
|
110
120
|
value: nil,
|
111
|
-
|
112
|
-
|
113
|
-
io: file,
|
114
|
-
|
115
|
-
)
|
121
|
+
files_attachments_attributes: files.map { |file|
|
122
|
+
{
|
123
|
+
blob: ActiveStorage::Blob.create_and_upload!(io: file, filename: File.basename(file.path))
|
124
|
+
}
|
116
125
|
}
|
117
126
|
)
|
118
127
|
end
|
@@ -3,16 +3,64 @@ module Headmin
|
|
3
3
|
class Date < Headmin::Filter::Base
|
4
4
|
OPERATORS = %w[eq not_eq gt gteq lt lteq between not_between in not_in is_null is_not_null]
|
5
5
|
|
6
|
+
QUERY_OPERATOR_CONVERT_TO = {
|
7
|
+
between: %w[eq],
|
8
|
+
not_between: %w[not_eq]
|
9
|
+
}
|
10
|
+
|
11
|
+
OPERATORS_CONVERT_TO = {
|
12
|
+
convert_to_range: %w[between not_between],
|
13
|
+
convert_to_array: %w[in not_in],
|
14
|
+
convert_to_value: %w[matches does_not_match is_null is_not_null starts_with ends_with],
|
15
|
+
convert_to_datetime_equals: %w[eq not_eq],
|
16
|
+
convert_to_datetime_begin: %w[lt gteq],
|
17
|
+
convert_to_datetime_end: %w[gt lteq]
|
18
|
+
}
|
19
|
+
|
6
20
|
def cast_value(value)
|
7
21
|
value.present? ? value.to_date : ::Date.current
|
8
22
|
rescue
|
9
23
|
raise TypeError, "The value that was passed to this filter is not a date"
|
10
24
|
end
|
11
25
|
|
26
|
+
def values
|
27
|
+
@instructions.map { |instruction| output_value(instruction) }.compact
|
28
|
+
end
|
29
|
+
|
30
|
+
def output_value(instruction)
|
31
|
+
if %w[eq not_eq].include?(instruction[:operator])
|
32
|
+
instruction[:value].last.to_date
|
33
|
+
elsif %w[lt lteq gt gteq].include?(instruction[:operator])
|
34
|
+
instruction[:value].to_date
|
35
|
+
else
|
36
|
+
instruction[:value]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def convert_to_datetime_equals(value)
|
41
|
+
casted_date = cast_value(value)
|
42
|
+
|
43
|
+
(casted_date - 1.day).end_of_day..casted_date.end_of_day
|
44
|
+
end
|
45
|
+
|
46
|
+
def convert_to_datetime_begin(value)
|
47
|
+
casted_date = cast_value(value)
|
48
|
+
casted_date.beginning_of_day
|
49
|
+
end
|
50
|
+
|
51
|
+
def convert_to_datetime_end(value)
|
52
|
+
casted_date = cast_value(value)
|
53
|
+
casted_date.end_of_day
|
54
|
+
end
|
55
|
+
|
12
56
|
def display_value(value)
|
13
57
|
# This uses the default date format of headmin.
|
14
58
|
# Can be overwritten by setting default date format of the application.
|
15
|
-
|
59
|
+
if value.class.to_s == "Range"
|
60
|
+
I18n.l(value.last.to_date)
|
61
|
+
else
|
62
|
+
I18n.l(value.to_date)
|
63
|
+
end
|
16
64
|
end
|
17
65
|
end
|
18
66
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Form
|
3
|
+
class ColorView < ViewModel
|
4
|
+
include Headmin::Form::Hintable
|
5
|
+
include Headmin::Form::Labelable
|
6
|
+
include Headmin::Form::Validatable
|
7
|
+
include Headmin::Form::Wrappable
|
8
|
+
|
9
|
+
def input_options
|
10
|
+
keys = attributes - %i[attribute form label validate wrapper]
|
11
|
+
options = to_h.slice(*keys)
|
12
|
+
default_input_options.deep_merge(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def label_options
|
16
|
+
{
|
17
|
+
class: ["form-label"],
|
18
|
+
attribute: attribute,
|
19
|
+
form: form,
|
20
|
+
required: required,
|
21
|
+
text: label
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def value
|
26
|
+
@form.object&.send(@attribute) || "#000000"
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrapper_options
|
30
|
+
default_wrapper_options.deep_merge(
|
31
|
+
{
|
32
|
+
}
|
33
|
+
).deep_merge(@wrapper || {})
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def default_input_options
|
39
|
+
{
|
40
|
+
aria: {describedby: validation_id},
|
41
|
+
class: ["form-control form-control-color", validation_class],
|
42
|
+
placeholder: placeholder,
|
43
|
+
title: value
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,113 @@
|
|
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: "#{attribute}_#{object_id}",
|
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 custom_validation_options
|
32
|
+
{
|
33
|
+
form: form,
|
34
|
+
attribute: attribute,
|
35
|
+
min: min,
|
36
|
+
max: max
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def association_object
|
41
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
42
|
+
result = form.object.send(nested_attribute)
|
43
|
+
result = result.order(position: :asc) if sort
|
44
|
+
result
|
45
|
+
else
|
46
|
+
form.object.send(nested_attribute)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def attachments
|
51
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
52
|
+
result = form.object.send(nested_attribute)
|
53
|
+
result = result.order(position: :asc) if sort
|
54
|
+
result.to_a.compact
|
55
|
+
else
|
56
|
+
[form.object.send(nested_attribute)].compact
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def attached
|
61
|
+
form.object.send(attribute)
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_nested_attribute
|
65
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
66
|
+
form.object.send(nested_attribute).build
|
67
|
+
else
|
68
|
+
form.object.send("build_#{nested_attribute}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def nested_attribute
|
73
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
74
|
+
:"#{attribute}_attachments"
|
75
|
+
else
|
76
|
+
:"#{attribute}_attachment"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def min
|
81
|
+
if @required
|
82
|
+
@min.to_i < 1 ? 1 : @min.to_i
|
83
|
+
else
|
84
|
+
@min.to_i < 1 ? 0 : @min.to_i
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def max
|
89
|
+
if attached.is_a?(ActiveStorage::Attached::Many)
|
90
|
+
@max
|
91
|
+
else
|
92
|
+
1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def required
|
97
|
+
@required ? 1 : nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def blob_ids
|
101
|
+
attachments.map { |attachment| attachment.blob_id }
|
102
|
+
end
|
103
|
+
|
104
|
+
def media_modal_url
|
105
|
+
headmin_media_url(name: "#{attribute}_#{object_id}", ids: blob_ids, min: min, max: max)
|
106
|
+
end
|
107
|
+
|
108
|
+
def sort
|
109
|
+
@sort == true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
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
|
@@ -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
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
# <%= render "headmin/blocks", blockable: @page, paths: %w(website/pages/blocks) %#>
|
16
16
|
|
17
17
|
blocks = Headmin::BlocksView.new(local_assigns)
|
18
|
-
@lookup_context.prefixes =
|
18
|
+
@lookup_context.prefixes = blocks.prefixes + @lookup_context.prefixes
|
19
19
|
%>
|
20
20
|
|
21
21
|
<% if blockable && blockable.respond_to?(:blocks) %>
|
@@ -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,7 +7,7 @@
|
|
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
|
@@ -22,7 +22,7 @@
|
|
22
22
|
<%= yield(form) %>
|
23
23
|
|
24
24
|
<!-- Default parameters (e.g. sorting, pagination) -->
|
25
|
-
<% default_params.except(
|
25
|
+
<% default_params.except("page").each do |name, value| %>
|
26
26
|
<%= form.hidden_field name.to_sym, value: value %>
|
27
27
|
<% end %>
|
28
28
|
|
@@ -44,8 +44,8 @@
|
|
44
44
|
<% if content_for?(:filters_menu) %>
|
45
45
|
<div class="btn-group">
|
46
46
|
<button type="button" class="btn h-btn-outline-light dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
47
|
-
<%= bootstrap_icon(
|
48
|
-
<%= t(
|
47
|
+
<%= bootstrap_icon("funnel") %>
|
48
|
+
<%= t(".button") %>
|
49
49
|
</button>
|
50
50
|
<ul class="dropdown-menu">
|
51
51
|
<%= content_for :filters_menu %>
|
@@ -53,7 +53,7 @@
|
|
53
53
|
<hr class="dropdown-divider">
|
54
54
|
</li>
|
55
55
|
<li>
|
56
|
-
<a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t(
|
56
|
+
<a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t(".remove_all") %></a>
|
57
57
|
</li>
|
58
58
|
</ul>
|
59
59
|
</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"
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<div class="h-thumbnail-bg" style="background-image: url('<%= thumbnail.src %>');"></div>
|
6
6
|
<% else %>
|
7
7
|
<div class="h-thumbnail-bg">
|
8
|
-
<%= bootstrap_icon(thumbnail.icon_name, class:
|
8
|
+
<%= bootstrap_icon(thumbnail.icon_name, class: "h-thumbnail-icon") %>
|
9
9
|
</div>
|
10
10
|
<% end %>
|
11
11
|
</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 %>
|
@@ -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,32 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/forms/color
|
3
|
+
#
|
4
|
+
# ==== Required parameters
|
5
|
+
# * +attribute+ - Name of the attribute of the form model
|
6
|
+
# * +form+ - Form object
|
7
|
+
#
|
8
|
+
# ==== Optional parameters
|
9
|
+
# * +hint+ - Informative text to assist with data input. HTML markup is allowed.
|
10
|
+
# * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
|
11
|
+
# * +wrapper+ - Hash with all options for the surrounding html tag
|
12
|
+
#
|
13
|
+
# ==== References
|
14
|
+
# https://headmin.dev/docs/forms/color
|
15
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color
|
16
|
+
# https://apidock.com/rails/v5.2.3/ActionView/Helpers/FormHelper/color_field
|
17
|
+
#
|
18
|
+
# ==== Examples
|
19
|
+
# Basic version
|
20
|
+
# <%= form_with do |form| %#>
|
21
|
+
# <%= render "headmin/forms/color", form: form, attribute: :active %#>
|
22
|
+
# <% end %#>
|
23
|
+
|
24
|
+
color = Headmin::Form::ColorView.new(local_assigns)
|
25
|
+
%>
|
26
|
+
|
27
|
+
<%= render "headmin/forms/wrapper", color.wrapper_options do %>
|
28
|
+
<%= render "headmin/forms/label", color.label_options if color.label? %>
|
29
|
+
<%= form.color_field(color.attribute, color.input_options) %>
|
30
|
+
<%= render "headmin/forms/validation", color.validation_options if color.validate? %>
|
31
|
+
<%= render "headmin/forms/hint", color.hint_options if color.hint? %>
|
32
|
+
<% 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| %>
|