pg_rails 7.6.40 → 7.6.42

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +1 -1
  3. data/pg_engine/app/assets/stylesheets/tables.scss +5 -1
  4. data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +2 -1
  5. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +6 -2
  6. data/pg_engine/app/controllers/users/accounts_controller.rb +1 -1
  7. data/pg_engine/app/decorators/account_decorator.rb +8 -0
  8. data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +1 -1
  9. data/pg_engine/app/decorators/user_account_decorator.rb +1 -1
  10. data/pg_engine/app/views/pg_engine/base/index.html.slim +2 -0
  11. data/pg_engine/app/views/users/accounts/index.html.slim +5 -0
  12. data/pg_engine/app/views/users/accounts/show.html.slim +1 -1
  13. data/pg_engine/config/locales/es.yml +2 -0
  14. data/pg_engine/lib/pg_engine/test/dummy_brand.rb +2 -2
  15. data/pg_engine/spec/mailers/pg_engine/base_mailer_spec.rb +1 -1
  16. data/pg_engine/spec/requests/base_controller_requests_spec.rb +3 -3
  17. data/pg_engine/spec/system/signup_spec.rb +1 -1
  18. data/pg_layout/app/javascript/config/index.js +11 -5
  19. data/pg_layout/app/lib/navbar.rb +10 -3
  20. data/pg_layout/app/views/layouts/pg_layout/base.html.slim +2 -0
  21. data/pg_layout/app/views/pg_layout/_sidebar.html.slim +2 -1
  22. data/pg_layout/app/views/pg_layout/_sidebar_mobile.html.slim +2 -1
  23. data/pg_layout/app/views/pg_layout/_signed_in_links.html.slim +19 -2
  24. data/pg_rails/lib/version.rb +1 -1
  25. data/pg_scaffold/lib/generators/pg_factory_bot/model/model_generator.rb +1 -1
  26. data/pg_scaffold/lib/generators/pg_rspec/scaffold/scaffold_generator.rb +2 -2
  27. data/pg_scaffold/spec/generators_spec.rb +2 -3
  28. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf260a16e98842bebe950a0d4c3253d6c63f2690a922ec767c04d8a99ae7a0f7
4
- data.tar.gz: 57dfdff6f3042539d11089edccf7fa32df6c38f86d151256a1536f5efe6d073b
3
+ metadata.gz: 519ff463ff0b6b54cc215587c8b526a9ac0385b0f084ef40e67379d88a1d7f35
4
+ data.tar.gz: 6a2ecec603c7daafaef6ee31da7b734b5e5fd810d2da4b43dc8bda4132bc6def
5
5
  SHA512:
6
- metadata.gz: e6fa99a2c8881e8f615839ce690c7cb9bf1d3c3ed3cf31f5490641bc253bd2de7b8826ee7c9c2374716dc8b85653db0d066d5bf5dcd4739d41bac81ff2938fbc
7
- data.tar.gz: 65c53c5d31a893c6700347d16f9e3b2146a82b21ca2b5905fc214ab551ff844c9b9880118f59a1adc030cd8636fffd44908c5032482e28e3c1501dc14041af9e
6
+ metadata.gz: c113f2b3d27671bd93409e82c234be4a0dbcf595140b2dd2b5be95da5b5e0e115045127ce1f00d560d0973579f2befcf692ed8079d28459b870ed5256e40b04e
7
+ data.tar.gz: efd482246afc90ecfbd885041f62446d337c084a12af4ba71d7f1142a63060384cac0b7b01ebcd21e037efde1339458bb8aa46b9df080b731ca2fff400ad29cb
@@ -21,7 +21,7 @@ module PgAssociable
21
21
  # porque de todos modos se pisaría en el create
22
22
  if !object.persisted? &&
23
23
  template.nested_record.present? &&
24
- object.send(atributo) == (template.nested_record)
24
+ object.send(atributo) == template.nested_record
25
25
  options[:disabled] = true
26
26
  end
27
27
 
@@ -23,7 +23,11 @@ $values: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100;
23
23
  }
24
24
 
25
25
  // Table row clickable (bindListingClick)
