headmin 0.5.5 → 0.5.6
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/Gemfile.lock +2 -2
- data/app/assets/javascripts/headmin/controllers/media_controller.js +1 -39
- data/app/assets/javascripts/headmin/controllers/repeater_controller.js +16 -4
- data/app/assets/javascripts/headmin.js +10 -33
- data/app/assets/stylesheets/headmin.css +1 -1
- data/app/controllers/headmin/media_controller.rb +8 -3
- data/app/models/concerns/headmin/blob.rb +36 -0
- data/app/models/concerns/headmin/field.rb +1 -1
- data/app/models/concerns/headmin/fieldable.rb +4 -1
- data/app/models/headmin/filter/field_view.rb +1 -1
- data/app/models/headmin/form/media_item_view.rb +4 -0
- data/app/models/headmin/form/media_view.rb +5 -1
- data/app/views/headmin/forms/_media.html.erb +3 -5
- data/app/views/headmin/media/_modal.html.erb +1 -1
- data/app/views/headmin/media/index.html.erb +1 -1
- data/config/initializers/extend_active_storage_blob.rb +3 -0
- data/config/locales/headmin/forms/en.yml +0 -8
- data/config/locales/headmin/forms/nl.yml +0 -8
- data/lib/headmin/version.rb +1 -1
- data/package.json +1 -1
- metadata +4 -3
- data/app/views/headmin/forms/media/_validation.html.erb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f5b560711076cca763871af2499728101e4f8d7a27a04f5c702671165e134d7
|
4
|
+
data.tar.gz: ed2d18ec0405786fd9b4f18984e750571062124828fc1102a662f78e0333c03e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8afa230d5e31dad3cbaa288fe46849672af9c4df118b4e9a9ed8024eea60da7d1089865b3678ee67860cfe88d34f67ba3a3db0c2b8ee1e37ebfbe515e2ae07fc
|
7
|
+
data.tar.gz: 106023130df278d025a608345e763aac87b6586736e511fd05866703876b296de9ae08d43ea5fd86d3f7cb75d378935e3aa86ff2d9f519d50434ee02e6453dc8
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
headmin (0.5.
|
4
|
+
headmin (0.5.5)
|
5
5
|
closure_tree (~> 7.4)
|
6
6
|
inline_svg (~> 1.7)
|
7
7
|
redcarpet (~> 3.5)
|
@@ -226,7 +226,7 @@ GEM
|
|
226
226
|
actionpack (>= 5.0)
|
227
227
|
railties (>= 5.0)
|
228
228
|
rexml (3.2.5)
|
229
|
-
rouge (3.
|
229
|
+
rouge (3.30.0)
|
230
230
|
route_translator (12.1.0)
|
231
231
|
actionpack (>= 5.2, < 7.1)
|
232
232
|
activesupport (>= 5.2, < 7.1)
|
@@ -3,7 +3,7 @@ import Sortable from 'sortablejs'
|
|
3
3
|
|
4
4
|
export default class extends Controller {
|
5
5
|
static get targets () {
|
6
|
-
return ['item', 'template', 'thumbnails', 'modalButton', 'placeholder', '
|
6
|
+
return ['item', 'template', 'thumbnails', 'modalButton', 'placeholder', 'count', 'editButton']
|
7
7
|
}
|
8
8
|
|
9
9
|
connect () {
|
@@ -17,8 +17,6 @@ export default class extends Controller {
|
|
17
17
|
if (this.hasSorting()) {
|
18
18
|
this.initSortable()
|
19
19
|
}
|
20
|
-
|
21
|
-
this.validate()
|
22
20
|
}
|
23
21
|
|
24
22
|
// Actions
|
@@ -83,42 +81,6 @@ export default class extends Controller {
|
|
83
81
|
|
84
82
|
// Toggle placeholder
|
85
83
|
this.togglePlaceholder()
|
86
|
-
|
87
|
-
// Validate
|
88
|
-
this.validate()
|
89
|
-
}
|
90
|
-
|
91
|
-
validate () {
|
92
|
-
this.clearValidation()
|
93
|
-
if (this.element.dataset.required === '0') return
|
94
|
-
this.validateMinimum()
|
95
|
-
this.validateMaximum()
|
96
|
-
}
|
97
|
-
|
98
|
-
clearValidation () {
|
99
|
-
this.validationInputTarget.setCustomValidity('')
|
100
|
-
}
|
101
|
-
|
102
|
-
validateMinimum () {
|
103
|
-
const count = this.activeItems().length
|
104
|
-
if (count < this.minActiveItems()) {
|
105
|
-
this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.minMessage)
|
106
|
-
}
|
107
|
-
}
|
108
|
-
|
109
|
-
validateMaximum () {
|
110
|
-
const count = this.activeItems().length
|
111
|
-
if (count > this.maxActiveItems()) {
|
112
|
-
this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.maxMessage)
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
|
-
minActiveItems () {
|
117
|
-
return parseInt(this.element.dataset.min, 10) || 0
|
118
|
-
}
|
119
|
-
|
120
|
-
maxActiveItems () {
|
121
|
-
return parseInt(this.element.dataset.max, 10) || Infinity
|
122
84
|
}
|
123
85
|
|
124
86
|
resetPositions () {
|
@@ -80,8 +80,8 @@ export default class extends Controller {
|
|
80
80
|
row.remove()
|
81
81
|
} else {
|
82
82
|
// Existing records are hidden and flagged for deletion
|
83
|
-
|
84
|
-
row.
|
83
|
+
this.flagRowForDeletion(row)
|
84
|
+
row.remove()
|
85
85
|
}
|
86
86
|
|
87
87
|
this.resetIndices()
|
@@ -89,6 +89,18 @@ export default class extends Controller {
|
|
89
89
|
this.toggleEmpty()
|
90
90
|
}
|
91
91
|
|
92
|
+
flagRowForDeletion (row) {
|
93
|
+
const destroyInput = row.querySelector('input[name*=\'_destroy\']')
|
94
|
+
const idInput = row.querySelector('input[name*=\'[id]\']')
|
95
|
+
|
96
|
+
// Update _destroy value
|
97
|
+
destroyInput.value = 1
|
98
|
+
|
99
|
+
// Move away from row
|
100
|
+
this.listTarget.parentNode.appendChild(destroyInput)
|
101
|
+
this.listTarget.parentNode.appendChild(idInput)
|
102
|
+
}
|
103
|
+
|
92
104
|
getTemplate (name) {
|
93
105
|
return this.templateTargets.filter((template) => {
|
94
106
|
return template.dataset.templateName === name
|
@@ -107,7 +119,7 @@ export default class extends Controller {
|
|
107
119
|
visibleRows () {
|
108
120
|
const rows = this.rowTargets
|
109
121
|
return rows.filter((row) => {
|
110
|
-
return row.querySelector(
|
122
|
+
return row.querySelector('input[name*=\'_destroy\']').value !== '1'
|
111
123
|
})
|
112
124
|
}
|
113
125
|
|
@@ -121,7 +133,7 @@ export default class extends Controller {
|
|
121
133
|
|
122
134
|
resetPositions () {
|
123
135
|
this.visibleRows().forEach((row, index) => {
|
124
|
-
const positionInput = row.querySelector(
|
136
|
+
const positionInput = row.querySelector('input[name*=\'position\']')
|
125
137
|
if (positionInput) {
|
126
138
|
positionInput.value = index
|
127
139
|
}
|
@@ -10096,7 +10096,7 @@ var hello_controller_default = class extends Controller {
|
|
10096
10096
|
// app/assets/javascripts/headmin/controllers/media_controller.js
|
10097
10097
|
var media_controller_default = class extends Controller {
|
10098
10098
|
static get targets() {
|
10099
|
-
return ["item", "template", "thumbnails", "modalButton", "placeholder", "
|
10099
|
+
return ["item", "template", "thumbnails", "modalButton", "placeholder", "count", "editButton"];
|
10100
10100
|
}
|
10101
10101
|
connect() {
|
10102
10102
|
document.addEventListener("mediaSelectionSubmitted", (event) => {
|
@@ -10107,7 +10107,6 @@ var media_controller_default = class extends Controller {
|
|
10107
10107
|
if (this.hasSorting()) {
|
10108
10108
|
this.initSortable();
|
10109
10109
|
}
|
10110
|
-
this.validate();
|
10111
10110
|
}
|
10112
10111
|
destroy(event) {
|
10113
10112
|
const item = event.currentTarget.closest("[data-media-target='item']");
|
@@ -10148,35 +10147,6 @@ var media_controller_default = class extends Controller {
|
|
10148
10147
|
this.resetPositions();
|
10149
10148
|
this.syncIds();
|
10150
10149
|
this.togglePlaceholder();
|
10151
|
-
this.validate();
|
10152
|
-
}
|
10153
|
-
validate() {
|
10154
|
-
this.clearValidation();
|
10155
|
-
if (this.element.dataset.required === "0")
|
10156
|
-
return;
|
10157
|
-
this.validateMinimum();
|
10158
|
-
this.validateMaximum();
|
10159
|
-
}
|
10160
|
-
clearValidation() {
|
10161
|
-
this.validationInputTarget.setCustomValidity("");
|
10162
|
-
}
|
10163
|
-
validateMinimum() {
|
10164
|
-
const count = this.activeItems().length;
|
10165
|
-
if (count < this.minActiveItems()) {
|
10166
|
-
this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.minMessage);
|
10167
|
-
}
|
10168
|
-
}
|
10169
|
-
validateMaximum() {
|
10170
|
-
const count = this.activeItems().length;
|
10171
|
-
if (count > this.maxActiveItems()) {
|
10172
|
-
this.validationInputTarget.setCustomValidity(this.validationInputTarget.dataset.maxMessage);
|
10173
|
-
}
|
10174
|
-
}
|
10175
|
-
minActiveItems() {
|
10176
|
-
return parseInt(this.element.dataset.min, 10) || 0;
|
10177
|
-
}
|
10178
|
-
maxActiveItems() {
|
10179
|
-
return parseInt(this.element.dataset.max, 10) || Infinity;
|
10180
10150
|
}
|
10181
10151
|
resetPositions() {
|
10182
10152
|
this.activeItems().forEach((item, index2) => {
|
@@ -15559,13 +15529,20 @@ var repeater_controller_default = class extends Controller {
|
|
15559
15529
|
if (row.dataset.newRecord === "true") {
|
15560
15530
|
row.remove();
|
15561
15531
|
} else {
|
15562
|
-
|
15563
|
-
row.
|
15532
|
+
this.flagRowForDeletion(row);
|
15533
|
+
row.remove();
|
15564
15534
|
}
|
15565
15535
|
this.resetIndices();
|
15566
15536
|
this.resetPositions();
|
15567
15537
|
this.toggleEmpty();
|
15568
15538
|
}
|
15539
|
+
flagRowForDeletion(row) {
|
15540
|
+
const destroyInput = row.querySelector("input[name*='_destroy']");
|
15541
|
+
const idInput = row.querySelector("input[name*='[id]']");
|
15542
|
+
destroyInput.value = 1;
|
15543
|
+
this.listTarget.parentNode.appendChild(destroyInput);
|
15544
|
+
this.listTarget.parentNode.appendChild(idInput);
|
15545
|
+
}
|
15569
15546
|
getTemplate(name) {
|
15570
15547
|
return this.templateTargets.filter((template) => {
|
15571
15548
|
return template.dataset.templateName === name;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
@charset "UTF-8";
|
2
2
|
@import "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css";
|
3
3
|
|
4
|
-
/* sass-plugin-0:/
|
4
|
+
/* sass-plugin-0:/opt/homebrew/var/www/headmin/src/scss/headmin.scss */
|
5
5
|
:root {
|
6
6
|
--bs-blue: #0d6efd;
|
7
7
|
--bs-indigo: #6610f2;
|
@@ -4,12 +4,12 @@ class Headmin::MediaController < HeadminController
|
|
4
4
|
def index
|
5
5
|
@blobs =
|
6
6
|
ActiveStorage::Blob
|
7
|
-
.
|
8
|
-
.
|
9
|
-
.or(ActiveStorage::Blob.where(active_storage_attachments: {id: nil})) # Or an orphan
|
7
|
+
.not_attached_to_variant
|
8
|
+
.by_mimetypes_string(media_params[:mimetype])
|
10
9
|
.order(created_at: :desc)
|
11
10
|
.group(:id)
|
12
11
|
.all
|
12
|
+
@mimetypes = media_params[:mimetype]
|
13
13
|
end
|
14
14
|
|
15
15
|
def create
|
@@ -42,6 +42,11 @@ class Headmin::MediaController < HeadminController
|
|
42
42
|
|
43
43
|
def media_params
|
44
44
|
params.permit(
|
45
|
+
:min,
|
46
|
+
:max,
|
47
|
+
:name,
|
48
|
+
:mimetype,
|
49
|
+
ids: [],
|
45
50
|
files: []
|
46
51
|
)
|
47
52
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Blob
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class << self
|
7
|
+
def not_attached_to_variant
|
8
|
+
left_outer_joins(:attachments)
|
9
|
+
.where.not(active_storage_attachments: {record_type: "ActiveStorage::VariantRecord"})
|
10
|
+
.or(is_orphan)
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_orphan
|
14
|
+
left_outer_joins(:attachments)
|
15
|
+
.where(active_storage_attachments: {id: nil})
|
16
|
+
end
|
17
|
+
|
18
|
+
def by_mimetypes_string(mimetype_string)
|
19
|
+
by_mimetypes(mimetype_string.split(","))
|
20
|
+
end
|
21
|
+
|
22
|
+
def by_mimetypes(mimetypes = [])
|
23
|
+
results = self
|
24
|
+
|
25
|
+
mimetypes.map.with_index do |mimetype, index|
|
26
|
+
content_type = mimetype.tr("*", "%")
|
27
|
+
query = where(arel_table[:content_type].matches(content_type))
|
28
|
+
results = index == 0 ? query : results.or(query)
|
29
|
+
end
|
30
|
+
|
31
|
+
results
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -4,7 +4,7 @@ module Headmin
|
|
4
4
|
|
5
5
|
included do
|
6
6
|
# Configuration
|
7
|
-
has_closure_tree order: "position", numeric_order: true
|
7
|
+
has_closure_tree order: "position", numeric_order: true, dependent: :destroy
|
8
8
|
|
9
9
|
# Associations
|
10
10
|
belongs_to :fieldable, polymorphic: true, optional: true, touch: true
|
@@ -28,7 +28,10 @@ module Headmin
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def parse_fields
|
31
|
-
hash_tree =
|
31
|
+
hash_tree = {}
|
32
|
+
fields.roots.includes(default_include_tables | include_tables).each do |field|
|
33
|
+
field.hash_tree.map { |key, value| hash_tree[key] = value }
|
34
|
+
end
|
32
35
|
parse_hash_tree(hash_tree)
|
33
36
|
end
|
34
37
|
|
@@ -27,7 +27,7 @@ module Headmin
|
|
27
27
|
{
|
28
28
|
label: label,
|
29
29
|
name: "field_#{attribute}".to_sym,
|
30
|
-
filter: Headmin::Filter::Field.new(
|
30
|
+
filter: Headmin::Filter::Field.new(attribute.to_s.to_sym, @params),
|
31
31
|
allowed_operators: Headmin::Filter::Field::OPERATORS - %w[in not_in]
|
32
32
|
}
|
33
33
|
end
|
@@ -23,6 +23,7 @@ module Headmin
|
|
23
23
|
min: min,
|
24
24
|
max: max,
|
25
25
|
sort: sort,
|
26
|
+
accept: accept,
|
26
27
|
required: required.nil? ? 0 : required
|
27
28
|
}
|
28
29
|
}).deep_merge(@wrapper || {})
|
@@ -45,7 +46,8 @@ module Headmin
|
|
45
46
|
form: form,
|
46
47
|
attribute: attribute,
|
47
48
|
min: min,
|
48
|
-
max: max
|
49
|
+
max: max,
|
50
|
+
accept: accept
|
49
51
|
}
|
50
52
|
end
|
51
53
|
|
@@ -117,6 +119,8 @@ module Headmin
|
|
117
119
|
end
|
118
120
|
end
|
119
121
|
|
122
|
+
attr_reader :accept
|
123
|
+
|
120
124
|
def required
|
121
125
|
@required ? 1 : nil
|
122
126
|
end
|
@@ -31,16 +31,14 @@
|
|
31
31
|
<%= render "headmin/forms/wrapper", media.wrapper_options do %>
|
32
32
|
<%= render "headmin/forms/label", media.label_options if media.prepend_label? %>
|
33
33
|
<div class="h-form-file-thumbnails" data-media-target="thumbnails">
|
34
|
-
<%= render "headmin/forms/media/validation", media.custom_validation_options %>
|
35
|
-
|
36
34
|
<!-- Render previews for attachments -->
|
37
35
|
<%= form.fields_for(media.nested_attribute, media.association_object) do |ff| %>
|
38
|
-
<%= render "headmin/forms/media/item", media.item_options.merge(form: ff, url: headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max)) %>
|
36
|
+
<%= render "headmin/forms/media/item", media.item_options.merge(form: ff, url: headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max, mimetype: media.accept)) %>
|
39
37
|
<% end %>
|
40
38
|
|
41
39
|
<!-- Placeholder -->
|
42
40
|
<div class="<%= "d-none" if media.attachments.any? %>" data-media-target="placeholder">
|
43
|
-
<a href="<%= headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max) %>" data-turbo-frame="remote_modal" data-media-target="modalButton">
|
41
|
+
<a href="<%= headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max, mimetype: media.accept) %>" data-turbo-frame="remote_modal" data-media-target="modalButton">
|
44
42
|
<%= render "headmin/thumbnail", media.thumbnail_options %>
|
45
43
|
</a>
|
46
44
|
</div>
|
@@ -50,7 +48,7 @@
|
|
50
48
|
<% association_object = ActiveStorage::Attachment.new %>
|
51
49
|
<template data-media-target="template" data-template-id-regex="<%= association_object.object_id %>">
|
52
50
|
<%= form.fields_for(media.nested_attribute, ActiveStorage::Attachment.new, child_index: association_object.object_id) do |ff| %>
|
53
|
-
<%= render "headmin/forms/media/item", media.item_options.merge(form: ff, url: headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max)) %>
|
51
|
+
<%= render "headmin/forms/media/item", media.item_options.merge(form: ff, url: headmin_media_url(name: media.name, ids: media.blob_ids, min: media.min, max: media.max, mimetype: media.accept)) %>
|
54
52
|
<% end %>
|
55
53
|
</template>
|
56
54
|
|
@@ -22,7 +22,7 @@
|
|
22
22
|
<%= form.label :files, class: "btn h-btn-outline-light" do %>
|
23
23
|
<%= bootstrap_icon("upload") %>
|
24
24
|
<%= t(".upload") %>
|
25
|
-
<%= form.file_field :files, class: "d-none", multiple: true, data: {action: "change->media-modal#submitForm"} %>
|
25
|
+
<%= form.file_field :files, accept: mimetypes, class: "d-none", multiple: true, data: {action: "change->media-modal#submitForm"} %>
|
26
26
|
<% end %>
|
27
27
|
<% end %>
|
28
28
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><%= t(".close") %></button>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<%= turbo_frame_tag "remote_modal" do %>
|
2
|
-
<%= render "headmin/media/modal", blobs: @blobs, name: params[:name], min: params[:min], max: params[:max] %>
|
2
|
+
<%= render "headmin/media/modal", blobs: @blobs, mimetypes: @mimetypes, name: params[:name], min: params[:min], max: params[:max] %>
|
3
3
|
<% end %>
|
@@ -18,14 +18,6 @@ en:
|
|
18
18
|
remove:
|
19
19
|
title: Delete
|
20
20
|
confirm: Are you sure you want to delete this?
|
21
|
-
media:
|
22
|
-
validation:
|
23
|
-
min:
|
24
|
-
one: "Please select at least 1 item"
|
25
|
-
other: "Please select at least %{count} items"
|
26
|
-
max:
|
27
|
-
one: "Please limit your selection to maximum 1 item"
|
28
|
-
other: "Please limit your selection to maximum %{count} items"
|
29
21
|
select:
|
30
22
|
blank: Make a choice
|
31
23
|
repeater:
|
@@ -17,14 +17,6 @@ nl:
|
|
17
17
|
remove:
|
18
18
|
title: Verwijderen
|
19
19
|
confirm: Ben je zeker dat je dit wil verwijderen?
|
20
|
-
media:
|
21
|
-
validation:
|
22
|
-
min:
|
23
|
-
one: "Gelieve minstens 1 item te selecteren"
|
24
|
-
other: "Gelieve minstens %{count} items te selecteren"
|
25
|
-
max:
|
26
|
-
one: "Gelieve maximum 1 item te selecteren"
|
27
|
-
other: "Gelieve maximum %{count} items te selecteren"
|
28
20
|
select:
|
29
21
|
blank: Maak een keuze
|
30
22
|
repeater:
|
data/lib/headmin/version.rb
CHANGED
data/package.json
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: headmin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jef Vlamings
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: closure_tree
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- app/helpers/headmin/form_helper.rb
|
245
245
|
- app/helpers/headmin/notification_helper.rb
|
246
246
|
- app/helpers/headmin/request_helper.rb
|
247
|
+
- app/models/concerns/headmin/blob.rb
|
247
248
|
- app/models/concerns/headmin/block.rb
|
248
249
|
- app/models/concerns/headmin/blockable.rb
|
249
250
|
- app/models/concerns/headmin/field.rb
|
@@ -393,7 +394,6 @@ files:
|
|
393
394
|
- app/views/headmin/forms/fields/_list.html.erb
|
394
395
|
- app/views/headmin/forms/fields/_text.html.erb
|
395
396
|
- app/views/headmin/forms/media/_item.html.erb
|
396
|
-
- app/views/headmin/forms/media/_validation.html.erb
|
397
397
|
- app/views/headmin/forms/repeater/_row.html.erb
|
398
398
|
- app/views/headmin/heading/_title.html.erb
|
399
399
|
- app/views/headmin/layout/_body.html.erb
|
@@ -466,6 +466,7 @@ files:
|
|
466
466
|
- bin/setup
|
467
467
|
- config/importmap.rb
|
468
468
|
- config/initializers/customize_input_error.rb
|
469
|
+
- config/initializers/extend_active_storage_blob.rb
|
469
470
|
- config/locales/activerecord/en.yml
|
470
471
|
- config/locales/activerecord/nl.yml
|
471
472
|
- config/locales/defaults/en.yml
|
@@ -1,10 +0,0 @@
|
|
1
|
-
<!-- Custom validation field -->
|
2
|
-
<%= form.text_field :"validation_#{attribute}",
|
3
|
-
name: nil,
|
4
|
-
value: nil,
|
5
|
-
class: "h-form-media-validation",
|
6
|
-
data: {
|
7
|
-
"media-target": "validationInput",
|
8
|
-
"min-message": t(".min", count: min),
|
9
|
-
"max-message": t(".max", count: max),
|
10
|
-
} %>
|