lato_cms 3.0.0 → 3.0.1
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_gallery_field_controller.js +3 -3
- data/app/assets/javascripts/lato_cms/controllers/lato_cms_repeater_controller.js +33 -0
- data/app/controllers/lato_cms/pages_controller.rb +92 -48
- data/app/helpers/lato_cms/pages_helper.rb +15 -2
- data/app/models/lato_cms/page.rb +35 -4
- data/app/models/lato_cms/page_field.rb +22 -2
- data/app/models/lato_cms/template_manager.rb +2 -0
- data/app/views/lato_cms/pages/_component_accordion.html.erb +13 -9
- data/app/views/lato_cms/pages/_repeater.html.erb +22 -0
- data/app/views/lato_cms/pages/_repeater_item.html.erb +28 -0
- data/app/views/lato_cms/pages/fields/_boolean.html.erb +6 -4
- data/app/views/lato_cms/pages/fields/_color.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_date.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_datetime.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_file.html.erb +6 -3
- data/app/views/lato_cms/pages/fields/_gallery.html.erb +3 -2
- data/app/views/lato_cms/pages/fields/_image.html.erb +6 -3
- data/app/views/lato_cms/pages/fields/_json.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_multiselect.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_number.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_select.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_string.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_text.html.erb +5 -3
- data/app/views/lato_cms/pages/fields/_textarea.html.erb +5 -3
- data/config/locales/en.yml +2 -0
- data/config/locales/it.yml +2 -0
- data/lib/lato_cms/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce57b3c62b4c5ad59c91a5ec2f01e0eb958bfd5244097e2df0b7210f625e1a0e
|
|
4
|
+
data.tar.gz: b6304761ec5116b821b75660140fdab9002a6a8e13b68923e0df77ace2fb53d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 997c72993680123c414c978e5291ffb511f7c7b19f728c23aa8535e84c226002ee7a2a950e07513f48b7840a79db55ee0c7ef9f0319e1dd2f62f44a70c957e51
|
|
7
|
+
data.tar.gz: a11ae95caf80c3d4ceacb798f5515da2ca6f0448d1f1c859d8ed5819112adde51b5035e829f03d6791c7308b229a3880d83d09bc30fc74df216035f58f102422
|
|
@@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
2
2
|
|
|
3
3
|
export default class extends Controller {
|
|
4
4
|
static targets = ["grid", "fileInput", "emptyMsg"]
|
|
5
|
-
static values = { fieldId: String }
|
|
5
|
+
static values = { fieldId: String, inputNamePrefix: String }
|
|
6
6
|
|
|
7
7
|
dragging = null
|
|
8
8
|
newFileMap = new Map()
|
|
@@ -42,7 +42,7 @@ export default class extends Controller {
|
|
|
42
42
|
if (attachmentId) {
|
|
43
43
|
const input = document.createElement('input')
|
|
44
44
|
input.type = 'hidden'
|
|
45
|
-
input.name =
|
|
45
|
+
input.name = `${this.inputNamePrefixValue}[remove_file_ids][]`
|
|
46
46
|
input.value = attachmentId
|
|
47
47
|
this.element.appendChild(input)
|
|
48
48
|
} else if (fileUid) {
|
|
@@ -96,7 +96,7 @@ export default class extends Controller {
|
|
|
96
96
|
if (!id) return
|
|
97
97
|
const input = document.createElement('input')
|
|
98
98
|
input.type = 'hidden'
|
|
99
|
-
input.name =
|
|
99
|
+
input.name = `${this.inputNamePrefixValue}[order][]`
|
|
100
100
|
input.value = id
|
|
101
101
|
input.setAttribute('data-gallery-order-input', '')
|
|
102
102
|
this.element.appendChild(input)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static targets = ['items', 'template', 'item', 'position', 'orderInput']
|
|
5
|
+
|
|
6
|
+
add () {
|
|
7
|
+
const itemId = window.crypto.randomUUID()
|
|
8
|
+
const html = this.templateTarget.innerHTML
|
|
9
|
+
.replaceAll('NEW_RECORD', itemId)
|
|
10
|
+
.replaceAll('NEW_INDEX', this.itemTargets.length.toString())
|
|
11
|
+
|
|
12
|
+
this.itemsTarget.insertAdjacentHTML('beforeend', html)
|
|
13
|
+
this.refresh()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
remove (event) {
|
|
17
|
+
const item = event.currentTarget.closest('[data-lato-cms-repeater-target="item"]')
|
|
18
|
+
if (!item) return
|
|
19
|
+
|
|
20
|
+
item.remove()
|
|
21
|
+
this.refresh()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
refresh () {
|
|
25
|
+
this.itemTargets.forEach((item, index) => {
|
|
26
|
+
const position = item.querySelector('[data-lato-cms-repeater-target="position"]')
|
|
27
|
+
if (position) position.textContent = index + 1
|
|
28
|
+
|
|
29
|
+
const orderInput = item.querySelector('[data-lato-cms-repeater-target="orderInput"]')
|
|
30
|
+
if (orderInput) orderInput.value = item.dataset.repeaterItemId
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -77,55 +77,13 @@ module LatoCms
|
|
|
77
77
|
return
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
field = @page.fields.find_or_initialize_by(
|
|
82
|
-
template_id: @page.template_id,
|
|
83
|
-
template_component_id: template_component_id,
|
|
84
|
-
component_id: component_id,
|
|
85
|
-
field_id: field_id
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
field_config = component&.dig('fields', field_id)
|
|
89
|
-
field_type = field_config&.dig('type') || 'string'
|
|
90
|
-
|
|
91
|
-
case field_type
|
|
92
|
-
when 'file', 'image'
|
|
93
|
-
field.save if field.new_record?
|
|
94
|
-
if field_data[:files].present?
|
|
95
|
-
Array(field_data[:files]).compact.each { |f| field.files.attach(f) }
|
|
96
|
-
end
|
|
97
|
-
if field_data[:remove_file_ids].present?
|
|
98
|
-
Array(field_data[:remove_file_ids]).reject(&:blank?).each do |file_id_to_remove|
|
|
99
|
-
field.files.find { |f| f.id == file_id_to_remove.to_i }&.purge
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
when 'gallery'
|
|
103
|
-
field.save if field.new_record?
|
|
104
|
-
if field_data[:files].present?
|
|
105
|
-
Array(field_data[:files]).compact.each { |f| field.files.attach(f) }
|
|
106
|
-
end
|
|
107
|
-
if field_data[:remove_file_ids].present?
|
|
108
|
-
Array(field_data[:remove_file_ids]).reject(&:blank?).each do |file_id_to_remove|
|
|
109
|
-
field.files.find { |f| f.id == file_id_to_remove.to_i }&.purge
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
# Persist order: existing IDs in dragged order + any new file IDs appended at end
|
|
113
|
-
order = Array(field_data[:order]).reject(&:blank?).map(&:to_s)
|
|
114
|
-
all_ids = field.files.reload.map { |f| f.id.to_s }
|
|
115
|
-
sorted = order.select { |id| all_ids.include?(id) }
|
|
116
|
-
new_ids = all_ids - sorted
|
|
117
|
-
field.value = (sorted + new_ids).to_json
|
|
118
|
-
when 'multiselect'
|
|
119
|
-
value = field_data[:value]
|
|
120
|
-
value = Array(value).reject(&:blank?)
|
|
121
|
-
field.value = value.to_json
|
|
122
|
-
else
|
|
123
|
-
raw_value = field_data.is_a?(ActionController::Parameters) ? field_data[:value] : field_data
|
|
124
|
-
field.value = raw_value.to_s.presence
|
|
125
|
-
end
|
|
80
|
+
template_component = @page.template_components.find { |tc| tc[:template_component_id] == template_component_id.to_s }
|
|
126
81
|
|
|
127
|
-
|
|
128
|
-
|
|
82
|
+
if template_component&.dig(:repeater)
|
|
83
|
+
save_repeater_fields(template_component, component, params[:repeater_items] || {}, params[:repeater_order] || [], errors)
|
|
84
|
+
else
|
|
85
|
+
fields_data.each do |field_id, field_data|
|
|
86
|
+
save_field(component, template_component_id, component_id, field_id, field_id, field_data, errors)
|
|
129
87
|
end
|
|
130
88
|
end
|
|
131
89
|
|
|
@@ -183,6 +141,92 @@ module LatoCms
|
|
|
183
141
|
|
|
184
142
|
private
|
|
185
143
|
|
|
144
|
+
def save_repeater_fields(template_component, component, repeater_items, repeater_order, errors)
|
|
145
|
+
template_component_id = template_component[:template_component_id]
|
|
146
|
+
component_id = template_component[:component_id]
|
|
147
|
+
item_ids = Array(repeater_order).reject(&:blank?).map(&:to_s)
|
|
148
|
+
|
|
149
|
+
order_field = @page.fields.find_or_initialize_by(
|
|
150
|
+
template_id: @page.template_id,
|
|
151
|
+
template_component_id: template_component_id,
|
|
152
|
+
component_id: component_id,
|
|
153
|
+
field_id: LatoCms::PageField::REPEATER_ORDER_FIELD_ID
|
|
154
|
+
)
|
|
155
|
+
order_field.value = item_ids.to_json
|
|
156
|
+
errors << { field_id: order_field.field_id, errors: order_field.errors.full_messages } unless order_field.save
|
|
157
|
+
|
|
158
|
+
existing_item_ids = @page.fields.where(template_component_id: template_component_id).reject(&:repeater_order?).filter_map(&:repeater_item_id).uniq
|
|
159
|
+
removed_item_ids = existing_item_ids - item_ids
|
|
160
|
+
removed_item_ids.each do |item_id|
|
|
161
|
+
@page.fields
|
|
162
|
+
.where(template_component_id: template_component_id)
|
|
163
|
+
.where("field_id LIKE ?", "#{ActiveRecord::Base.sanitize_sql_like(item_id)}.%")
|
|
164
|
+
.destroy_all
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
item_ids.each do |item_id|
|
|
168
|
+
item_fields = repeater_items[item_id] || repeater_items[item_id.to_sym] || {}
|
|
169
|
+
(template_component[:fields] || {}).each_key do |field_id|
|
|
170
|
+
field_data = item_fields[field_id] || item_fields[field_id.to_sym] || {}
|
|
171
|
+
save_field(component, template_component_id, component_id, field_id, "#{item_id}.#{field_id}", field_data, errors)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def save_field(component, template_component_id, component_id, config_field_id, persisted_field_id, field_data, errors)
|
|
177
|
+
field = @page.fields.find_or_initialize_by(
|
|
178
|
+
template_id: @page.template_id,
|
|
179
|
+
template_component_id: template_component_id,
|
|
180
|
+
component_id: component_id,
|
|
181
|
+
field_id: persisted_field_id
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
field_config = component&.dig('fields', config_field_id)
|
|
185
|
+
field_type = field_config&.dig('type') || 'string'
|
|
186
|
+
|
|
187
|
+
assign_field_value(field, field_type, field_data)
|
|
188
|
+
|
|
189
|
+
unless field.save
|
|
190
|
+
errors << { field_id: persisted_field_id, errors: field.errors.full_messages }
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def assign_field_value(field, field_type, field_data)
|
|
195
|
+
case field_type
|
|
196
|
+
when 'file', 'image'
|
|
197
|
+
field.save if field.new_record?
|
|
198
|
+
attach_field_files(field, field_data)
|
|
199
|
+
remove_field_files(field, field_data)
|
|
200
|
+
when 'gallery'
|
|
201
|
+
field.save if field.new_record?
|
|
202
|
+
attach_field_files(field, field_data)
|
|
203
|
+
remove_field_files(field, field_data)
|
|
204
|
+
order = Array(field_data[:order]).reject(&:blank?).map(&:to_s)
|
|
205
|
+
all_ids = field.files.reload.map { |f| f.id.to_s }
|
|
206
|
+
sorted = order.select { |id| all_ids.include?(id) }
|
|
207
|
+
field.value = (sorted + (all_ids - sorted)).to_json
|
|
208
|
+
when 'multiselect'
|
|
209
|
+
field.value = Array(field_data[:value]).reject(&:blank?).to_json
|
|
210
|
+
else
|
|
211
|
+
raw_value = field_data.is_a?(ActionController::Parameters) ? field_data[:value] : field_data
|
|
212
|
+
field.value = raw_value.to_s.presence
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def attach_field_files(field, field_data)
|
|
217
|
+
return unless field_data[:files].present?
|
|
218
|
+
|
|
219
|
+
Array(field_data[:files]).compact.each { |file| field.files.attach(file) }
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def remove_field_files(field, field_data)
|
|
223
|
+
return unless field_data[:remove_file_ids].present?
|
|
224
|
+
|
|
225
|
+
Array(field_data[:remove_file_ids]).reject(&:blank?).each do |file_id_to_remove|
|
|
226
|
+
field.files.find { |file| file.id == file_id_to_remove.to_i }&.purge
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
186
230
|
def create_params
|
|
187
231
|
params.require(:page).permit(:title, :locale)
|
|
188
232
|
end
|
|
@@ -42,17 +42,30 @@ module LatoCms
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
def lato_cms_render_field(field_id:, field_config:, page_field:)
|
|
45
|
+
def lato_cms_render_field(field_id:, field_config:, page_field:, input_name_prefix: nil, dom_id_prefix: nil)
|
|
46
46
|
render resolve_lato_cms_field_partial(field_config),
|
|
47
47
|
field_id: field_id,
|
|
48
48
|
field_config: field_config,
|
|
49
|
-
page_field: page_field
|
|
49
|
+
page_field: page_field,
|
|
50
|
+
input_name_prefix: input_name_prefix,
|
|
51
|
+
dom_id_prefix: dom_id_prefix
|
|
50
52
|
rescue ActionView::MissingTemplate => e
|
|
51
53
|
content_tag(:div, class: 'alert alert-danger mb-0') do
|
|
52
54
|
"Field '#{field_id}' render error: #{e.message}"
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
|
|
58
|
+
def lato_cms_field_input_name(field_id, suffix = 'value', input_name_prefix: nil, multiple: false)
|
|
59
|
+
base = input_name_prefix.presence || "fields[#{field_id}]"
|
|
60
|
+
name = "#{base}[#{suffix}]"
|
|
61
|
+
multiple ? "#{name}[]" : name
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def lato_cms_field_dom_id(field_id, suffix = 'value', dom_id_prefix: nil)
|
|
65
|
+
base = dom_id_prefix.presence || "fields_#{field_id}"
|
|
66
|
+
"#{base}_#{suffix}".parameterize(separator: '_')
|
|
67
|
+
end
|
|
68
|
+
|
|
56
69
|
private
|
|
57
70
|
|
|
58
71
|
def resolve_lato_cms_field_partial(field_config)
|
data/app/models/lato_cms/page.rb
CHANGED
|
@@ -87,14 +87,45 @@ module LatoCms
|
|
|
87
87
|
hash[tc[:template_component_id]] = {
|
|
88
88
|
component_id: tc[:component_id],
|
|
89
89
|
name: tc[:name],
|
|
90
|
-
fields:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end
|
|
90
|
+
fields: tc[:repeater] ?
|
|
91
|
+
build_repeater_fields_json(tc, fields_by_component[tc[:template_component_id]] || []) :
|
|
92
|
+
build_component_fields_json(tc, component_fields)
|
|
94
93
|
}
|
|
95
94
|
end
|
|
96
95
|
end
|
|
97
96
|
|
|
97
|
+
def build_component_fields_json(tc, component_fields)
|
|
98
|
+
(tc[:fields] || {}).each_with_object({}) do |(fid, fconfig), fhash|
|
|
99
|
+
field = component_fields[fid.to_s]
|
|
100
|
+
fhash[fid] = field ? field.as_json : empty_field_json(fid.to_s, fconfig)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def build_repeater_fields_json(tc, component_fields)
|
|
105
|
+
order = repeater_order(component_fields)
|
|
106
|
+
fields_by_item = component_fields.reject(&:repeater_order?).group_by(&:repeater_item_id)
|
|
107
|
+
item_ids = order.presence || fields_by_item.keys.compact
|
|
108
|
+
|
|
109
|
+
item_ids.filter_map do |item_id|
|
|
110
|
+
item_fields = (fields_by_item[item_id] || []).index_by(&:base_field_id)
|
|
111
|
+
next if item_fields.blank?
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
id: item_id,
|
|
115
|
+
fields: build_component_fields_json(tc, item_fields)
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def repeater_order(component_fields)
|
|
121
|
+
order_field = component_fields.find(&:repeater_order?)
|
|
122
|
+
return [] unless order_field&.value.present?
|
|
123
|
+
|
|
124
|
+
JSON.parse(order_field.value)
|
|
125
|
+
rescue JSON::ParserError
|
|
126
|
+
[]
|
|
127
|
+
end
|
|
128
|
+
|
|
98
129
|
def empty_field_json(fid, fconfig)
|
|
99
130
|
{
|
|
100
131
|
id: nil,
|
|
@@ -10,6 +10,8 @@ module LatoCms
|
|
|
10
10
|
validates :field_id, presence: true
|
|
11
11
|
validates :field_id, uniqueness: { scope: [:page_id, :template_component_id] }
|
|
12
12
|
|
|
13
|
+
REPEATER_ORDER_FIELD_ID = "__repeater_order".freeze
|
|
14
|
+
|
|
13
15
|
before_save :parse_value
|
|
14
16
|
|
|
15
17
|
def parsed_value
|
|
@@ -34,9 +36,27 @@ module LatoCms
|
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def field_config
|
|
39
|
+
return nil if repeater_order?
|
|
40
|
+
|
|
37
41
|
component = LatoCms::TemplateManager.find_component(component_id)
|
|
38
42
|
return nil unless component
|
|
39
|
-
component.dig('fields',
|
|
43
|
+
component.dig('fields', base_field_id)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def repeater_order?
|
|
47
|
+
field_id == REPEATER_ORDER_FIELD_ID
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def repeater_item_id
|
|
51
|
+
return nil unless field_id.to_s.include?('.')
|
|
52
|
+
|
|
53
|
+
field_id.to_s.split('.', 2).first
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def base_field_id
|
|
57
|
+
return field_id unless repeater_item_id
|
|
58
|
+
|
|
59
|
+
field_id.to_s.split('.', 2).last
|
|
40
60
|
end
|
|
41
61
|
|
|
42
62
|
def field_type
|
|
@@ -58,7 +78,7 @@ module LatoCms
|
|
|
58
78
|
def as_json(_options = {})
|
|
59
79
|
result = {
|
|
60
80
|
id: id,
|
|
61
|
-
field_id:
|
|
81
|
+
field_id: base_field_id,
|
|
62
82
|
field_type: field_type,
|
|
63
83
|
field_name: field_name,
|
|
64
84
|
required: field_required?,
|
|
@@ -41,6 +41,8 @@ module LatoCms
|
|
|
41
41
|
component_id: tc_config['component_id'].to_s,
|
|
42
42
|
name: tc_config['name'].presence || component&.dig('name') || tc_config['component_id'].to_s.humanize,
|
|
43
43
|
required: tc_config['required'] == true,
|
|
44
|
+
repeater: tc_config['repeater'] == true || tc_config['repeatable'] == true,
|
|
45
|
+
settings: tc_config['settings'] || {},
|
|
44
46
|
component: component,
|
|
45
47
|
fields: component ? (component['fields'] || {}) : {}
|
|
46
48
|
}
|
|
@@ -54,16 +54,20 @@
|
|
|
54
54
|
<%= hidden_field_tag :template_component_id, tc[:template_component_id] %>
|
|
55
55
|
<%= hidden_field_tag :component_id, tc[:component_id] %>
|
|
56
56
|
|
|
57
|
-
<% tc[:
|
|
58
|
-
|
|
57
|
+
<% if tc[:repeater] %>
|
|
58
|
+
<%= render 'lato_cms/pages/repeater', tc: tc, component_fields: component_fields %>
|
|
59
|
+
<% else %>
|
|
60
|
+
<% tc[:fields].each do |field_id, field_config| %>
|
|
61
|
+
<% page_field = component_fields.find { |f| f.field_id == field_id } %>
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
<div class="mb-3">
|
|
64
|
+
<%= lato_cms_render_field(
|
|
65
|
+
field_id: field_id,
|
|
66
|
+
field_config: field_config,
|
|
67
|
+
page_field: page_field
|
|
68
|
+
) %>
|
|
69
|
+
</div>
|
|
70
|
+
<% end %>
|
|
67
71
|
<% end %>
|
|
68
72
|
|
|
69
73
|
<div class="d-flex justify-content-end align-items-center gap-3 mt-1">
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<% order_field = component_fields.find(&:repeater_order?) %>
|
|
2
|
+
<% saved_order = begin; order_field&.value.present? ? JSON.parse(order_field.value) : []; rescue JSON::ParserError; []; end %>
|
|
3
|
+
<% fields_by_item = component_fields.reject(&:repeater_order?).group_by(&:repeater_item_id) %>
|
|
4
|
+
<% item_ids = (saved_order.presence || fields_by_item.keys.compact) %>
|
|
5
|
+
<% item_ids = [SecureRandom.uuid] if item_ids.blank? && tc[:settings]['min'].to_i.positive? %>
|
|
6
|
+
|
|
7
|
+
<div data-controller="lato-cms-repeater">
|
|
8
|
+
<div data-lato-cms-repeater-target="items">
|
|
9
|
+
<% item_ids.each_with_index do |item_id, item_index| %>
|
|
10
|
+
<% item_fields = (fields_by_item[item_id] || []).index_by(&:base_field_id) %>
|
|
11
|
+
<%= render 'lato_cms/pages/repeater_item', tc: tc, item_id: item_id, item_index: item_index, item_fields: item_fields %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<template data-lato-cms-repeater-target="template">
|
|
16
|
+
<%= render 'lato_cms/pages/repeater_item', tc: tc, item_id: 'NEW_RECORD', item_index: 'NEW_INDEX', item_fields: {} %>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<button type="button" class="btn btn-sm btn-outline-primary" data-action="lato-cms-repeater#add">
|
|
20
|
+
<i class="bi bi-plus-lg me-1"></i><%= t('lato_cms.repeater_add_item') %>
|
|
21
|
+
</button>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div class="card mb-3" data-lato-cms-repeater-target="item" data-repeater-item-id="<%= item_id %>">
|
|
2
|
+
<input type="hidden" name="repeater_order[]" value="<%= item_id %>" data-lato-cms-repeater-target="orderInput">
|
|
3
|
+
|
|
4
|
+
<div class="card-header d-flex justify-content-between align-items-center py-2">
|
|
5
|
+
<strong class="small"><%= tc[:name] %> #<span data-lato-cms-repeater-target="position"><%= item_index.to_i + 1 %></span></strong>
|
|
6
|
+
<button type="button" class="btn btn-sm btn-outline-danger" data-action="lato-cms-repeater#remove">
|
|
7
|
+
<i class="bi bi-trash me-1"></i><%= t('lato_cms.repeater_remove_item') %>
|
|
8
|
+
</button>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="card-body pb-2">
|
|
12
|
+
<% tc[:fields].each do |field_id, field_config| %>
|
|
13
|
+
<% page_field = item_fields[field_id.to_s] %>
|
|
14
|
+
<% input_name_prefix = "repeater_items[#{item_id}][#{field_id}]" %>
|
|
15
|
+
<% dom_id_prefix = "repeater_items_#{item_id}_#{field_id}" %>
|
|
16
|
+
|
|
17
|
+
<div class="mb-3">
|
|
18
|
+
<%= lato_cms_render_field(
|
|
19
|
+
field_id: field_id,
|
|
20
|
+
field_config: field_config,
|
|
21
|
+
page_field: page_field,
|
|
22
|
+
input_name_prefix: input_name_prefix,
|
|
23
|
+
dom_id_prefix: dom_id_prefix
|
|
24
|
+
) %>
|
|
25
|
+
</div>
|
|
26
|
+
<% end %>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<% label = field_config['name'] || field_id.humanize %>
|
|
2
2
|
<% current_value = page_field&.value %>
|
|
3
3
|
<% checked = current_value == 'true' %>
|
|
4
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
5
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
4
6
|
|
|
5
7
|
<div class="form-check form-switch">
|
|
6
|
-
<input type="hidden" name="
|
|
8
|
+
<input type="hidden" name="<%= input_name %>" value="false">
|
|
7
9
|
<input type="checkbox"
|
|
8
10
|
class="form-check-input"
|
|
9
|
-
name="
|
|
10
|
-
id="
|
|
11
|
+
name="<%= input_name %>"
|
|
12
|
+
id="<%= input_id %>"
|
|
11
13
|
value="true"
|
|
12
14
|
<%= 'checked' if checked %>>
|
|
13
|
-
<label class="form-check-label" for="
|
|
15
|
+
<label class="form-check-label" for="<%= input_id %>">
|
|
14
16
|
<%= label %>
|
|
15
17
|
</label>
|
|
16
18
|
</div>
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
<% label = field_config['name'] || field_id.humanize %>
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% current_value = page_field&.value.presence || '#000000' %>
|
|
4
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
5
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
4
6
|
|
|
5
|
-
<label class="form-label" for="
|
|
7
|
+
<label class="form-label" for="<%= input_id %>">
|
|
6
8
|
<%= label %><%= ' *' if required %>
|
|
7
9
|
</label>
|
|
8
10
|
<div class="d-flex align-items-center gap-2" data-controller="lato-cms-color-field">
|
|
9
11
|
<input type="color"
|
|
10
12
|
class="form-control form-control-color"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
value="<%= current_value %>"
|
|
14
16
|
data-lato-cms-color-field-target="input"
|
|
15
17
|
data-action="input->lato-cms-color-field#update"
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% current_value = page_field&.value || '' %>
|
|
5
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
6
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
5
7
|
|
|
6
|
-
<label class="form-label" for="
|
|
8
|
+
<label class="form-label" for="<%= input_id %>">
|
|
7
9
|
<%= label %><%= ' *' if required %>
|
|
8
10
|
</label>
|
|
9
11
|
<input type="date"
|
|
10
12
|
class="form-control"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
value="<%= current_value %>"
|
|
14
16
|
<%= 'required' if required %>
|
|
15
17
|
<% if settings['min'] %>min="<%= settings['min'] %>"<% end %>
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% current_value = page_field&.value || '' %>
|
|
5
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
6
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
5
7
|
|
|
6
|
-
<label class="form-label" for="
|
|
8
|
+
<label class="form-label" for="<%= input_id %>">
|
|
7
9
|
<%= label %><%= ' *' if required %>
|
|
8
10
|
</label>
|
|
9
11
|
<input type="datetime-local"
|
|
10
12
|
class="form-control"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
value="<%= current_value %>"
|
|
14
16
|
<%= 'required' if required %>
|
|
15
17
|
<% if settings['min'] %>min="<%= settings['min'] %>"<% end %>
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% multiple = settings['multiple'] != false %>
|
|
5
5
|
<% accept = settings['accept'] %>
|
|
6
|
+
<% files_input_name = lato_cms_field_input_name(field_id, 'files', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
7
|
+
<% remove_input_name = lato_cms_field_input_name(field_id, 'remove_file_ids', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
8
|
+
<% input_id = lato_cms_field_dom_id(field_id, 'files', dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
6
9
|
|
|
7
10
|
<label class="form-label">
|
|
8
11
|
<%= label %><%= ' *' if required %>
|
|
@@ -12,7 +15,7 @@
|
|
|
12
15
|
<div class="mb-2">
|
|
13
16
|
<% page_field.files.each do |file| %>
|
|
14
17
|
<div class="form-check mb-1 p-2 ps-4 bg-light rounded">
|
|
15
|
-
<input type="checkbox" class="form-check-input" name="
|
|
18
|
+
<input type="checkbox" class="form-check-input" name="<%= remove_input_name %>" value="<%= file.id %>" id="remove_file_<%= file.id %>">
|
|
16
19
|
<label class="form-check-label small" for="remove_file_<%= file.id %>">
|
|
17
20
|
<i class="bi bi-paperclip me-1"></i><%= file.blob.filename %> (<%= number_to_human_size(file.blob.byte_size) %>) — <span class="text-danger"><%= t('lato_cms.field_file_remove') %></span>
|
|
18
21
|
</label>
|
|
@@ -23,7 +26,7 @@
|
|
|
23
26
|
|
|
24
27
|
<input type="file"
|
|
25
28
|
class="form-control"
|
|
26
|
-
name="
|
|
27
|
-
id="
|
|
29
|
+
name="<%= files_input_name %>"
|
|
30
|
+
id="<%= input_id %>"
|
|
28
31
|
<%= 'multiple' if multiple %>
|
|
29
32
|
<% if accept %>accept="<%= accept %>"<% end %>>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% accept = settings['accept'] || 'image/*' %>
|
|
5
|
+
<% files_input_name = lato_cms_field_input_name(field_id, 'files', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
5
6
|
|
|
6
7
|
<%# Build ordered file list from value JSON or default order %>
|
|
7
8
|
<% ordered_files = begin
|
|
@@ -19,7 +20,7 @@ end %>
|
|
|
19
20
|
<%= label %><%= ' *' if required %>
|
|
20
21
|
</label>
|
|
21
22
|
|
|
22
|
-
<div data-controller="lato-cms-gallery-field" data-lato-cms-gallery-field-field-id-value="<%= field_id %>">
|
|
23
|
+
<div data-controller="lato-cms-gallery-field" data-lato-cms-gallery-field-field-id-value="<%= field_id %>" data-lato-cms-gallery-field-input-name-prefix-value="<%= local_assigns[:input_name_prefix].presence || "fields[#{field_id}]" %>">
|
|
23
24
|
<div class="lato-cms-gallery-field__grid mb-2"
|
|
24
25
|
data-lato-cms-gallery-field-target="grid"
|
|
25
26
|
data-action="dragover->lato-cms-gallery-field#onGridDragOver drop->lato-cms-gallery-field#onGridDrop">
|
|
@@ -45,7 +46,7 @@ end %>
|
|
|
45
46
|
<i class="bi bi-plus-lg me-1"></i><%= t('lato_cms.field_gallery_add_images') %>
|
|
46
47
|
<input type="file"
|
|
47
48
|
class="d-none"
|
|
48
|
-
name="
|
|
49
|
+
name="<%= files_input_name %>"
|
|
49
50
|
accept="<%= accept %>"
|
|
50
51
|
multiple
|
|
51
52
|
data-lato-cms-gallery-field-target="fileInput"
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% accept = settings['accept'] || 'image/*' %>
|
|
5
5
|
<% current_file = page_field&.files&.attached? ? page_field.files.first : nil %>
|
|
6
|
+
<% files_input_name = lato_cms_field_input_name(field_id, 'files', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
7
|
+
<% remove_input_name = lato_cms_field_input_name(field_id, 'remove_file_ids', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
8
|
+
<% input_id = lato_cms_field_dom_id(field_id, 'files', dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
6
9
|
|
|
7
10
|
<label class="form-label">
|
|
8
11
|
<%= label %><%= ' *' if required %>
|
|
@@ -14,7 +17,7 @@
|
|
|
14
17
|
<div class="position-relative d-inline-block">
|
|
15
18
|
<img src="<%= lato_cms_attachment_path(current_file) %>" class="img-thumbnail lato-cms-image-field__thumb" data-lato-cms-image-field-target="currentImage" alt="<%= current_file.filename %>">
|
|
16
19
|
<label class="lato-cms-image-field__remove-btn" title="<%= t('lato_cms.field_image_remove') %>">
|
|
17
|
-
<input type="checkbox" class="d-none" name="
|
|
20
|
+
<input type="checkbox" class="d-none" name="<%= remove_input_name %>" value="<%= current_file.id %>" data-lato-cms-image-field-target="removeCheck" data-action="change->lato-cms-image-field#toggleRemove">
|
|
18
21
|
<i class="bi bi-x-lg"></i>
|
|
19
22
|
</label>
|
|
20
23
|
</div>
|
|
@@ -30,8 +33,8 @@
|
|
|
30
33
|
|
|
31
34
|
<input type="file"
|
|
32
35
|
class="form-control"
|
|
33
|
-
name="
|
|
34
|
-
id="
|
|
36
|
+
name="<%= files_input_name %>"
|
|
37
|
+
id="<%= input_id %>"
|
|
35
38
|
accept="<%= accept %>"
|
|
36
39
|
data-lato-cms-image-field-target="input"
|
|
37
40
|
data-action="change->lato-cms-image-field#preview"
|
|
@@ -5,15 +5,17 @@
|
|
|
5
5
|
<% if current_value.present? %>
|
|
6
6
|
<% begin; current_value = JSON.pretty_generate(JSON.parse(current_value)); rescue JSON::ParserError; end %>
|
|
7
7
|
<% end %>
|
|
8
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
9
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
8
10
|
|
|
9
|
-
<label class="form-label" for="
|
|
11
|
+
<label class="form-label" for="<%= input_id %>">
|
|
10
12
|
<%= label %><%= ' *' if required %>
|
|
11
13
|
</label>
|
|
12
14
|
<div data-controller="lato-cms-json-field">
|
|
13
15
|
<textarea
|
|
14
16
|
class="form-control font-monospace"
|
|
15
|
-
name="
|
|
16
|
-
id="
|
|
17
|
+
name="<%= input_name %>"
|
|
18
|
+
id="<%= input_id %>"
|
|
17
19
|
rows="<%= settings['rows'] || 6 %>"
|
|
18
20
|
data-lato-cms-json-field-target="input"
|
|
19
21
|
data-action="input->lato-cms-json-field#validate"
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% options = settings['options'] || [] %>
|
|
5
5
|
<% current_values = begin; page_field&.value.present? ? JSON.parse(page_field.value) : []; rescue; []; end %>
|
|
6
|
+
<% input_name = lato_cms_field_input_name(field_id, 'value', input_name_prefix: local_assigns[:input_name_prefix], multiple: true) %>
|
|
7
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
6
8
|
|
|
7
|
-
<label class="form-label" for="
|
|
9
|
+
<label class="form-label" for="<%= input_id %>">
|
|
8
10
|
<%= label %><%= ' *' if required %>
|
|
9
11
|
</label>
|
|
10
12
|
<select
|
|
11
13
|
class="form-select"
|
|
12
|
-
name="
|
|
13
|
-
id="
|
|
14
|
+
name="<%= input_name %>"
|
|
15
|
+
id="<%= input_id %>"
|
|
14
16
|
multiple
|
|
15
17
|
size="<%= [options.length, 6].min %>"
|
|
16
18
|
<%= 'required' if required %>>
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% current_value = page_field&.value || '' %>
|
|
5
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
6
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
5
7
|
|
|
6
|
-
<label class="form-label" for="
|
|
8
|
+
<label class="form-label" for="<%= input_id %>">
|
|
7
9
|
<%= label %><%= ' *' if required %>
|
|
8
10
|
</label>
|
|
9
11
|
<input type="number"
|
|
10
12
|
class="form-control"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
value="<%= current_value %>"
|
|
14
16
|
<%= 'required' if required %>
|
|
15
17
|
<% if settings['min'] %>min="<%= settings['min'] %>"<% end %>
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% options = settings['options'] || [] %>
|
|
5
5
|
<% current_value = page_field&.value || '' %>
|
|
6
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
7
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
6
8
|
|
|
7
|
-
<label class="form-label" for="
|
|
9
|
+
<label class="form-label" for="<%= input_id %>">
|
|
8
10
|
<%= label %><%= ' *' if required %>
|
|
9
11
|
</label>
|
|
10
12
|
<select
|
|
11
13
|
class="form-select"
|
|
12
|
-
name="
|
|
13
|
-
id="
|
|
14
|
+
name="<%= input_name %>"
|
|
15
|
+
id="<%= input_id %>"
|
|
14
16
|
<%= 'required' if required %>>
|
|
15
17
|
<option value=""><%= t('lato_cms.field_select_placeholder') %></option>
|
|
16
18
|
<% options.each do |option| %>
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% current_value = page_field&.value || '' %>
|
|
5
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
6
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
5
7
|
|
|
6
|
-
<label class="form-label" for="
|
|
8
|
+
<label class="form-label" for="<%= input_id %>">
|
|
7
9
|
<%= label %><%= ' *' if required %>
|
|
8
10
|
</label>
|
|
9
11
|
<input type="text"
|
|
10
12
|
class="form-control"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
value="<%= current_value %>"
|
|
14
16
|
<%= 'required' if required %>
|
|
15
17
|
<% if settings['placeholder'] %>placeholder="<%= settings['placeholder'] %>"<% end %>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<% label = field_config['name'] || field_id.humanize %>
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% current_value = page_field&.value || '' %>
|
|
4
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
5
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
4
6
|
|
|
5
|
-
<label class="form-label" for="
|
|
7
|
+
<label class="form-label" for="<%= input_id %>">
|
|
6
8
|
<%= label %><%= ' *' if required %>
|
|
7
9
|
</label>
|
|
8
10
|
|
|
@@ -73,8 +75,8 @@
|
|
|
73
75
|
|
|
74
76
|
<%# ── Hidden input submitted with the form ───────────────────────────── %>
|
|
75
77
|
<input type="hidden"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
name="<%= input_name %>"
|
|
79
|
+
id="<%= input_id %>"
|
|
78
80
|
data-lato-cms-text-field-target="input"
|
|
79
81
|
value="<%= CGI.escapeHTML(current_value) %>">
|
|
80
82
|
</div>
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
<% required = field_config['required'] == true %>
|
|
3
3
|
<% settings = field_config['settings'] || {} %>
|
|
4
4
|
<% current_value = page_field&.value || '' %>
|
|
5
|
+
<% input_name = lato_cms_field_input_name(field_id, input_name_prefix: local_assigns[:input_name_prefix]) %>
|
|
6
|
+
<% input_id = lato_cms_field_dom_id(field_id, dom_id_prefix: local_assigns[:dom_id_prefix]) %>
|
|
5
7
|
|
|
6
|
-
<label class="form-label" for="
|
|
8
|
+
<label class="form-label" for="<%= input_id %>">
|
|
7
9
|
<%= label %><%= ' *' if required %>
|
|
8
10
|
</label>
|
|
9
11
|
<textarea
|
|
10
12
|
class="form-control"
|
|
11
|
-
name="
|
|
12
|
-
id="
|
|
13
|
+
name="<%= input_name %>"
|
|
14
|
+
id="<%= input_id %>"
|
|
13
15
|
rows="<%= settings['rows'] || 4 %>"
|
|
14
16
|
<%= 'required' if required %>
|
|
15
17
|
<% if settings['placeholder'] %>placeholder="<%= settings['placeholder'] %>"<% end %>
|
data/config/locales/en.yml
CHANGED
|
@@ -48,6 +48,8 @@ en:
|
|
|
48
48
|
component_required_cannot_disable: Required component cannot be disabled
|
|
49
49
|
component_disabled_cannot_save: Disabled component cannot be saved
|
|
50
50
|
fields_save_component: Save
|
|
51
|
+
repeater_add_item: Add item
|
|
52
|
+
repeater_remove_item: Remove
|
|
51
53
|
fields_component_missing_alert_html: "Component <strong>%{component_id}</strong> not found. The component configuration may have been removed."
|
|
52
54
|
fields_previously_saved_data: "Previously saved data:"
|
|
53
55
|
field_file_remove: Remove
|
data/config/locales/it.yml
CHANGED
|
@@ -48,6 +48,8 @@ it:
|
|
|
48
48
|
component_required_cannot_disable: Una componente obbligatoria non puo essere disattivata
|
|
49
49
|
component_disabled_cannot_save: Una componente disattivata non puo essere salvata
|
|
50
50
|
fields_save_component: Salva
|
|
51
|
+
repeater_add_item: Aggiungi elemento
|
|
52
|
+
repeater_remove_item: Rimuovi
|
|
51
53
|
fields_component_missing_alert_html: "Componente <strong>%{component_id}</strong> non trovato. La configurazione del componente potrebbe essere stata rimossa."
|
|
52
54
|
fields_previously_saved_data: "Dati salvati in precedenza:"
|
|
53
55
|
field_file_remove: Rimuovi
|
data/lib/lato_cms/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lato_cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gregorio Galante
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- app/assets/javascripts/lato_cms/controllers/lato_cms_image_field_controller.js
|
|
87
87
|
- app/assets/javascripts/lato_cms/controllers/lato_cms_json_field_controller.js
|
|
88
88
|
- app/assets/javascripts/lato_cms/controllers/lato_cms_page_preview_controller.js
|
|
89
|
+
- app/assets/javascripts/lato_cms/controllers/lato_cms_repeater_controller.js
|
|
89
90
|
- app/assets/javascripts/lato_cms/controllers/lato_cms_text_field_controller.js
|
|
90
91
|
- app/assets/stylesheets/lato_cms/application.scss
|
|
91
92
|
- app/controllers/lato_cms/api/pages_controller.rb
|
|
@@ -102,6 +103,8 @@ files:
|
|
|
102
103
|
- app/views/lato_cms/pages/_fields_editor.html.erb
|
|
103
104
|
- app/views/lato_cms/pages/_form_create.html.erb
|
|
104
105
|
- app/views/lato_cms/pages/_form_update.html.erb
|
|
106
|
+
- app/views/lato_cms/pages/_repeater.html.erb
|
|
107
|
+
- app/views/lato_cms/pages/_repeater_item.html.erb
|
|
105
108
|
- app/views/lato_cms/pages/create.html.erb
|
|
106
109
|
- app/views/lato_cms/pages/fields/_boolean.html.erb
|
|
107
110
|
- app/views/lato_cms/pages/fields/_color.html.erb
|