pg_rails 7.6.8 → 7.6.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61bc441e108885c9686261c08fc110a3096fd0da5f43b78c5b995f2d6a0ae69b
4
- data.tar.gz: b016d6b41b1a814e135c0e15049469ea61c37a056bc4e9545b8946195d0e7164
3
+ metadata.gz: 91cd30e1ebe3fd2ec058f38ac2ad843421e8bb65c989aa5c8b5b7597703719f5
4
+ data.tar.gz: ceeaa8d7d5a2e3cfb32b39ff6c5da0b4c497a826685ef35f92be2cade7ad2d28
5
5
  SHA512:
6
- metadata.gz: 31fc27bf74fce36435f8e23283d5612f893baca07f8d90ac26df6bfe870a7aa74df8b91b116445c680da11e8bebb1db35c7dba2f3ed46ab9ca458d72636f1ca8
7
- data.tar.gz: 0a74fc77e43ef5000cd6acce42f1f48e00bcb07f80847c8a2b3c9c9c2e750ef96dceb51418092f1e3eb75ae160771b4ed4438c524c570dfa8b855a20462f56ba
6
+ metadata.gz: 4e4444db810e6836a963c75fa5727c39f434c6032c269671bd9286fca0eb788a3013c45f494cebf2c583df4bc0c37803922d86090bc10685e46fee4b158919aa
7
+ data.tar.gz: a44d48f9d63295bdf519ac6ba424ebc0d1ed1c69f28b5c8be898b1c58dc72165a8ae3b5bb75f4ac47efc13987fba2e134cf275f03a7ac00f9251774f1f387c78
@@ -6,7 +6,7 @@ module PgAssociable
6
6
  mod.include PgEngine::RouteHelper
7
7
  end
8
8
 
9
- MAXIMO_PARA_SELECT = 10
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
- options.deep_merge!({ wrapper_html: { 'data-puede-crear': 'true' } }) if puede_crear
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 && collection.count <= MAXIMO_PARA_SELECT
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)
@@ -138,16 +138,6 @@ export default class extends Controller {
138
138
  resetResultados () {
139
139
  this.lastValue = null
140
140
  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
141
  if (this.element.dataset.preload) {
152
142
  JSON.parse(this.element.dataset.preload).forEach((object) => {
153
143
  rows.push(
@@ -162,6 +152,18 @@ export default class extends Controller {
162
152
  )
163
153
  })
164
154
  }
155
+ if (this.element.dataset.puedeCrear) {
156
+ rows.push(
157
+ <a key="new" href="javascript:void(0)"
158
+ className="list-group-item mt-3 text-center"
159
+ data-action="asociable#crearItem"
160
+ >
161
+ <i className="bi bi-stars"/>
162
+ &nbsp;
163
+ {this.element.dataset.puedeCrear}
164
+ </a>
165
+ )
166
+ }
165
167
  this.subWrapper.innerHTML = renderToStaticMarkup(
166
168
  <div className="resultados" tabIndex={-1}>
167
169
  <ul className="list-group list-group-flush">
@@ -279,7 +281,6 @@ export default class extends Controller {
279
281
  <input type="hidden" name="id" value={this.elemId} />
280
282
  <input type="hidden" name="query" value={this.input.value} />
281
283
  <input type="hidden" name="timeout_id" value={timeouts} />
282
- <input type="hidden" name="puede_crear" value={this.element.dataset.puedeCrear} />
283
284
  </form>
284
285
  )
285
286
  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 collection.any?
5
+ - if count.positive?
6
+ .text-center.fst-italic 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.px-3.py-1 style="font-size: 0.85em" No hay resultados para "#{query}"
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
+ | &nbsp;
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, 'Nuevo'
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'
@@ -1,18 +1,19 @@
1
1
  = helpers.turbo_frame_tag(@frame_id, class: 'inline-edit')
2
- = helpers.pg_form_for(@model, render_errors: false, wrapper_mappings: @wrapper_mappings) do |f|
3
- = hidden_field_tag :inline_attribute, @attribute
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
- / html5 solo aplica a datetime
6
- / date_selector solo aplica a date
7
- / ignore_date y prompt solo aplica a time
8
- / cada caso es inocuo para el resto de los types
9
- = f.field @unsuffixed_attribute, label: false, date_selector: true, minute_step: 15,
10
- ignore_date: true, prompt: { hour: 'hh', minute: 'mm' }
11
- .actions.d-flex.gap-1
12
- = button_tag class: 'btn btn-sm btn-primary',
13
- data: { controller: 'tooltip', 'bs-title': 'Guardar' } do
14
- i.bi.bi-check-lg
15
- = link_to users_inline_show_path(model: @model.to_gid, attribute: @attribute),
16
- class: 'btn btn-sm btn-secondary',
17
- data: { controller: 'tooltip', 'bs-title': 'Cancelar' } do
18
- i.bi.bi-x-lg
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: :inline_form_control,
6
+ date: :inline_form_control_autosubmit,
7
7
  datetime: :inline_form_control,
8
8
  time: :inline_multi_select,
9
9
  select: :inline_form_select
@@ -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 = "Adjuntar archivos"
10
- Trix.config.lang.bold = "Negrita"
11
- Trix.config.lang.bullets = "Lista sin números"
12
- Trix.config.lang.byte = "Byte"
13
- Trix.config.lang.bytes = "Bytes"
14
- Trix.config.lang.captionPlaceholder = "Agregá un subtítulo"
15
- Trix.config.lang.code = "Monospace"
16
- Trix.config.lang.heading1 = "Título"
17
- Trix.config.lang.indent = "Incrementar nivel"
18
- Trix.config.lang.italic = "Cursiva"
19
- Trix.config.lang.link = "Linkear"
20
- Trix.config.lang.numbers = "Lista numerada"
21
- Trix.config.lang.outdent = "Disminuir nivel"
22
- Trix.config.lang.quote = "Cita"
23
- Trix.config.lang.redo = "Rehacer"
24
- Trix.config.lang.remove = "Quitar"
25
- Trix.config.lang.strike = "Tachar"
26
- Trix.config.lang.undo = "Deshacer"
27
- Trix.config.lang.unlink = "Deslinkear"
28
- Trix.config.lang.url = "URL"
29
- Trix.config.lang.urlPlaceholder = "Ingresá una URL"
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
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.6.8'
4
+ VERSION = '7.6.9'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.6.8
4
+ version: 7.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martín Rosso