26
- .listado tr:has(td:hover):has(.bi-eye-fill):not(:has(.actions-wrapper:hover)):not(:has(a:hover)):not(:has(.inline-edit:hover)) td {
26
+ .listado tr:has(td:hover):has(.bi-eye-fill):not(:has(.actions-wrapper:hover)):not(:has(a:hover)):not(:has(.inline-edit:hover)):not(:has(.inline-no-edit:hover)) td {
27
+ background-color: #f2f2f2;
28
+ cursor: pointer;
29
+ }
30
+ .listado tr:has(td:hover):has(.main-row-link):not(:has(.actions-wrapper:hover)):not(:has(a:hover)):not(:has(.inline-edit:hover)):not(:has(.inline-no-edit:hover)) td {
27
31
  background-color: #f2f2f2;
28
32
  cursor: pointer;
29
33
  }
@@ -14,4 +14,5 @@
14
14
  i.bi.bi-pencil
15
15
  span = @model.decorate.send(@attribute)
16
16
  - else
17
- = @model.decorate.send(@attribute)
17
+ span.inline-no-edit
18
+ = @model.decorate.send(@attribute)
@@ -382,7 +382,9 @@ module PgEngine
382
382
 
383
383
  def pg_respond_update
384
384
  object = instancia_modelo
385
+ # Maybe lock! to ensure consistency of audits
385
386
  if (@saved = object.save)
387
+ ActiveSupport::Notifications.instrument("record_updated.pg_engine", object)
386
388
  respond_to do |format|
387
389
  format.html do
388
390
  if params[:inline_attribute].present?
@@ -419,6 +421,7 @@ module PgEngine
419
421
  def pg_respond_create
420
422
  object = instancia_modelo
421
423
  if (@saved = object.save)
424
+ ActiveSupport::Notifications.instrument("record_created.pg_engine", object)
422
425
  if in_modal?
423
426
  body = <<~HTML.html_safe
424
427
  <pg-event data-event-name="pg:record-created" data-turbo-temporary
@@ -475,6 +478,7 @@ module PgEngine
475
478
  # rubocop:disable Metrics/PerceivedComplexity
476
479
  def pg_respond_destroy(model, land_on = nil)
477
480
  if destroy_model(model)
481
+ ActiveSupport::Notifications.instrument("record_destroyed.pg_engine", model)
478
482
  # TODO!!: rename to main
479
483
  if turbo_frame? && current_turbo_frame != 'top'
480
484
  body = <<~HTML.html_safe
@@ -581,12 +585,12 @@ module PgEngine
581
585
  if action_name == 'new'
582
586
  params.permit(atributos_permitidos)
583
587
  else
584
- params.require(nombre_modelo).permit(atributos_permitidos)
588
+ params.require(clase_modelo.model_name.param_key).permit(atributos_permitidos)
585
589
  end
586
590
  end
587
591
 
588
592
  def nombre_modelo
589
- clase_modelo.name.underscore
593
+ clase_modelo.model_name.element
590
594
  end
591
595
 
592
596
  def filtros_y_policy(campos, dflt_sort = nil, archived: false)
@@ -75,7 +75,7 @@ module Users
75
75
  end
76
76
 
77
77
  def atributos_para_listar
78
- %i[nombre owner]
78
+ %i[logo_f nombre owner]
79
79
  end
80
80
  end
81
81
  end
@@ -33,4 +33,12 @@ class AccountDecorator < PgEngine::BaseRecordDecorator
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ def logo_f
38
+ if logo.present?
39
+ image_tag logo.variant(:thumb), style: 'max-height:3em'
40
+ else
41
+ content_tag 'i', nil, class: 'bi bi-bag-fill text-center d-inline-block', style: 'font-size: 1.7em; width: 1.6em'
42
+ end
43
+ end
36
44
  end
@@ -196,7 +196,7 @@ module PgEngine
196
196
  end
197
197
 
198
198
  def target_new
199
- mod_name_sing = object.class.model_name.singular.to_sym
199
+ mod_name_sing = object.class.model_name.singular_route_key.to_sym
200
200
  [:new, pg_namespace, nested_record, mod_name_sing]
201
201
  end
202
202
 
@@ -15,7 +15,7 @@ class UserAccountDecorator < PgEngine::BaseRecordDecorator
15
15
  helpers.content_tag :span do
16
16
  h.link_to h.tenant_root_path(tid: object.to_param),
17
17
  'data-turbo-frame': :_top,
18
- class: 'btn btn-sm btn-primary' do
18
+ class: 'btn btn-sm btn-primary main-row-link' do
19
19
  '<i class="bi bi-box-arrow-in-right"></i> Ingresar'.html_safe
20
20
  end
21
21
  end
@@ -53,6 +53,8 @@
53
53
  tr
54
54
  th
55
55
  - atributos_para_listar.each do |att|
56
+ / TODO: poder configurar el ordenable en false
57
+ / Sería ideal hacer algo OOP, pero es medio bardo
56
58
  th.text-nowrap style="font-size: 0.8em" = encabezado att, ordenable: true
57
59
  - if action_name == 'archived'
58
60
  th.text-nowrap style="font-size: 0.8em" = encabezado :discarded_at, ordenable: true
@@ -3,3 +3,8 @@
3
3
  - content_for(:padding_top_class) { 'pt-0' }
4
4
 
5
5
  = render template: 'pg_engine/base/index'
6
+
7
+ css:
8
+ .listado {
9
+ vertical-align: middle;
10
+ }
@@ -5,7 +5,7 @@
5
5
  .text-center
6
6
  .d-flex.justify-content-center.gap-2.align-items-center.m-3
7
7
  - if @account.logo.present?
8
- = image_tag @account.logo, style: 'max-height:3em'
8
+ = image_tag @account.logo.variant(:thumb), style: 'max-height:3em'
9
9
  .fs-1
10
10
  = @account
11
11
 
@@ -187,6 +187,8 @@ es:
187
187
  attributes:
188
188
  account:
189
189
  owner: Administrado por
190
+ logo/scoped:
191
+ listado_header: ""
190
192
  user_account:
191
193
  membership_status: Estado
192
194
  user: Nombre
@@ -1,7 +1,7 @@
1
1
  module PgEngine
2
2
  module Test
3
3
  class DummyBrand < PgEngine::SiteBrand
4
- def initialize(include_all: false) # rubocop:disable Metrics/MethodLength
4
+ def initialize(skip_default_url_options: Rails.env.test?) # rubocop:disable Metrics/MethodLength
5
5
  super()
6
6
 
7
7
  @default_site_brand = :factura
@@ -48,7 +48,7 @@ module PgEngine
48
48
  }
