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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61bc441e108885c9686261c08fc110a3096fd0da5f43b78c5b995f2d6a0ae69b
4
- data.tar.gz: b016d6b41b1a814e135c0e15049469ea61c37a056bc4e9545b8946195d0e7164
3
+ metadata.gz: 893c71adcb5816e5cbd09b2860163a03d84c56a4980388578f22ce31dd75e2c6
4
+ data.tar.gz: 8debfcd4a503776a404c284add03df833a2e95efea61ba51e67068203bd72492
5
5
  SHA512:
6
- metadata.gz: 31fc27bf74fce36435f8e23283d5612f893baca07f8d90ac26df6bfe870a7aa74df8b91b116445c680da11e8bebb1db35c7dba2f3ed46ab9ca458d72636f1ca8
7
- data.tar.gz: 0a74fc77e43ef5000cd6acce42f1f48e00bcb07f80847c8a2b3c9c9c2e750ef96dceb51418092f1e3eb75ae160771b4ed4438c524c570dfa8b855a20462f56ba
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
- 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)
@@ -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
+ &nbsp;
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 collection.any?
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.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'
@@ -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
- a:hover {
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
- = 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
@@ -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: 'text-body-tertiary edit-link', style: 'font-size: 0.8em' do
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 = "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.10'
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.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martín Rosso