lato_cms 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/lato_cms/controllers/lato_cms_file_field_controller.js +4 -4
- data/app/assets/javascripts/lato_cms/controllers/lato_cms_gallery_field_controller.js +6 -2
- data/app/assets/javascripts/lato_cms/controllers/lato_cms_image_field_controller.js +5 -5
- data/app/assets/stylesheets/lato_cms/application.scss +25 -37
- data/app/models/lato_cms/page_field.rb +39 -4
- data/app/views/lato_cms/pages/fields/_file.html.erb +2 -2
- data/app/views/lato_cms/pages/fields/_gallery.html.erb +3 -3
- data/app/views/lato_cms/pages/fields/_image.html.erb +5 -5
- data/lib/lato_cms/version.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 319316314172ac5393d5d560741b331e00a8570fe476090f607cf3c583addce4
|
|
4
|
+
data.tar.gz: c8566ef62e7af5280fd4627a376d79b1dabbef383eeb365d7f3720ad9b3d5dba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6be7fac9bc254c30c2302b9bdd8351c7e20809b0a1f39cfaad773c74d82ead10bd7db204816f02ca86809eb46f03afb98ecbe516e474ad93a7a7cc2e01b7c9c8
|
|
7
|
+
data.tar.gz: 139e9d97bacf5cb8eb36542674c84483c4296964359799440689fc604a0705449c0e48531ad286d961569a115cef5b5fbdb2d2fd0ca08441a5e33f01ea939f43
|
|
@@ -106,8 +106,8 @@ export default class extends Controller {
|
|
|
106
106
|
<span class="text-muted small">(${this.humanSize(file.size)})</span>
|
|
107
107
|
<span class="badge bg-success">${this.newBadgeLabel}</span>
|
|
108
108
|
</div>
|
|
109
|
-
<button type="button" class="
|
|
110
|
-
<i class="bi bi-trash
|
|
109
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="${this.removeLabel}" aria-label="${this.removeLabel}" data-action="lato-cms-file-field#remove">
|
|
110
|
+
<i class="bi bi-trash"></i>
|
|
111
111
|
</button>
|
|
112
112
|
`
|
|
113
113
|
return item
|
|
@@ -150,8 +150,8 @@ export default class extends Controller {
|
|
|
150
150
|
<span>${this.escapeHtml(attachment.filename)}</span>
|
|
151
151
|
<span class="text-muted small">(${this.humanSize(attachment.byte_size || 0)})</span>
|
|
152
152
|
</div>
|
|
153
|
-
<button type="button" class="
|
|
154
|
-
<i class="bi bi-trash
|
|
153
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="${this.removeLabel}" aria-label="${this.removeLabel}" data-action="lato-cms-file-field#remove">
|
|
154
|
+
<i class="bi bi-trash"></i>
|
|
155
155
|
</button>
|
|
156
156
|
<div class="lato-cms-file-field__removed d-none" data-lato-cms-file-field-target="removedNotice">
|
|
157
157
|
<span class="text-danger small">
|
|
@@ -136,8 +136,8 @@ export default class extends Controller {
|
|
|
136
136
|
div.setAttribute('data-action', 'dragstart->lato-cms-gallery-field#onDragStart dragend->lato-cms-gallery-field#onDragEnd')
|
|
137
137
|
div.innerHTML = `
|
|
138
138
|
<img src="${src}" class="lato-cms-gallery-field__thumb" alt="">
|
|
139
|
-
<button type="button" class="lato-cms-gallery-field__remove" data-action="click->lato-cms-gallery-field#remove">
|
|
140
|
-
<i class="bi bi-
|
|
139
|
+
<button type="button" class="lato-cms-attachment-field__remove lato-cms-gallery-field__remove" title="${this.removeLabel}" aria-label="${this.removeLabel}" data-action="click->lato-cms-gallery-field#remove">
|
|
140
|
+
<i class="bi bi-trash"></i>
|
|
141
141
|
</button>
|
|
142
142
|
`
|
|
143
143
|
return div
|
|
@@ -165,4 +165,8 @@ export default class extends Controller {
|
|
|
165
165
|
return field.persisted_field_id === this.fieldIdValue || field.field_id === this.fieldIdValue
|
|
166
166
|
})
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
get removeLabel() {
|
|
170
|
+
return this.element.dataset.removeLabel || 'Remove'
|
|
171
|
+
}
|
|
168
172
|
}
|
|
@@ -42,7 +42,7 @@ export default class extends Controller {
|
|
|
42
42
|
remove() {
|
|
43
43
|
if (!this.hasCurrentContainerTarget) return
|
|
44
44
|
|
|
45
|
-
this.currentContainerTarget.classList.add('lato-cms-
|
|
45
|
+
this.currentContainerTarget.classList.add('lato-cms-file-field__item--removing')
|
|
46
46
|
this.removedNoticeTarget.classList.remove('d-none')
|
|
47
47
|
this.ensureRemoveInput()
|
|
48
48
|
}
|
|
@@ -50,7 +50,7 @@ export default class extends Controller {
|
|
|
50
50
|
undo() {
|
|
51
51
|
if (!this.hasCurrentContainerTarget) return
|
|
52
52
|
|
|
53
|
-
this.currentContainerTarget.classList.remove('lato-cms-
|
|
53
|
+
this.currentContainerTarget.classList.remove('lato-cms-file-field__item--removing')
|
|
54
54
|
this.removedNoticeTarget.classList.add('d-none')
|
|
55
55
|
this.removeInput?.remove()
|
|
56
56
|
this.removeInput = null
|
|
@@ -104,10 +104,10 @@ export default class extends Controller {
|
|
|
104
104
|
<span>${this.escapeHtml(attachment.filename)}</span>
|
|
105
105
|
<span class="text-muted small">(${this.humanSize(attachment.byte_size || 0)})</span>
|
|
106
106
|
</div>
|
|
107
|
-
<button type="button" class="
|
|
108
|
-
<i class="bi bi-trash
|
|
107
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="${this.removeLabel}" aria-label="${this.removeLabel}" data-action="lato-cms-image-field#remove">
|
|
108
|
+
<i class="bi bi-trash"></i>
|
|
109
109
|
</button>
|
|
110
|
-
<div class="lato-cms-
|
|
110
|
+
<div class="lato-cms-file-field__removed d-none" data-lato-cms-image-field-target="removedNotice">
|
|
111
111
|
<span class="text-danger small">
|
|
112
112
|
<i class="bi bi-trash me-1"></i>${this.removePendingLabel}
|
|
113
113
|
</span>
|
|
@@ -189,6 +189,28 @@ body.lato-cms-advanced-editor--open {
|
|
|
189
189
|
width: 100%;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
.lato-cms-attachment-field__remove {
|
|
193
|
+
align-items: center;
|
|
194
|
+
align-self: center;
|
|
195
|
+
background: #f8d7da;
|
|
196
|
+
border: 0;
|
|
197
|
+
border-radius: 50%;
|
|
198
|
+
color: var(--bs-danger);
|
|
199
|
+
display: inline-flex;
|
|
200
|
+
flex: 0 0 auto;
|
|
201
|
+
height: 32px;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
padding: 0;
|
|
204
|
+
transition: background 0.15s, color 0.15s;
|
|
205
|
+
width: 32px;
|
|
206
|
+
|
|
207
|
+
&:hover,
|
|
208
|
+
&:focus {
|
|
209
|
+
background: #f1aeb5;
|
|
210
|
+
color: var(--bs-danger);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
192
214
|
.lato-cms-file-field__item--removing {
|
|
193
215
|
background: rgba(220, 53, 69, 0.06);
|
|
194
216
|
border-color: rgba(220, 53, 69, 0.35);
|
|
@@ -196,6 +218,7 @@ body.lato-cms-advanced-editor--open {
|
|
|
196
218
|
|
|
197
219
|
.lato-cms-file-field__info,
|
|
198
220
|
.lato-cms-image-field__preview,
|
|
221
|
+
.lato-cms-attachment-field__remove,
|
|
199
222
|
> .btn {
|
|
200
223
|
display: none;
|
|
201
224
|
}
|
|
@@ -259,23 +282,6 @@ body.lato-cms-advanced-editor--open {
|
|
|
259
282
|
}
|
|
260
283
|
}
|
|
261
284
|
|
|
262
|
-
.lato-cms-image-field__removed {
|
|
263
|
-
align-items: center;
|
|
264
|
-
display: flex;
|
|
265
|
-
gap: 0.75rem;
|
|
266
|
-
justify-content: space-between;
|
|
267
|
-
width: 100%;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
.lato-cms-image-field--removing {
|
|
271
|
-
.lato-cms-image-field__preview,
|
|
272
|
-
.lato-cms-file-field__info,
|
|
273
|
-
.lato-cms-image-field__remove-btn,
|
|
274
|
-
> .btn {
|
|
275
|
-
display: none;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
285
|
.lato-cms-image-field__new-badge {
|
|
280
286
|
position: absolute;
|
|
281
287
|
bottom: 4px;
|
|
@@ -318,26 +324,8 @@ body.lato-cms-advanced-editor--open {
|
|
|
318
324
|
|
|
319
325
|
.lato-cms-gallery-field__remove {
|
|
320
326
|
position: absolute;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
width: 20px;
|
|
324
|
-
height: 20px;
|
|
325
|
-
border-radius: 50%;
|
|
326
|
-
border: none;
|
|
327
|
-
background: rgba(220, 53, 69, 0.85);
|
|
328
|
-
color: #fff;
|
|
329
|
-
display: flex;
|
|
330
|
-
align-items: center;
|
|
331
|
-
justify-content: center;
|
|
332
|
-
font-size: 9px;
|
|
333
|
-
padding: 0;
|
|
334
|
-
cursor: pointer;
|
|
335
|
-
line-height: 1;
|
|
336
|
-
transition: background 0.15s;
|
|
337
|
-
|
|
338
|
-
&:hover {
|
|
339
|
-
background: rgb(220, 53, 69);
|
|
340
|
-
}
|
|
327
|
+
right: 4px;
|
|
328
|
+
top: 4px;
|
|
341
329
|
}
|
|
342
330
|
|
|
343
331
|
.controller-pages-show {
|
|
@@ -92,12 +92,12 @@ module LatoCms
|
|
|
92
92
|
result[:attachments] = files.map { |f| attachment_as_json(f) }
|
|
93
93
|
when 'image'
|
|
94
94
|
attached = files.first
|
|
95
|
-
result[:attachments] = attached ? [attachment_as_json(attached)] : []
|
|
95
|
+
result[:attachments] = attached ? [attachment_as_json(attached, with_variants: true)] : []
|
|
96
96
|
when 'gallery'
|
|
97
97
|
order = value ? (JSON.parse(value) rescue []) : []
|
|
98
98
|
all_files = files.to_a
|
|
99
99
|
ordered = order.any? ? all_files.sort_by { |f| order.index(f.id.to_s) || Float::INFINITY } : all_files
|
|
100
|
-
result[:attachments] = ordered.map { |f| attachment_as_json(f) }
|
|
100
|
+
result[:attachments] = ordered.map { |f| attachment_as_json(f, with_variants: true) }
|
|
101
101
|
else
|
|
102
102
|
result[:value] = parsed_value
|
|
103
103
|
end
|
|
@@ -107,14 +107,49 @@ module LatoCms
|
|
|
107
107
|
|
|
108
108
|
private
|
|
109
109
|
|
|
110
|
-
def attachment_as_json(attachment)
|
|
111
|
-
{
|
|
110
|
+
def attachment_as_json(attachment, with_variants: false)
|
|
111
|
+
json = {
|
|
112
112
|
id: attachment.id,
|
|
113
113
|
filename: attachment.filename.to_s,
|
|
114
114
|
content_type: attachment.content_type,
|
|
115
115
|
byte_size: attachment.byte_size,
|
|
116
116
|
url: Rails.application.routes.url_helpers.rails_blob_path(attachment, only_path: true)
|
|
117
117
|
}
|
|
118
|
+
json[:sizes] = attachment_variant_urls(attachment) if with_variants
|
|
119
|
+
json
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Builds a map of { size_name => variant_url } from the field's `settings.sizes`.
|
|
123
|
+
# Variants are processed lazily by Active Storage on first request to their URL.
|
|
124
|
+
def attachment_variant_urls(attachment)
|
|
125
|
+
sizes = field_settings['sizes']
|
|
126
|
+
return {} if sizes.blank? || !sizes.respond_to?(:each_pair) || !attachment.variable?
|
|
127
|
+
|
|
128
|
+
url_helpers = Rails.application.routes.url_helpers
|
|
129
|
+
sizes.each_with_object({}) do |(name, opts), acc|
|
|
130
|
+
transformation = variant_transformation(opts)
|
|
131
|
+
next if transformation.blank?
|
|
132
|
+
|
|
133
|
+
variant = attachment.variant(transformation)
|
|
134
|
+
acc[name] = url_helpers.rails_representation_path(variant, only_path: true)
|
|
135
|
+
end
|
|
136
|
+
rescue StandardError => e
|
|
137
|
+
Rails.logger.error("LatoCms: Failed to build image variants for attachment #{attachment.id}: #{e.message}")
|
|
138
|
+
{}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Maps a size config (width/height/resize) to an Active Storage variant transformation.
|
|
142
|
+
# resize modes: "limit" (default, scale down only), "fit" (scale to fit), "fill" (crop to exact size).
|
|
143
|
+
def variant_transformation(opts)
|
|
144
|
+
opts = {} unless opts.respond_to?(:[])
|
|
145
|
+
dimensions = [opts['width'] || opts[:width], opts['height'] || opts[:height]]
|
|
146
|
+
return nil if dimensions.compact.empty?
|
|
147
|
+
|
|
148
|
+
case (opts['resize'] || opts[:resize] || 'limit').to_s
|
|
149
|
+
when 'fill' then { resize_to_fill: dimensions }
|
|
150
|
+
when 'fit' then { resize_to_fit: dimensions }
|
|
151
|
+
else { resize_to_limit: dimensions }
|
|
152
|
+
end
|
|
118
153
|
end
|
|
119
154
|
|
|
120
155
|
def parse_value
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
<span><%= file.blob.filename %></span>
|
|
28
28
|
<span class="text-muted small">(<%= number_to_human_size(file.blob.byte_size) %>)</span>
|
|
29
29
|
</div>
|
|
30
|
-
<button type="button" class="
|
|
31
|
-
<i class="bi bi-trash
|
|
30
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="<%= t('lato_cms.field_file_remove') %>" aria-label="<%= t('lato_cms.field_file_remove') %>" data-action="lato-cms-file-field#remove">
|
|
31
|
+
<i class="bi bi-trash"></i>
|
|
32
32
|
</button>
|
|
33
33
|
<div class="lato-cms-file-field__removed d-none" data-lato-cms-file-field-target="removedNotice">
|
|
34
34
|
<span class="text-danger small">
|
|
@@ -20,7 +20,7 @@ end %>
|
|
|
20
20
|
<%= label %><%= ' *' if required %>
|
|
21
21
|
</label>
|
|
22
22
|
|
|
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
|
+
<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}]" %>" data-remove-label="<%= t('lato_cms.field_file_remove') %>">
|
|
24
24
|
<div class="lato-cms-gallery-field__grid mb-2"
|
|
25
25
|
data-lato-cms-gallery-field-target="grid"
|
|
26
26
|
data-action="dragover->lato-cms-gallery-field#onGridDragOver drop->lato-cms-gallery-field#onGridDrop">
|
|
@@ -31,8 +31,8 @@ end %>
|
|
|
31
31
|
draggable="true"
|
|
32
32
|
data-action="dragstart->lato-cms-gallery-field#onDragStart dragend->lato-cms-gallery-field#onDragEnd">
|
|
33
33
|
<img src="<%= lato_cms_attachment_path(file) %>" class="lato-cms-gallery-field__thumb" alt="<%= file.filename %>">
|
|
34
|
-
<button type="button" class="lato-cms-gallery-field__remove" data-action="click->lato-cms-gallery-field#remove">
|
|
35
|
-
<i class="bi bi-
|
|
34
|
+
<button type="button" class="lato-cms-attachment-field__remove lato-cms-gallery-field__remove" title="<%= t('lato_cms.field_file_remove') %>" aria-label="<%= t('lato_cms.field_file_remove') %>" data-action="click->lato-cms-gallery-field#remove">
|
|
35
|
+
<i class="bi bi-trash"></i>
|
|
36
36
|
</button>
|
|
37
37
|
</div>
|
|
38
38
|
<% end %>
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
<span><%= current_file.blob.filename %></span>
|
|
28
28
|
<span class="text-muted small">(<%= number_to_human_size(current_file.blob.byte_size) %>)</span>
|
|
29
29
|
</div>
|
|
30
|
-
<button type="button" class="
|
|
31
|
-
<i class="bi bi-trash
|
|
30
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="<%= t('lato_cms.field_image_remove') %>" aria-label="<%= t('lato_cms.field_image_remove') %>" data-action="lato-cms-image-field#remove">
|
|
31
|
+
<i class="bi bi-trash"></i>
|
|
32
32
|
</button>
|
|
33
|
-
<div class="lato-cms-
|
|
33
|
+
<div class="lato-cms-file-field__removed d-none" data-lato-cms-image-field-target="removedNotice">
|
|
34
34
|
<span class="text-danger small">
|
|
35
35
|
<i class="bi bi-trash me-1"></i><%= t('lato_cms.field_image_remove_pending') %>
|
|
36
36
|
</span>
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
<span class="text-muted small" data-lato-cms-image-field-target="newPreviewSize"></span>
|
|
52
52
|
<span class="badge bg-success"><%= t('lato_cms.field_image_new_badge') %></span>
|
|
53
53
|
</div>
|
|
54
|
-
<button type="button" class="
|
|
55
|
-
<i class="bi bi-trash
|
|
54
|
+
<button type="button" class="lato-cms-attachment-field__remove" title="<%= t('lato_cms.field_image_remove') %>" aria-label="<%= t('lato_cms.field_image_remove') %>" data-action="lato-cms-image-field#removeNew">
|
|
55
|
+
<i class="bi bi-trash"></i>
|
|
56
56
|
</button>
|
|
57
57
|
</div>
|
|
58
58
|
|
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.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gregorio Galante
|
|
@@ -65,6 +65,20 @@ dependencies:
|
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: image_processing
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '1.2'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '1.2'
|
|
68
82
|
description: A Rails engine to manage application users on Lato projects!
|
|
69
83
|
email:
|
|
70
84
|
- me@gregoriogalante.com
|