lato 3.19.5 → 3.19.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/app/assets/javascripts/lato/controllers/lato_input_signature_controller.js +210 -0
- data/app/helpers/lato/components_helper.rb +4 -0
- data/app/views/lato/components/_form_item_input_signature.html.erb +112 -0
- data/app/views/layouts/lato/_head_content.html.erb +23 -2
- data/config/locales/en.yml +8 -0
- data/config/locales/fr.yml +8 -0
- data/config/locales/it.yml +8 -0
- data/config/locales/ro.yml +8 -0
- data/lib/lato/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ddcd8ca090462fcc1ce80afc270605f0f777d879c6408a0a62a3abfd4f45245
|
|
4
|
+
data.tar.gz: 30241f1b60707214faf19fbda81bf98244c87a94298a0b975c5c982f49f68db9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1ad908430ec114c1c8ef4793bc018c0533c2742fc3f8e24f1dbd4cb7ebca3cd6437062b1cd75bd4207945d13e31d709b699c9dca9ccb36c73cbbd2c8f778f40
|
|
7
|
+
data.tar.gz: 62410dee533b4f52c0c0cec2e1a43a66dca86eec5b30de4181a582ba6fda55b40fd655b25571c3ab9b3a3d6d15e917ba78f3ef4a76b59fac883b6809de9e7ddc
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static targets = ["canvas", "fileInput", "uploadInput", "preview", "drawPanel", "uploadPanel", "drawTab", "uploadTab", "currentTab", "currentPanel", "clearRow"]
|
|
5
|
+
static values = {
|
|
6
|
+
existingUrl: String,
|
|
7
|
+
defaultTab: String
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
connect() {
|
|
11
|
+
this.isDrawing = false
|
|
12
|
+
this.hasDrawing = false
|
|
13
|
+
this.activeTab = this.defaultTabValue || 'draw'
|
|
14
|
+
this._submitting = false
|
|
15
|
+
|
|
16
|
+
if (this.hasCanvasTarget) {
|
|
17
|
+
this._setupCanvas()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Nascondi il pulsante clear se si parte sulla tab current
|
|
21
|
+
this._updateClearRow()
|
|
22
|
+
|
|
23
|
+
this._form = this.element.closest('form')
|
|
24
|
+
if (this._form) {
|
|
25
|
+
this._boundSubmit = this.onFormSubmit.bind(this)
|
|
26
|
+
this._form.addEventListener('submit', this._boundSubmit)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
disconnect() {
|
|
31
|
+
if (this._form && this._boundSubmit) {
|
|
32
|
+
this._form.removeEventListener('submit', this._boundSubmit)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
_setupCanvas() {
|
|
37
|
+
const canvas = this.canvasTarget
|
|
38
|
+
// Use fixed internal resolution; CSS handles display size
|
|
39
|
+
canvas.width = 800
|
|
40
|
+
canvas.height = 200
|
|
41
|
+
|
|
42
|
+
const ctx = canvas.getContext('2d')
|
|
43
|
+
ctx.strokeStyle = '#1a1a1a'
|
|
44
|
+
ctx.lineWidth = 2.5
|
|
45
|
+
ctx.lineCap = 'round'
|
|
46
|
+
ctx.lineJoin = 'round'
|
|
47
|
+
this._ctx = ctx
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_getPos(clientX, clientY) {
|
|
51
|
+
const canvas = this.canvasTarget
|
|
52
|
+
const rect = canvas.getBoundingClientRect()
|
|
53
|
+
const scaleX = canvas.width / rect.width
|
|
54
|
+
const scaleY = canvas.height / rect.height
|
|
55
|
+
return {
|
|
56
|
+
x: (clientX - rect.left) * scaleX,
|
|
57
|
+
y: (clientY - rect.top) * scaleY
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
onMouseDown(e) {
|
|
62
|
+
if (this.activeTab !== 'draw') return
|
|
63
|
+
this.isDrawing = true
|
|
64
|
+
const pos = this._getPos(e.clientX, e.clientY)
|
|
65
|
+
this._ctx.beginPath()
|
|
66
|
+
this._ctx.moveTo(pos.x, pos.y)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
onMouseMove(e) {
|
|
70
|
+
if (!this.isDrawing) return
|
|
71
|
+
e.preventDefault()
|
|
72
|
+
const pos = this._getPos(e.clientX, e.clientY)
|
|
73
|
+
this._ctx.lineTo(pos.x, pos.y)
|
|
74
|
+
this._ctx.stroke()
|
|
75
|
+
this.hasDrawing = true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
onMouseUp() {
|
|
79
|
+
this.isDrawing = false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onMouseLeave() {
|
|
83
|
+
this.isDrawing = false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
onTouchStart(e) {
|
|
87
|
+
if (this.activeTab !== 'draw') return
|
|
88
|
+
e.preventDefault()
|
|
89
|
+
this.isDrawing = true
|
|
90
|
+
const touch = e.touches[0]
|
|
91
|
+
const pos = this._getPos(touch.clientX, touch.clientY)
|
|
92
|
+
this._ctx.beginPath()
|
|
93
|
+
this._ctx.moveTo(pos.x, pos.y)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
onTouchMove(e) {
|
|
97
|
+
if (!this.isDrawing) return
|
|
98
|
+
e.preventDefault()
|
|
99
|
+
const touch = e.touches[0]
|
|
100
|
+
const pos = this._getPos(touch.clientX, touch.clientY)
|
|
101
|
+
this._ctx.lineTo(pos.x, pos.y)
|
|
102
|
+
this._ctx.stroke()
|
|
103
|
+
this.hasDrawing = true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
onTouchEnd() {
|
|
107
|
+
this.isDrawing = false
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
switchToCurrentTab(e) {
|
|
111
|
+
e.preventDefault()
|
|
112
|
+
this.activeTab = 'current'
|
|
113
|
+
if (this.hasCurrentPanelTarget) this.currentPanelTarget.classList.remove('d-none')
|
|
114
|
+
this.drawPanelTarget.classList.add('d-none')
|
|
115
|
+
this.uploadPanelTarget.classList.add('d-none')
|
|
116
|
+
if (this.hasCurrentTabTarget) this.currentTabTarget.classList.add('active')
|
|
117
|
+
this.drawTabTarget.classList.remove('active')
|
|
118
|
+
this.uploadTabTarget.classList.remove('active')
|
|
119
|
+
// Nessun nuovo file: mantieni la firma esistente
|
|
120
|
+
this.fileInputTarget.value = ''
|
|
121
|
+
this._updateClearRow()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
switchToDrawTab(e) {
|
|
125
|
+
e.preventDefault()
|
|
126
|
+
this.activeTab = 'draw'
|
|
127
|
+
if (this.hasCurrentPanelTarget) this.currentPanelTarget.classList.add('d-none')
|
|
128
|
+
this.drawPanelTarget.classList.remove('d-none')
|
|
129
|
+
this.uploadPanelTarget.classList.add('d-none')
|
|
130
|
+
if (this.hasCurrentTabTarget) this.currentTabTarget.classList.remove('active')
|
|
131
|
+
this.drawTabTarget.classList.add('active')
|
|
132
|
+
this.uploadTabTarget.classList.remove('active')
|
|
133
|
+
this._updateClearRow()
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
switchToUploadTab(e) {
|
|
137
|
+
e.preventDefault()
|
|
138
|
+
this.activeTab = 'upload'
|
|
139
|
+
if (this.hasCurrentPanelTarget) this.currentPanelTarget.classList.add('d-none')
|
|
140
|
+
this.drawPanelTarget.classList.add('d-none')
|
|
141
|
+
this.uploadPanelTarget.classList.remove('d-none')
|
|
142
|
+
if (this.hasCurrentTabTarget) this.currentTabTarget.classList.remove('active')
|
|
143
|
+
this.drawTabTarget.classList.remove('active')
|
|
144
|
+
this.uploadTabTarget.classList.add('active')
|
|
145
|
+
this._updateClearRow()
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
_updateClearRow() {
|
|
149
|
+
if (!this.hasClearRowTarget) return
|
|
150
|
+
if (this.activeTab === 'current') {
|
|
151
|
+
this.clearRowTarget.classList.add('d-none')
|
|
152
|
+
} else {
|
|
153
|
+
this.clearRowTarget.classList.remove('d-none')
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
clearSignature(e) {
|
|
158
|
+
e.preventDefault()
|
|
159
|
+
if (this.activeTab === 'draw') {
|
|
160
|
+
this._ctx.clearRect(0, 0, this.canvasTarget.width, this.canvasTarget.height)
|
|
161
|
+
this.hasDrawing = false
|
|
162
|
+
} else {
|
|
163
|
+
this.uploadInputTarget.value = ''
|
|
164
|
+
this.previewTarget.src = ''
|
|
165
|
+
this.previewTarget.classList.add('d-none')
|
|
166
|
+
}
|
|
167
|
+
// Reset the hidden file input so the existing attachment is preserved (no new file)
|
|
168
|
+
this.fileInputTarget.value = ''
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
onUploadChange() {
|
|
172
|
+
const file = this.uploadInputTarget.files[0]
|
|
173
|
+
if (!file) return
|
|
174
|
+
|
|
175
|
+
const reader = new FileReader()
|
|
176
|
+
reader.onload = (ev) => {
|
|
177
|
+
this.previewTarget.src = ev.target.result
|
|
178
|
+
this.previewTarget.classList.remove('d-none')
|
|
179
|
+
}
|
|
180
|
+
reader.readAsDataURL(file)
|
|
181
|
+
|
|
182
|
+
// Copy the selected file to the real (hidden) input
|
|
183
|
+
const dt = new DataTransfer()
|
|
184
|
+
dt.items.add(file)
|
|
185
|
+
this.fileInputTarget.files = dt.files
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
onFormSubmit(e) {
|
|
189
|
+
// Se siamo sulla tab current, non toccare il file input (mantieni firma esistente)
|
|
190
|
+
if (this.activeTab === 'current') return
|
|
191
|
+
// Se siamo sulla tab upload, il file input è già popolato
|
|
192
|
+
if (this.activeTab === 'upload') return
|
|
193
|
+
// Tab draw: intercetta solo se l'utente ha disegnato qualcosa
|
|
194
|
+
if (this._submitting) return
|
|
195
|
+
if (!this.hasDrawing) return
|
|
196
|
+
|
|
197
|
+
e.preventDefault()
|
|
198
|
+
this._submitting = true
|
|
199
|
+
|
|
200
|
+
this.canvasTarget.toBlob((blob) => {
|
|
201
|
+
const file = new File([blob], 'signature.png', { type: 'image/png' })
|
|
202
|
+
const dt = new DataTransfer()
|
|
203
|
+
dt.items.add(file)
|
|
204
|
+
this.fileInputTarget.files = dt.files
|
|
205
|
+
this.hasDrawing = false
|
|
206
|
+
this._submitting = false
|
|
207
|
+
this._form.requestSubmit()
|
|
208
|
+
}, 'image/png')
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -244,6 +244,10 @@ module Lato
|
|
|
244
244
|
render 'lato/components/form_item_input_list', form: form, key: key, partial: partial, partial_params: partial_params
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
+
def lato_form_item_input_signature(form, key, options = {})
|
|
248
|
+
render 'lato/components/form_item_input_signature', form: form, key: key, options: options
|
|
249
|
+
end
|
|
250
|
+
|
|
247
251
|
def lato_form_submit(form, label, options = {})
|
|
248
252
|
options[:class] ||= []
|
|
249
253
|
options[:class].push('btn')
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<%
|
|
2
|
+
|
|
3
|
+
form ||= nil
|
|
4
|
+
key ||= nil
|
|
5
|
+
options ||= {}
|
|
6
|
+
|
|
7
|
+
existing_attachment = form.object.respond_to?(key) ? form.object.send(key) : nil
|
|
8
|
+
existing_url = (existing_attachment.respond_to?(:attached?) && existing_attachment.attached?) ? url_for(existing_attachment) : nil
|
|
9
|
+
|
|
10
|
+
has_error = form.object && form.object.errors[key] && form.object.errors[key].any?
|
|
11
|
+
container_classes = ['lato-input-signature', 'border', 'rounded', 'p-3']
|
|
12
|
+
container_classes << 'border-danger' if has_error
|
|
13
|
+
|
|
14
|
+
# Se esiste una firma, la tab attiva di default è 'current', altrimenti 'draw'
|
|
15
|
+
default_tab = existing_url ? 'current' : 'draw'
|
|
16
|
+
|
|
17
|
+
%>
|
|
18
|
+
|
|
19
|
+
<div class="<%= container_classes.join(' ') %>"
|
|
20
|
+
data-controller="lato-input-signature"
|
|
21
|
+
data-lato-input-signature-default-tab-value="<%= default_tab %>"
|
|
22
|
+
<% if existing_url %>data-lato-input-signature-existing-url-value="<%= existing_url %>"<% end %>>
|
|
23
|
+
|
|
24
|
+
<%# Hidden file input – submitted with the form %>
|
|
25
|
+
<%= form.file_field key, class: 'd-none', data: { 'lato_input_signature_target': 'fileInput' }, accept: 'image/png,image/jpeg' %>
|
|
26
|
+
|
|
27
|
+
<%# Tab navigation %>
|
|
28
|
+
<ul class="nav nav-tabs mb-2" style="font-size: 0.8rem;">
|
|
29
|
+
<% if existing_url %>
|
|
30
|
+
<li class="nav-item">
|
|
31
|
+
<a href="#" class="nav-link py-1 px-2 <%= 'active' if default_tab == 'current' %>"
|
|
32
|
+
data-lato-input-signature-target="currentTab"
|
|
33
|
+
data-action="click->lato-input-signature#switchToCurrentTab">
|
|
34
|
+
<i class="bi bi-image"></i> <%= I18n.t('lato.signature_current') %>
|
|
35
|
+
</a>
|
|
36
|
+
</li>
|
|
37
|
+
<% end %>
|
|
38
|
+
<li class="nav-item">
|
|
39
|
+
<a href="#" class="nav-link py-1 px-2 <%= 'active' if default_tab == 'draw' %>"
|
|
40
|
+
data-lato-input-signature-target="drawTab"
|
|
41
|
+
data-action="click->lato-input-signature#switchToDrawTab">
|
|
42
|
+
<i class="bi bi-pen"></i> <%= I18n.t('lato.signature_draw') %>
|
|
43
|
+
</a>
|
|
44
|
+
</li>
|
|
45
|
+
<li class="nav-item">
|
|
46
|
+
<a href="#" class="nav-link py-1 px-2"
|
|
47
|
+
data-lato-input-signature-target="uploadTab"
|
|
48
|
+
data-action="click->lato-input-signature#switchToUploadTab">
|
|
49
|
+
<i class="bi bi-upload"></i> <%= I18n.t('lato.signature_upload') %>
|
|
50
|
+
</a>
|
|
51
|
+
</li>
|
|
52
|
+
</ul>
|
|
53
|
+
|
|
54
|
+
<%# Current signature panel (solo se esiste) %>
|
|
55
|
+
<% if existing_url %>
|
|
56
|
+
<div data-lato-input-signature-target="currentPanel">
|
|
57
|
+
<img src="<%= existing_url %>"
|
|
58
|
+
class="border rounded"
|
|
59
|
+
style="max-height: 120px; max-width: 100%; object-fit: contain; display: block;"
|
|
60
|
+
alt="<%= I18n.t('lato.signature_current') %>">
|
|
61
|
+
</div>
|
|
62
|
+
<% end %>
|
|
63
|
+
|
|
64
|
+
<%# Draw panel %>
|
|
65
|
+
<div class="<%= existing_url ? 'd-none' : '' %>" data-lato-input-signature-target="drawPanel">
|
|
66
|
+
<canvas class="border rounded w-100 bg-white"
|
|
67
|
+
style="height: 140px; cursor: crosshair; touch-action: none; display: block;"
|
|
68
|
+
data-lato-input-signature-target="canvas"
|
|
69
|
+
data-action="mousedown->lato-input-signature#onMouseDown
|
|
70
|
+
mousemove->lato-input-signature#onMouseMove
|
|
71
|
+
mouseup->lato-input-signature#onMouseUp
|
|
72
|
+
mouseleave->lato-input-signature#onMouseLeave
|
|
73
|
+
touchstart->lato-input-signature#onTouchStart
|
|
74
|
+
touchmove->lato-input-signature#onTouchMove
|
|
75
|
+
touchend->lato-input-signature#onTouchEnd">
|
|
76
|
+
</canvas>
|
|
77
|
+
<div class="text-muted mt-1" style="font-size: 0.75rem;">
|
|
78
|
+
<i class="bi bi-info-circle"></i> <%= I18n.t('lato.signature_draw_help') %>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<%# Upload panel %>
|
|
83
|
+
<div class="d-none" data-lato-input-signature-target="uploadPanel">
|
|
84
|
+
<input type="file"
|
|
85
|
+
accept="image/png,image/jpeg"
|
|
86
|
+
class="form-control form-control-sm"
|
|
87
|
+
data-lato-input-signature-target="uploadInput"
|
|
88
|
+
data-action="change->lato-input-signature#onUploadChange">
|
|
89
|
+
<img class="mt-2 border rounded d-none"
|
|
90
|
+
style="max-height: 120px; max-width: 100%; object-fit: contain;"
|
|
91
|
+
data-lato-input-signature-target="preview"
|
|
92
|
+
alt="<%= I18n.t('lato.signature_preview_alt') %>">
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<%# Validation error %>
|
|
96
|
+
<% if has_error %>
|
|
97
|
+
<div class="invalid-feedback d-block mt-1">
|
|
98
|
+
<%= form.object.errors[key].first %>
|
|
99
|
+
</div>
|
|
100
|
+
<% end %>
|
|
101
|
+
|
|
102
|
+
<%# Clear button (solo nelle tab di editing) %>
|
|
103
|
+
<div class="d-flex justify-content-end mt-2" data-lato-input-signature-target="clearRow">
|
|
104
|
+
<button type="button"
|
|
105
|
+
class="btn btn-outline-secondary btn-sm"
|
|
106
|
+
style="font-size: 0.75rem;"
|
|
107
|
+
data-action="click->lato-input-signature#clearSignature">
|
|
108
|
+
<i class="bi bi-eraser"></i> <%= I18n.t('lato.signature_clear') %>
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
</div>
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<link rel="canonical" href="<%= request.original_url %>">
|
|
2
|
+
|
|
3
|
+
<!-- PWA Support -->
|
|
1
4
|
<meta name="application-name" content="<%= Lato.config.application_title %>">
|
|
2
5
|
<meta name="theme-color" content="<%= Lato.config.application_brand_color %>">
|
|
3
6
|
<meta name="full-screen" content="yes">
|
|
@@ -6,8 +9,26 @@
|
|
|
6
9
|
<meta name="mobile-web-app-capable" content="yes">
|
|
7
10
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
8
11
|
<meta name="apple-mobile-web-app-title" content="<%= Lato.config.application_title %>">
|
|
9
|
-
|
|
10
12
|
<link rel="icon" href="/favicon.ico">
|
|
11
13
|
<link rel="manifest" href="/manifest.json">
|
|
12
14
|
|
|
13
|
-
<!--
|
|
15
|
+
<!-- Standard Metadata -->
|
|
16
|
+
<%# <meta name="description" content=""> %>
|
|
17
|
+
<%# <meta name="keywords" content=""> %>
|
|
18
|
+
<%# <meta name="author" content=""> %>
|
|
19
|
+
|
|
20
|
+
<!-- OG Tags -->
|
|
21
|
+
<meta property="og:title" content="<%= @layout_page_title || Lato.config.application_title %>">
|
|
22
|
+
<meta property="og:site_name" content="<%= Lato.config.application_title %>">
|
|
23
|
+
<meta property="og:type" content="website">
|
|
24
|
+
<meta property="og:url" content="<%= request.original_url %>">
|
|
25
|
+
<%# <meta property="og:description" content=""> %>
|
|
26
|
+
<%# <meta property="og:image" content=""> %>
|
|
27
|
+
|
|
28
|
+
<!-- Twitter Card Tags -->
|
|
29
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
30
|
+
<meta name="twitter:title" content="<%= @layout_page_title || Lato.config.application_title %>">
|
|
31
|
+
<%# <meta name="twitter:description" content=""> %>
|
|
32
|
+
<%# <meta name="twitter:image" content=""> %>
|
|
33
|
+
|
|
34
|
+
<%# Free for head tags %>
|
data/config/locales/en.yml
CHANGED
|
@@ -93,6 +93,14 @@ en:
|
|
|
93
93
|
dropzone_drag_and_drop_or_click: Drag and drop files here or click to upload
|
|
94
94
|
add_item: Add item
|
|
95
95
|
remove_item: Remove item
|
|
96
|
+
signature_draw: Draw
|
|
97
|
+
signature_upload: Upload image
|
|
98
|
+
signature_draw_help: Draw your signature in the space above
|
|
99
|
+
signature_clear: Clear
|
|
100
|
+
signature_current: Current signature
|
|
101
|
+
signature_preview_alt: Signature preview
|
|
102
|
+
signature_edit: Edit
|
|
103
|
+
signature_cancel_edit: Cancel edit
|
|
96
104
|
|
|
97
105
|
invitation_mailer:
|
|
98
106
|
invite_mail_subject: You received an invitation
|
data/config/locales/fr.yml
CHANGED
|
@@ -93,6 +93,14 @@ fr:
|
|
|
93
93
|
operation_failed_title: Échec de l'opération
|
|
94
94
|
operation_failed_subtitle: Une erreur s'est produite lors de l'opération
|
|
95
95
|
dropzone_drag_and_drop_or_click: Faites glisser et déposez les fichiers ici ou cliquez pour télécharger
|
|
96
|
+
signature_draw: Dessiner
|
|
97
|
+
signature_upload: Télécharger une image
|
|
98
|
+
signature_draw_help: Dessinez votre signature dans l'espace ci-dessus
|
|
99
|
+
signature_clear: Effacer
|
|
100
|
+
signature_current: Signature actuelle
|
|
101
|
+
signature_preview_alt: Aperçu de la signature
|
|
102
|
+
signature_edit: Modifier
|
|
103
|
+
signature_cancel_edit: Annuler la modification
|
|
96
104
|
add_item: Ajouter un élément
|
|
97
105
|
remove_item: Supprimer un élément
|
|
98
106
|
|
data/config/locales/it.yml
CHANGED
|
@@ -95,6 +95,14 @@ it:
|
|
|
95
95
|
dropzone_drag_and_drop_or_click: Trascina qui i file o clicca per caricare
|
|
96
96
|
add_item: Aggiungi elemento
|
|
97
97
|
remove_item: Rimuovi elemento
|
|
98
|
+
signature_draw: Disegna
|
|
99
|
+
signature_upload: Carica immagine
|
|
100
|
+
signature_draw_help: Disegna la tua firma nello spazio sopra
|
|
101
|
+
signature_clear: Cancella
|
|
102
|
+
signature_current: Firma attuale
|
|
103
|
+
signature_preview_alt: Anteprima firma
|
|
104
|
+
signature_edit: Modifica
|
|
105
|
+
signature_cancel_edit: Annulla modifica
|
|
98
106
|
|
|
99
107
|
invitation_mailer:
|
|
100
108
|
invite_mail_subject: Hai ricevuto un invito
|
data/config/locales/ro.yml
CHANGED
|
@@ -93,6 +93,14 @@ ro:
|
|
|
93
93
|
operation_failed_title: Operație eșuată
|
|
94
94
|
operation_failed_subtitle: A apărut o eroare în timpul operației
|
|
95
95
|
dropzone_drag_and_drop_or_click: Trage și plasează fișiere aici sau fă clic pentru a le încărca
|
|
96
|
+
signature_draw: Desenează
|
|
97
|
+
signature_upload: Încarcă imagine
|
|
98
|
+
signature_draw_help: Desenează semnătura ta în spațiul de mai sus
|
|
99
|
+
signature_clear: Șterge
|
|
100
|
+
signature_current: Semnătura actuală
|
|
101
|
+
signature_preview_alt: Previzualizare semnătură
|
|
102
|
+
signature_edit: Editează
|
|
103
|
+
signature_cancel_edit: Anulează modificarea
|
|
96
104
|
add_item: Adaugă un element
|
|
97
105
|
remove_item: Elimină un element
|
|
98
106
|
|
data/lib/lato/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lato
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.19.
|
|
4
|
+
version: 3.19.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gregorio Galante
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -184,6 +183,7 @@ files:
|
|
|
184
183
|
- app/assets/javascripts/lato/controllers/lato_input_autocomplete_controller.js
|
|
185
184
|
- app/assets/javascripts/lato/controllers/lato_input_dropzone_controller.js
|
|
186
185
|
- app/assets/javascripts/lato/controllers/lato_input_list_controller.js
|
|
186
|
+
- app/assets/javascripts/lato/controllers/lato_input_signature_controller.js
|
|
187
187
|
- app/assets/javascripts/lato/controllers/lato_network_controller.js
|
|
188
188
|
- app/assets/javascripts/lato/controllers/lato_operation_controller.js
|
|
189
189
|
- app/assets/javascripts/lato/controllers/lato_tooltip_controller.js
|
|
@@ -247,6 +247,7 @@ files:
|
|
|
247
247
|
- app/views/lato/authentication/webauthn.html.erb
|
|
248
248
|
- app/views/lato/components/_form_item_input_file_dropzone.html.erb
|
|
249
249
|
- app/views/lato/components/_form_item_input_list.html.erb
|
|
250
|
+
- app/views/lato/components/_form_item_input_signature.html.erb
|
|
250
251
|
- app/views/lato/components/_index.html.erb
|
|
251
252
|
- app/views/lato/components/_navbar_nav_item.html.erb
|
|
252
253
|
- app/views/lato/components/_navbar_nav_locales_item.html.erb
|
|
@@ -310,7 +311,6 @@ licenses:
|
|
|
310
311
|
metadata:
|
|
311
312
|
homepage_uri: https://github.com/Lato-org/lato
|
|
312
313
|
source_code_uri: https://github.com/Lato-org/lato
|
|
313
|
-
post_install_message:
|
|
314
314
|
rdoc_options: []
|
|
315
315
|
require_paths:
|
|
316
316
|
- lib
|
|
@@ -325,8 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
325
325
|
- !ruby/object:Gem::Version
|
|
326
326
|
version: '0'
|
|
327
327
|
requirements: []
|
|
328
|
-
rubygems_version:
|
|
329
|
-
signing_key:
|
|
328
|
+
rubygems_version: 4.0.9
|
|
330
329
|
specification_version: 4
|
|
331
330
|
summary: Basic engine for all Lato projects
|
|
332
331
|
test_files: []
|