lato_cms 3.0.9 → 3.0.10
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/app/assets/javascripts/lato_cms/controllers/lato_cms_repeater_controller.js +29 -1
- data/app/controllers/lato_cms/pages_controller.rb +13 -0
- data/app/views/lato_cms/pages/_repeater.html.erb +8 -3
- data/config/locales/en.yml +2 -0
- data/config/locales/it.yml +2 -0
- data/lib/lato_cms/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67cc56a05385cb8ed79d06de5407bae73f23444f0872e02021696ebc1dd4000b
|
|
4
|
+
data.tar.gz: 794483334a4c7906ad00a370448ce488650bc6a94b6755a5f84bd2c909fd3676
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d020a8b135ea587b61396ed1d8bc8314a9066a165d576e3a31aeb4c127894d0e0652729adf4c3c634a70ef07b075f54de1010d70dcff0ffbdb3f6218e3641fc7
|
|
7
|
+
data.tar.gz: 20a54bfd7811d1de1acfe2b44af5012fb5d1f810ab9fc2c84b037431e98b9f28541ae9c2a0dc17061db40670c72ce213670404e158ad40b991a35e2f6a534aec
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
|
2
2
|
|
|
3
3
|
export default class extends Controller {
|
|
4
|
-
static targets = ['items', 'template', 'item', 'position', 'orderInput']
|
|
4
|
+
static targets = ['items', 'template', 'item', 'position', 'orderInput', 'addButton']
|
|
5
|
+
static values = { min: { type: Number, default: 0 }, max: { type: Number, default: 0 } }
|
|
6
|
+
|
|
7
|
+
connect () {
|
|
8
|
+
this.refresh()
|
|
9
|
+
}
|
|
5
10
|
|
|
6
11
|
add () {
|
|
12
|
+
// Guard against exceeding max even if the button state is stale.
|
|
13
|
+
if (this.maxValue > 0 && this.itemTargets.length >= this.maxValue) return
|
|
14
|
+
|
|
7
15
|
const itemId = window.crypto.randomUUID()
|
|
8
16
|
const html = this.templateTarget.innerHTML
|
|
9
17
|
.replaceAll('NEW_RECORD', itemId)
|
|
@@ -14,6 +22,9 @@ export default class extends Controller {
|
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
remove (event) {
|
|
25
|
+
// Block removal below the required minimum.
|
|
26
|
+
if (this.minValue > 0 && this.itemTargets.length <= this.minValue) return
|
|
27
|
+
|
|
17
28
|
const item = event.currentTarget.closest('[data-lato-cms-repeater-target="item"]')
|
|
18
29
|
if (!item) return
|
|
19
30
|
|
|
@@ -29,5 +40,22 @@ export default class extends Controller {
|
|
|
29
40
|
const orderInput = item.querySelector('[data-lato-cms-repeater-target="orderInput"]')
|
|
30
41
|
if (orderInput) orderInput.value = item.dataset.repeaterItemId
|
|
31
42
|
})
|
|
43
|
+
|
|
44
|
+
this.updateControls()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Toggle add/remove availability against the min/max constraints.
|
|
48
|
+
updateControls () {
|
|
49
|
+
const count = this.itemTargets.length
|
|
50
|
+
|
|
51
|
+
if (this.hasAddButtonTarget) {
|
|
52
|
+
this.addButtonTarget.disabled = this.maxValue > 0 && count >= this.maxValue
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const disableRemove = this.minValue > 0 && count <= this.minValue
|
|
56
|
+
this.itemTargets.forEach((item) => {
|
|
57
|
+
const removeButton = item.querySelector('[data-action~="lato-cms-repeater#remove"]')
|
|
58
|
+
if (removeButton) removeButton.disabled = disableRemove
|
|
59
|
+
})
|
|
32
60
|
}
|
|
33
61
|
}
|
|
@@ -233,6 +233,19 @@ module LatoCms
|
|
|
233
233
|
component_id = template_component[:component_id]
|
|
234
234
|
item_ids = Array(repeater_order).reject(&:blank?).map(&:to_s)
|
|
235
235
|
|
|
236
|
+
# Enforce min/max item count (authoritative check). Missing settings = no constraint.
|
|
237
|
+
settings = template_component[:settings] || {}
|
|
238
|
+
min = settings['min'].presence && settings['min'].to_i
|
|
239
|
+
max = settings['max'].presence && settings['max'].to_i
|
|
240
|
+
if min && item_ids.size < min
|
|
241
|
+
errors << { field_id: template_component_id, errors: [t('lato_cms.repeater_min_error', count: min)] }
|
|
242
|
+
return
|
|
243
|
+
end
|
|
244
|
+
if max && item_ids.size > max
|
|
245
|
+
errors << { field_id: template_component_id, errors: [t('lato_cms.repeater_max_error', count: max)] }
|
|
246
|
+
return
|
|
247
|
+
end
|
|
248
|
+
|
|
236
249
|
order_field = @page.fields.find_or_initialize_by(
|
|
237
250
|
template_id: @page.template_id,
|
|
238
251
|
template_component_id: template_component_id,
|
|
@@ -2,9 +2,14 @@
|
|
|
2
2
|
<% saved_order = begin; order_field&.value.present? ? JSON.parse(order_field.value) : []; rescue JSON::ParserError; []; end %>
|
|
3
3
|
<% fields_by_item = component_fields.reject(&:repeater_order?).group_by(&:repeater_item_id) %>
|
|
4
4
|
<% item_ids = (saved_order.presence || fields_by_item.keys.compact) %>
|
|
5
|
-
<%
|
|
5
|
+
<% min = tc[:settings]['min'].to_i %>
|
|
6
|
+
<% max = tc[:settings]['max'].to_i %>
|
|
7
|
+
<%# Seed `min` empty items when the list is empty, so the minimum is met up front. %>
|
|
8
|
+
<% item_ids = Array.new(min) { SecureRandom.uuid } if item_ids.blank? && min.positive? %>
|
|
6
9
|
|
|
7
|
-
<div data-controller="lato-cms-repeater"
|
|
10
|
+
<div data-controller="lato-cms-repeater"
|
|
11
|
+
data-lato-cms-repeater-min-value="<%= min %>"
|
|
12
|
+
data-lato-cms-repeater-max-value="<%= max %>">
|
|
8
13
|
<div data-lato-cms-repeater-target="items">
|
|
9
14
|
<% item_ids.each_with_index do |item_id, item_index| %>
|
|
10
15
|
<% item_fields = (fields_by_item[item_id] || []).index_by(&:base_field_id) %>
|
|
@@ -16,7 +21,7 @@
|
|
|
16
21
|
<%= render 'lato_cms/pages/repeater_item', tc: tc, item_id: 'NEW_RECORD', item_index: 'NEW_INDEX', item_fields: {} %>
|
|
17
22
|
</template>
|
|
18
23
|
|
|
19
|
-
<button type="button" class="btn btn-sm btn-outline-primary" data-action="lato-cms-repeater#add">
|
|
24
|
+
<button type="button" class="btn btn-sm btn-outline-primary" data-action="lato-cms-repeater#add" data-lato-cms-repeater-target="addButton">
|
|
20
25
|
<i class="bi bi-plus-lg me-1"></i><%= t('lato_cms.repeater_add_item') %>
|
|
21
26
|
</button>
|
|
22
27
|
</div>
|
data/config/locales/en.yml
CHANGED
|
@@ -80,6 +80,8 @@ en:
|
|
|
80
80
|
fields_save_component: Save
|
|
81
81
|
repeater_add_item: Add item
|
|
82
82
|
repeater_remove_item: Remove
|
|
83
|
+
repeater_min_error: "At least %{count} items are required"
|
|
84
|
+
repeater_max_error: "At most %{count} items are allowed"
|
|
83
85
|
fields_component_missing_alert_html: "Component <strong>%{component_id}</strong> not found. The component configuration may have been removed."
|
|
84
86
|
fields_previously_saved_data: "Previously saved data:"
|
|
85
87
|
field_file_remove: Remove
|
data/config/locales/it.yml
CHANGED
|
@@ -80,6 +80,8 @@ it:
|
|
|
80
80
|
fields_save_component: Salva
|
|
81
81
|
repeater_add_item: Aggiungi elemento
|
|
82
82
|
repeater_remove_item: Rimuovi
|
|
83
|
+
repeater_min_error: "Sono richiesti almeno %{count} elementi"
|
|
84
|
+
repeater_max_error: "Sono ammessi al massimo %{count} elementi"
|
|
83
85
|
fields_component_missing_alert_html: "Componente <strong>%{component_id}</strong> non trovato. La configurazione del componente potrebbe essere stata rimossa."
|
|
84
86
|
fields_previously_saved_data: "Dati salvati in precedenza:"
|
|
85
87
|
field_file_remove: Rimuovi
|
data/lib/lato_cms/version.rb
CHANGED