49
49
  }
50
50
 
51
- return unless Rails.env.development? || include_all
51
+ return if skip_default_url_options
52
52
 
53
53
  @options.merge!({
54
54
  default_url_options: {
@@ -27,7 +27,7 @@ describe PgEngine::BaseMailer do
27
27
  # rubocop:disable Style/GlobalVars
28
28
  before do
29
29
  $site_brand_before = PgEngine.site_brand
30
- PgEngine.site_brand = PgEngine::Test::DummyBrand.new(include_all: true)
30
+ PgEngine.site_brand = PgEngine::Test::DummyBrand.new(skip_default_url_options: false)
31
31
  end
32
32
 
33
33
  after do
@@ -42,7 +42,7 @@ describe 'Base requests' do
42
42
  { 'ACCEPT' => 'text/html' }
43
43
  end
44
44
 
45
- include_examples 'manda el status correcto'
45
+ it_behaves_like 'manda el status correcto'
46
46
 
47
47
  it 'no manda el flash' do
48
48
  subject
@@ -60,7 +60,7 @@ describe 'Base requests' do
60
60
  { 'ACCEPT' => 'text/vnd.turbo-stream.html' }
61
61
  end
62
62
 
63
- include_examples 'manda el status correcto'
63
+ it_behaves_like 'manda el status correcto'
64
64
 
65
65
  it 'manda el flash' do
66
66
  subject
@@ -73,7 +73,7 @@ describe 'Base requests' do
73
73
  { 'ACCEPT' => 'application/json' }
74
74
  end
75
75
 
76
- include_examples 'manda el status correcto'
76
+ it_behaves_like 'manda el status correcto'
77
77
  end
78
78
  end
79
79
 
@@ -6,7 +6,7 @@ describe 'Al Registrarse' do
6
6
  include ActiveJob::TestHelper
7
7
 
8
8
  find_scroll = proc do |selector, options = {}|
9
- elem = find(selector, **options.merge(visible: :all))
9
+ elem = find(selector, **options, visible: :all)
10
10
  script = 'arguments[0].scrollIntoView({ behavior: "instant", block: "start", inline: "nearest" });'
11
11
  page.execute_script(script, elem)
12
12
  sleep 0.5
@@ -11,14 +11,20 @@ function bindListingClick () {
11
11
  document.body.onclick = (ev) => {
12
12
  if (ev.target.closest('a')) return
13
13
  if (ev.target.closest('.inline-edit')) return
14
+ if (ev.target.closest('.inline-no-edit')) return
14
15
  if (ev.target.closest('.listado')) {
15
16
  const row = ev.target.closest('tr')
16
17
  if (row) {
17
- const show = row.querySelector('.bi-eye-fill')
18
- if (show) {
19
- const link = show.closest('a')
20
- if (link) {
21
- link.click()
18
+ const mainRowLink = row.querySelector('.main-row-link')
19
+ if (mainRowLink) {
20
+ mainRowLink.click()
21
+ } else {
22
+ const show = row.querySelector('.bi-eye-fill')
23
+ if (show) {
24
+ const link = show.closest('a')
25
+ if (link) {
26
+ link.click()
27
+ }
22
28
  }
23
29
  }
24
30
  }
@@ -31,6 +31,14 @@ class Navbar
31
31
  @configured = true
32
32
  end
33
33
 
34
+ def topbar_signed_in_links
35
+ return [] if @user.blank?
36
+
37
+ configure
38
+
39
+ bar('topbar.signed_in')
40
+ end
41
+
34
42
  def sidebar
35
43
  configure
36
44
 
@@ -43,13 +51,13 @@ class Navbar
43
51
  bar_data = @yaml_data[key]
44
52
  return [] if bar_data.blank?
45
53
 
46
- # rubocop:disable Style/MultilineBlockChain:
54
+ # rubocop:disable Style/MultilineBlockChain
47
55
  orig_idx = 0
48
56
  bar_data.map do |item|
49
57
  orig_idx += 1
50
58
  evaluate_node(item, orig_idx)
51
59
  end.sort_by { |a| [a[:priority], a[:orig_idx]] }
52
- # rubocop:enable Style/MultilineBlockChain:
60
+ # rubocop:enable Style/MultilineBlockChain
53
61
  end
54
62
 
55
63
  def evaluate_node(item, orig_idx = nil)
@@ -77,7 +85,6 @@ class Navbar
77
85
 
78
86
  def any_children_active?(entry, request)
79
87
  entry[:children].any? { |child| active_entry?(child, request) }
80
- # TODO: quitar
81
88
  end
82
89
 
83
90
  def hide_entry?(entry)
@@ -33,6 +33,8 @@ html
33
33
  meta name="view-transition" content="same-origin"
34
34
  meta name="cable-history-timestamp" content="#{Time.now.to_i}"
35
35
 
36
+ / Para qué era esto? Tenía que ver con la cache, no sé si del browser o de nginx, o de Rails
37
+ / Pero no sé si sigue siendo necesario. Se usa en las páginas estáticas de legales y history
36
38
  - unless @skip_csrf_meta_tags
37
39
  = csrf_meta_tags
38
40
 
@@ -16,7 +16,8 @@ div id="sidebar" class="#{@navbar_opened_class} flex-shrink-0 d-none d-#{@breakp
16
16
  - else
17
17
  span.bi.bi-chevron-right.ms-1.align-text-bottom style="font-size: 0.7em"
18
18
 
19
- .collapse data-turbo-temporary=('true' unless active) class="#{ 'show' if active}" id=entry_id
19
+ / data-turbo-temporary=('true' unless active)
20
+ .collapse class="#{ 'show' if active}" id=entry_id
20
21
  .collapse-inner
21
22
  - entry[:children].each do |child|
22
23
  - next if @navbar.hide_entry?(child)
@@ -21,7 +21,8 @@
21
21
  - else
22
22
  span.bi.bi-chevron-right.ms-1.align-text-bottom style="font-size: 0.7em"
23
23
 
24
- .collapse data-turbo-temporary=('true' unless active) class="#{ 'show' if active}" id=entry_id
24
+ / data-turbo-temporary=('true' unless active)
25
+ .collapse class="#{ 'show' if active}" id=entry_id
25
26
  .collapse-inner
26
27
  - entry[:children].each do |child|
27
28
  - next if @navbar.hide_entry?(child)
@@ -15,7 +15,13 @@ ul.navbar-nav.gap-3.align-items-center class="gap-#{@breakpoint_navbar_expand}-0
15
15
  - if @other_active_accounts&.any?
16
16
  h6.dropdown-header Cambiar a:
17
17
  - @other_active_accounts.each do |ua|
18
- li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
18
+ li
19
+ = link_to tenant_root_path(tid: ua.to_param), class: 'dropdown-item' do
20
+ - if ua.account.logo.present?
21
+ span = image_tag ua.account.logo.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
22
+ - else
23
+ i.bi.bi-bag-fill.me-2.d-inline-block.text-center style="font-size: 1.7em; width: 1.6em"
24
+ span = ua.account
19
25
  li
20
26
  hr.dropdown-divider
21
27
  li = link_to "Administrar #{Account.nombre_plural.downcase}", users_accounts_path(tid: nil), class: 'dropdown-item'
@@ -27,7 +33,11 @@ ul.navbar-nav.gap-3.align-items-center class="gap-#{@breakpoint_navbar_expand}-0
27
33
  = Account.nombre_plural
28
34
  ul.dropdown-menu
29
35
  - @other_active_accounts.each do |ua|
30
- li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
36
+ li
37
+ = link_to tenant_root_path(tid: ua.to_param), class: 'dropdown-item' do
38
+ - if ua.account.logo.present?
39
+ span = image_tag ua.account.logo.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
40
+ span = ua.account
31
41
  li
32
42
  hr.dropdown-divider
33
43
  li = link_to "Administrar #{Account.nombre_plural.downcase}", users_accounts_path(tid: nil), class: 'dropdown-item'
@@ -50,5 +60,12 @@ ul.navbar-nav.gap-3.align-items-center class="gap-#{@breakpoint_navbar_expand}-0
50
60
  li = link_to Account.nombre_plural, users_accounts_path(tid: nil), class: 'dropdown-item'
51
61
  - if Current.user.developer?
52
62
  li = link_to 'Admin', admin_users_path, class: 'dropdown-item'
63
+
64
+ - if @navbar.present?
65
+ - @navbar.topbar_signed_in_links.each do |entry|
66
+ - next if @navbar.hide_entry?(entry)
67
+ li
68
+ a href=entry[:path] class="dropdown-item #{@navbar.active_entry?(entry, request) ? 'active' : ''} #{entry[:attributes]}"
69
+ = entry[:title]
53
70
  li = link_to 'Cerrar sesión', destroy_user_session_path(tid: nil),
54
71
  'data-turbo-method': :delete, class: 'dropdown-item'
@@ -2,6 +2,6 @@
2
2
 
3
3
  # :nocov:
4
4
  module PgRails
5
- VERSION = '7.6.40'
5
+ VERSION = '7.6.42'
6
6
  end
7
7
  # :nocov:
@@ -82,7 +82,7 @@ module PgFactoryBot
82
82
  'Faker::Lorem.sentence'
83
83
  elsif attribute.type == :date
84
84
  'Faker::Date.backward'
85
- elsif attribute.type == :float || attribute.type == :decimal
85
+ elsif %i[float decimal].include?(attribute.type)
86
86
  'Faker::Number.decimal(l_digits: 3, r_digits: 2)'
87
87
  elsif attribute.type == :integer
88
88
  'rand(1..9999)'
@@ -15,8 +15,8 @@ module PgRspec
15
15
  class_option :trackeo_de_usuarios, type: :boolean, default: true,
16
16
  desc: 'Genera campos creado_por y actualizado_por.'
17
17
 
18
- class_option :controller_specs, type: :boolean, default: true
19
- class_option :request_specs, type: :boolean, default: false
18
+ class_option :controller_specs, type: :boolean, default: false
19
+ class_option :request_specs, type: :boolean, default: true
20
20
  class_option :view_specs, type: :boolean, default: false
21
21
 
22
22
  # remove_hook_for :integration_tool, as: :integration
@@ -33,9 +33,8 @@ describe 'Generators', type: :generator do
33
33
  it do
34
34
  run_generator(['users/modelo', 'bla:integer'])
35
35
 
36
- my_assert_file 'spec/controllers/users/modelos_controller_spec.rb' do |content|
37
- expect(content).to match(/routing/)
38
- expect(content).to match(/sign_in/)
36
+ my_assert_file 'spec/requests/users/modelos_spec.rb' do |content|
37
+ expect(content).to match(/valid_attributes/)
39
38
  end
40
39
  end
41
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.6.40
4
+ version: 7.6.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martín Rosso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-08 00:00:00.000000000 Z
11
+ date: 2025-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails