pg_rails 7.6.8 → 7.6.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/pg_associable/app/assets/stylesheets/pg_associable.scss +10 -1
- data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +16 -5
- data/pg_associable/app/helpers/pg_associable/helpers.rb +2 -1
- data/pg_associable/app/javascript/asociable_controller.tsx +12 -12
- data/pg_associable/app/views/pg_associable/_resultados_inline.html.slim +14 -3
- data/pg_associable/spec/system/associable_spec.rb +1 -1
- data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +6 -2
- data/pg_engine/app/components/inline_edit/inline_edit_component.html.slim +17 -16
- data/pg_engine/app/components/inline_edit/inline_edit_component.rb +1 -1
- data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +1 -1
- data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +7 -0
- data/pg_engine/config/simple_form/simple_form_bootstrap.rb +16 -1
- data/pg_layout/app/javascript/application.js +23 -21
- data/pg_layout/app/javascript/controllers/pg_form_controller.js +15 -0
- data/pg_rails/lib/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: 893c71adcb5816e5cbd09b2860163a03d84c56a4980388578f22ce31dd75e2c6
|
4
|
+
data.tar.gz: 8debfcd4a503776a404c284add03df833a2e95efea61ba51e67068203bd72492
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee18015d09a9ab2940295018f8cb5e8feb2bebb015e90b18984971f6194360cb205b614d5649155df68cbc619f173f3dcb46c9df6aa4f3f3166a00841cb244ef
|
7
|
+
data.tar.gz: 77223fb87d0035b0165b4c0edf47830dfc5493a07ec567bc6628a8c3d3407dc2d16030b03d5502d310f8fbf0d2602293b1b63c82d0912166186449798db3beed
|
@@ -82,17 +82,26 @@
|
|
82
82
|
.sub-wrapper {
|
83
83
|
overflow: auto;
|
84
84
|
box-shadow: 0px 9px 13px -3px rgba(0, 0, 0, 0.5);
|
85
|
+
z-index: 50;
|
85
86
|
// position: absolute;
|
86
87
|
// z-index: 1;
|
87
88
|
background-color: #{$body-bg};
|
88
89
|
border: 1px solid #a7b7bb;
|
89
90
|
border-top: none;
|
90
91
|
border-radius: 4px;
|
91
|
-
padding: 5px 0;
|
92
|
+
// padding: 5px 0;
|
92
93
|
width: 100%;
|
93
94
|
|
94
95
|
border-top-left-radius: 0;
|
95
96
|
border-top-right-radius: 0;
|
97
|
+
|
98
|
+
a[data-action="asociable#crearItem"] {
|
99
|
+
position: sticky;
|
100
|
+
bottom: 0;
|
101
|
+
background-color: #faf5ff;
|
102
|
+
outline: 1px solid #ababcc;
|
103
|
+
box-shadow: 20px 9px 13px 7px rgba(0, 0, 0, 0.5);
|
104
|
+
}
|
96
105
|
}
|
97
106
|
.modal-asociable .modal-footer {
|
98
107
|
justify-content: space-between;
|
@@ -6,7 +6,7 @@ module PgAssociable
|
|
6
6
|
mod.include PgEngine::RouteHelper
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
LIMIT_TO_AUTOPRELOAD = 10
|
10
10
|
# TODO: si está entre 10 y 50, habilitar un buscador por js
|
11
11
|
|
12
12
|
def pg_associable_pro(atributo, options = {})
|
@@ -27,15 +27,21 @@ module PgAssociable
|
|
27
27
|
return input(atributo, options) if options[:disabled]
|
28
28
|
|
29
29
|
collection, puede_crear = collection_pc(atributo, options)
|
30
|
-
|
30
|
+
collection_count = collection.count
|
31
|
+
options.deep_merge!({ wrapper_html: { 'data-puede-crear': text_for_new(atributo) } }) if puede_crear
|
31
32
|
|
32
|
-
if !puede_crear &&
|
33
|
+
if !puede_crear && collection_count <= LIMIT_TO_AUTOPRELOAD
|
33
34
|
select_comun(atributo, options, collection)
|
34
35
|
else
|
35
|
-
select_pro(atributo, options, collection)
|
36
|
+
select_pro(atributo, options, collection, collection_count)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
def text_for_new(atributo)
|
41
|
+
klass = clase_asociacion(atributo)
|
42
|
+
klass.new.decorate.text_for_new
|
43
|
+
end
|
44
|
+
|
39
45
|
def collection_pc(atributo, _options)
|
40
46
|
klass = clase_asociacion(atributo)
|
41
47
|
user = Current.user
|
@@ -45,7 +51,12 @@ module PgAssociable
|
|
45
51
|
[collection, puede_crear]
|
46
52
|
end
|
47
53
|
|
48
|
-
def select_pro(atributo, options, collection)
|
54
|
+
def select_pro(atributo, options, collection, collection_count = nil)
|
55
|
+
if collection_count.present? && collection_count.positive? &&
|
56
|
+
collection_count < LIMIT_TO_AUTOPRELOAD && options[:preload].blank?
|
57
|
+
options[:preload] = collection
|
58
|
+
end
|
59
|
+
|
49
60
|
if (preload = options.delete(:preload))
|
50
61
|
collection = preload.is_a?(Integer) ? collection.limit(preload) : preload
|
51
62
|
options.deep_merge!({ wrapper_html: { 'data-preload': collection.decorate.to_json } })
|
@@ -16,9 +16,10 @@ module PgAssociable
|
|
16
16
|
query = params[:query]
|
17
17
|
timeout_id = params[:timeout_id]
|
18
18
|
@collection = search_in_scope(query)
|
19
|
+
@count = @collection.count
|
19
20
|
render turbo_stream:
|
20
21
|
turbo_stream.update("#{resultados_prefix}-#{params[:id]}",
|
21
|
-
partial:, locals: { collection: @collection, query:, timeout_id: })
|
22
|
+
partial:, locals: { collection: @collection, query:, timeout_id:, count: @count })
|
22
23
|
end
|
23
24
|
|
24
25
|
def search_in_scope(query)
|
@@ -27,7 +27,6 @@ export default class extends Controller {
|
|
27
27
|
this.subWrapper.setAttribute('id', `resultados-inline-${this.elemId}`)
|
28
28
|
this.subWrapper.classList.add('sub-wrapper')
|
29
29
|
this.subWrapper.classList.add('position-absolute')
|
30
|
-
this.subWrapper.classList.add('z-1')
|
31
30
|
result.appendChild(this.subWrapper)
|
32
31
|
this.input.parentNode.appendChild(result)
|
33
32
|
|
@@ -138,16 +137,6 @@ export default class extends Controller {
|
|
138
137
|
resetResultados () {
|
139
138
|
this.lastValue = null
|
140
139
|
const rows = []
|
141
|
-
if (this.element.dataset.puedeCrear) {
|
142
|
-
rows.push(
|
143
|
-
<a key="new" href="javascript:void(0)"
|
144
|
-
className="list-group-item"
|
145
|
-
data-action="asociable#crearItem"
|
146
|
-
>
|
147
|
-
Nuevo
|
148
|
-
</a>
|
149
|
-
)
|
150
|
-
}
|
151
140
|
if (this.element.dataset.preload) {
|
152
141
|
JSON.parse(this.element.dataset.preload).forEach((object) => {
|
153
142
|
rows.push(
|
@@ -162,6 +151,18 @@ export default class extends Controller {
|
|
162
151
|
)
|
163
152
|
})
|
164
153
|
}
|
154
|
+
if (this.element.dataset.puedeCrear) {
|
155
|
+
rows.push(
|
156
|
+
<a key="new" href="javascript:void(0)"
|
157
|
+
className="list-group-item mt-3 text-center"
|
158
|
+
data-action="asociable#crearItem"
|
159
|
+
>
|
160
|
+
<i className="bi bi-stars"/>
|
161
|
+
|
162
|
+
{this.element.dataset.puedeCrear}
|
163
|
+
</a>
|
164
|
+
)
|
165
|
+
}
|
165
166
|
this.subWrapper.innerHTML = renderToStaticMarkup(
|
166
167
|
<div className="resultados" tabIndex={-1}>
|
167
168
|
<ul className="list-group list-group-flush">
|
@@ -279,7 +280,6 @@ export default class extends Controller {
|
|
279
280
|
<input type="hidden" name="id" value={this.elemId} />
|
280
281
|
<input type="hidden" name="query" value={this.input.value} />
|
281
282
|
<input type="hidden" name="timeout_id" value={timeouts} />
|
282
|
-
<input type="hidden" name="puede_crear" value={this.element.dataset.puedeCrear} />
|
283
283
|
</form>
|
284
284
|
)
|
285
285
|
const form = document.createElement('div')
|
@@ -1,12 +1,23 @@
|
|
1
|
-
/ # locals: (collection:, query:, timeout_id:, field_name: nil)
|
1
|
+
/ # locals: (collection:, query:, timeout_id:, count:, field_name: nil)
|
2
2
|
.resultados.inline tabindex="-1"
|
3
3
|
div data-controller="clear-timeout" data-timeout-id="#{timeout_id}"
|
4
4
|
ul.list-group.list-group-flush
|
5
|
-
- if
|
5
|
+
- if count.positive?
|
6
|
+
.text-center.fst-italic.text-secondary.pt-1 style="font-size:0.7em"
|
7
|
+
| #{count} resultados para "#{query}"
|
6
8
|
- collection.each do |object|
|
7
9
|
= link_to object.to_s, 'javascript:void(0)',
|
8
10
|
class: 'list-group-item',
|
9
11
|
data: { action: 'asociable#selectItem',
|
10
12
|
id: object.id, object: object.decorate.to_json, field_name: }
|
11
13
|
- else
|
12
|
-
li
|
14
|
+
li [class="list-group-item text-center text-warning-emphasis py-2" style="font-size: 0.85em"]
|
15
|
+
| No hay resultados para "#{query}"
|
16
|
+
|
17
|
+
- if policy(clase_modelo).new_from_associable?
|
18
|
+
/ TODO: unificar código repetido en asociable_controller.js
|
19
|
+
a [key="new" href="javascript:void(0)" class="list-group-item mt-3 text-center"
|
20
|
+
data-action="asociable#crearItem"]
|
21
|
+
i class="bi bi-stars"
|
22
|
+
|
|
23
|
+
= clase_modelo.new.decorate.text_for_new
|
@@ -14,7 +14,7 @@ describe 'Associable' do
|
|
14
14
|
fill_in 'cosa_nombre', with: 'La cosa'
|
15
15
|
select 'Los', from: 'cosa_tipo'
|
16
16
|
find('.cosa_categoria_de_cosa input[type=text]').click
|
17
|
-
expect(page).to have_text :all, '
|
17
|
+
expect(page).to have_text :all, 'Nueva categoría de cosa'
|
18
18
|
find('.cosa_categoria_de_cosa .list-group-item').click
|
19
19
|
select Account.first.to_s
|
20
20
|
fill_in 'categoria_de_cosa_nombre', with: 'la categoría'
|
@@ -211,6 +211,10 @@ input[type=datetime-local], input[type=datetime] {
|
|
211
211
|
border-bottom: 1px dotted #333;
|
212
212
|
padding-bottom: 1px;
|
213
213
|
|
214
|
+
.edit-link {
|
215
|
+
color: rgba(33, 37, 41, 0.21);
|
216
|
+
}
|
217
|
+
|
214
218
|
&:not(:has(.trix-content)) .edit-link {
|
215
219
|
margin-right: 0.25em;
|
216
220
|
}
|
@@ -221,8 +225,8 @@ input[type=datetime-local], input[type=datetime] {
|
|
221
225
|
border-bottom: 1px dotted #333;
|
222
226
|
}
|
223
227
|
|
224
|
-
|
225
|
-
i {
|
228
|
+
&:hover {
|
229
|
+
.edit-link i {
|
226
230
|
color: black;
|
227
231
|
}
|
228
232
|
}
|
@@ -1,18 +1,19 @@
|
|
1
1
|
= helpers.turbo_frame_tag(@frame_id, class: 'inline-edit')
|
2
|
-
=
|
3
|
-
=
|
2
|
+
div data-controller="pg_form"
|
3
|
+
= helpers.pg_form_for(@model, render_errors: false, wrapper_mappings: @wrapper_mappings) do |f|
|
4
|
+
= hidden_field_tag :inline_attribute, @attribute
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
6
|
+
/ html5 solo aplica a datetime
|
7
|
+
/ date_selector solo aplica a date
|
8
|
+
/ ignore_date y prompt solo aplica a time
|
9
|
+
/ cada caso es inocuo para el resto de los types
|
10
|
+
= f.field @unsuffixed_attribute, label: false, date_selector: true, minute_step: 15,
|
11
|
+
ignore_date: true, prompt: { hour: 'hh', minute: 'mm' }
|
12
|
+
.actions.d-flex.gap-1
|
13
|
+
= button_tag class: 'btn btn-sm btn-primary',
|
14
|
+
data: { controller: 'tooltip', 'bs-title': 'Guardar' } do
|
15
|
+
i.bi.bi-check-lg
|
16
|
+
= link_to users_inline_show_path(model: @model.to_gid, attribute: @attribute),
|
17
|
+
class: 'btn btn-sm btn-secondary',
|
18
|
+
data: { controller: 'tooltip', 'bs-title': 'Cancelar' } do
|
19
|
+
i.bi.bi-x-lg
|
@@ -3,7 +3,7 @@ class InlineEditComponent < InlineComponent
|
|
3
3
|
@wrapper_mappings = {
|
4
4
|
string: :inline_form_grow,
|
5
5
|
pg_associable: :inline_form_control,
|
6
|
-
date: :
|
6
|
+
date: :inline_form_control_autosubmit,
|
7
7
|
datetime: :inline_form_control,
|
8
8
|
time: :inline_multi_select,
|
9
9
|
select: :inline_form_select
|
@@ -4,7 +4,7 @@
|
|
4
4
|
data: { \
|
5
5
|
controller: :tooltip,
|
6
6
|
'bs-title': "Modificar #{@model.class.human_attribute_name(@attribute).downcase}" },
|
7
|
-
class: '
|
7
|
+
class: 'edit-link', style: 'font-size: 0.8em' do
|
8
8
|
i.bi.bi-pencil
|
9
9
|
span = @model.decorate.send(@attribute)
|
10
10
|
- else
|
@@ -26,6 +26,13 @@ module PgEngine
|
|
26
26
|
truncate(object.to_s)
|
27
27
|
end
|
28
28
|
|
29
|
+
def text_for_new
|
30
|
+
klass = object.class
|
31
|
+
# TODO: no está bueno tener que hacer el new, gender debería estar en la clase
|
32
|
+
verb = klass.new.gender == 'f' ? 'Nueva' : 'Nuevo'
|
33
|
+
"#{verb} #{klass.model_name.human.downcase}"
|
34
|
+
end
|
35
|
+
|
29
36
|
# rubocop:disable Style/MissingRespondToMissing
|
30
37
|
def method_missing(method_name, *args, &)
|
31
38
|
valor = object.attributes[method_name.to_s]
|
@@ -310,6 +310,21 @@ SimpleForm.setup do |config|
|
|
310
310
|
b.optional :hint, wrap_with: { class: 'form-text' }
|
311
311
|
end
|
312
312
|
|
313
|
+
config.wrappers :inline_form_control_autosubmit, class: '' do |b|
|
314
|
+
b.use :html5
|
315
|
+
b.use :placeholder
|
316
|
+
b.optional :maxlength
|
317
|
+
b.optional :minlength
|
318
|
+
b.optional :pattern
|
319
|
+
b.optional :min_max
|
320
|
+
b.optional :readonly
|
321
|
+
b.use :label, class: 'visually-hidden'
|
322
|
+
|
323
|
+
b.use :input, class: 'form-control form-control-sm', error_class: 'is-invalid', 'data-action': 'pg_form#submit'
|
324
|
+
b.use :error, wrap_with: { class: 'invalid-feedback' }
|
325
|
+
b.optional :hint, wrap_with: { class: 'form-text' }
|
326
|
+
end
|
327
|
+
|
313
328
|
config.wrappers :inline_form_select, class: '' do |b|
|
314
329
|
b.use :html5
|
315
330
|
b.use :placeholder
|
@@ -320,7 +335,7 @@ SimpleForm.setup do |config|
|
|
320
335
|
b.optional :readonly
|
321
336
|
b.use :label, class: 'visually-hidden'
|
322
337
|
|
323
|
-
b.use :input, class: 'form-select form-select-sm', error_class: 'is-invalid'
|
338
|
+
b.use :input, class: 'form-select form-select-sm', error_class: 'is-invalid', 'data-action': 'pg_form#submit'
|
324
339
|
b.use :error, wrap_with: { class: 'invalid-feedback' }
|
325
340
|
b.optional :hint, wrap_with: { class: 'form-text' }
|
326
341
|
end
|
@@ -5,28 +5,30 @@ import './elements'
|
|
5
5
|
|
6
6
|
import { Turbo } from '@hotwired/turbo-rails'
|
7
7
|
|
8
|
+
import Trix from 'trix'
|
9
|
+
|
8
10
|
document.addEventListener('trix-before-initialize', (ev) => {
|
9
|
-
Trix.config.lang.attachFiles =
|
10
|
-
Trix.config.lang.bold =
|
11
|
-
Trix.config.lang.bullets =
|
12
|
-
Trix.config.lang.byte =
|
13
|
-
Trix.config.lang.bytes =
|
14
|
-
Trix.config.lang.captionPlaceholder =
|
15
|
-
Trix.config.lang.code =
|
16
|
-
Trix.config.lang.heading1 =
|
17
|
-
Trix.config.lang.indent =
|
18
|
-
Trix.config.lang.italic =
|
19
|
-
Trix.config.lang.link =
|
20
|
-
Trix.config.lang.numbers =
|
21
|
-
Trix.config.lang.outdent =
|
22
|
-
Trix.config.lang.quote =
|
23
|
-
Trix.config.lang.redo =
|
24
|
-
Trix.config.lang.remove =
|
25
|
-
Trix.config.lang.strike =
|
26
|
-
Trix.config.lang.undo =
|
27
|
-
Trix.config.lang.unlink =
|
28
|
-
Trix.config.lang.url =
|
29
|
-
Trix.config.lang.urlPlaceholder =
|
11
|
+
Trix.config.lang.attachFiles = 'Adjuntar archivos'
|
12
|
+
Trix.config.lang.bold = 'Negrita'
|
13
|
+
Trix.config.lang.bullets = 'Lista sin números'
|
14
|
+
Trix.config.lang.byte = 'Byte'
|
15
|
+
Trix.config.lang.bytes = 'Bytes'
|
16
|
+
Trix.config.lang.captionPlaceholder = 'Agregá un subtítulo'
|
17
|
+
Trix.config.lang.code = 'Monospace'
|
18
|
+
Trix.config.lang.heading1 = 'Título'
|
19
|
+
Trix.config.lang.indent = 'Incrementar nivel'
|
20
|
+
Trix.config.lang.italic = 'Cursiva'
|
21
|
+
Trix.config.lang.link = 'Linkear'
|
22
|
+
Trix.config.lang.numbers = 'Lista numerada'
|
23
|
+
Trix.config.lang.outdent = 'Disminuir nivel'
|
24
|
+
Trix.config.lang.quote = 'Cita'
|
25
|
+
Trix.config.lang.redo = 'Rehacer'
|
26
|
+
Trix.config.lang.remove = 'Quitar'
|
27
|
+
Trix.config.lang.strike = 'Tachar'
|
28
|
+
Trix.config.lang.undo = 'Deshacer'
|
29
|
+
Trix.config.lang.unlink = 'Deslinkear'
|
30
|
+
Trix.config.lang.url = 'URL'
|
31
|
+
Trix.config.lang.urlPlaceholder = 'Ingresá una URL'
|
30
32
|
})
|
31
33
|
|
32
34
|
document.addEventListener('pg:record-created', (ev) => {
|
@@ -34,4 +34,19 @@ export default class extends Controller {
|
|
34
34
|
}
|
35
35
|
}
|
36
36
|
}
|
37
|
+
|
38
|
+
submit () {
|
39
|
+
let form = null
|
40
|
+
if (this.element instanceof HTMLFormElement) {
|
41
|
+
form = this.element
|
42
|
+
} else {
|
43
|
+
form = this.element.querySelector('form')
|
44
|
+
}
|
45
|
+
if (form) {
|
46
|
+
form.requestSubmit()
|
47
|
+
} else {
|
48
|
+
Rollbar.error('No form found')
|
49
|
+
console.error('No form found')
|
50
|
+
}
|
51
|
+
}
|
37
52
|
}
|
data/pg_rails/lib/version.rb
CHANGED