pg_rails 7.5.6 → 7.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) 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/components/asociable_modal_component.html.slim +1 -0
  4. data/pg_engine/app/controllers/admin/user_accounts_controller.rb +2 -0
  5. data/pg_engine/app/controllers/pg_engine/base_controller.rb +9 -1
  6. data/pg_engine/app/controllers/pg_engine/base_public_controller.rb +2 -0
  7. data/pg_engine/app/controllers/public/webhooks_controller.rb +6 -0
  8. data/pg_engine/app/models/user.rb +6 -0
  9. data/pg_engine/app/views/admin/accounts/show.html.slim +2 -0
  10. data/pg_engine/app/views/users/account_switcher/list.html.slim +1 -1
  11. data/pg_engine/config/initializers/action_controller.rb +7 -0
  12. data/pg_engine/config/routes.rb +3 -1
  13. data/pg_engine/lib/pg_engine/configuracion.rb +2 -5
  14. data/pg_engine/lib/pg_engine/engine.rb +8 -0
  15. data/pg_engine/lib/pg_engine/navigator.rb +67 -0
  16. data/pg_engine/lib/pg_engine.rb +1 -0
  17. data/pg_engine/spec/requests/active_storage_spec.rb +16 -0
  18. data/pg_engine/spec/requests/base_controller_requests_spec.rb +11 -0
  19. data/pg_engine/spec/{controllers/public/webhooks_controller_spec.rb → requests/public/webhooks_spec.rb} +13 -5
  20. data/pg_engine/spec/requests/users/switcher_spec.rb +1 -1
  21. data/pg_engine/spec/system/tenants_spec.rb +1 -1
  22. data/pg_layout/app/javascript/controllers/clear_timeout_controller.js +18 -5
  23. data/pg_layout/app/lib/navbar.rb +11 -6
  24. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +1 -1
  25. data/pg_layout/spec/lib/navbar_spec.rb +5 -1
  26. data/pg_rails/lib/version.rb +1 -1
  27. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b62210d098125764e407b10038d44a3e3fe91a52f6eff700fd83555dded8d194
4
- data.tar.gz: 4e9ac223dd652c00045af466a82af01ea07062f8968947286c304014ea3cb5ac
3
+ metadata.gz: 65d8b10e159a9378f670fed6dac91756cc87b27c66d3aa776803f010eff4fd34
4
+ data.tar.gz: e27911e05aa920930ef4a25a47f4a25d2d9dcd237b535e2b7ff35e1872464319
5
5
  SHA512:
6
- metadata.gz: b4cb69cca012bf23c8e1229353cd8b346150bc3029b9e45e995ce2f8ccb74d375c4019ce50ca894aaa9ef7cb5036781dcec219fa8ce108b64264e786d7467cda
7
- data.tar.gz: 074b884d3867fffc9a1835aa59ca9c69dc9b64c60042d49151bbc9b60bad72d12488964be429e4eb21626dcb251b6ae8ed4b61d58a40f62cc7d845a12118e72b
6
+ metadata.gz: b9a503a2eebcce6024f305a06629deebf419beca24b2a2fb9e5e8b8f0fc7d071beb8175eabaa2da25cbe428dc141001f92dfaca71acdbf6d218062c81042aa01
7
+ data.tar.gz: d978b0345f61e377aa98ac94d194cdf9342ef6affd812b57300390cfc82a3c34dc7a11d32c4603026f286da6e3a43fb88f558a46774b7fb2c6e2a460a612bb3b
@@ -20,7 +20,7 @@ module PgAssociable
20
20
  # porque de todos modos se pisaría en el create
21
21
  if !object.persisted? &&
22
22
  template.nested_record.present? &&
23
- object.send(template.nested_key) == (template.nested_record.id)
23
+ object.send(atributo) == (template.nested_record)
24
24
  options[:disabled] = true
25
25
  end
26
26
 
@@ -1,3 +1,4 @@
1
+ / TODO: usar ModalComponent?
1
2
  .modal[class="#{@klass} modal-#{@modal_id}" tabindex="-1" data-controller="modal"
2
3
  data-auto-show="true" data-remove-on-hide="false"
3
4
  data-modal-asociable-outlet=".asociable-#{@modal_id}"
@@ -7,6 +7,8 @@ module Admin
7
7
  include PgEngine::Resource
8
8
 
9
9
  self.clase_modelo = UserAccount
10
+ self.nested_class = Account
11
+ self.nested_key = :account_id
10
12
 
11
13
  before_action(only: :index) { authorize UserAccount }
12
14
 
@@ -76,6 +76,7 @@ module PgEngine
76
76
  rescue_from ActsAsTenant::Errors::NoTenantSet, with: :no_tenant_set
77
77
 
78
78
  rescue_from PgEngine::BadUserInput, with: :bad_user_input
79
+ rescue_from ActionController::UnknownFormat, with: :unknown_format
79
80
 
80
81
  rescue_from ActionController::InvalidAuthenticityToken,
81
82
  with: :invalid_authenticity_token
@@ -96,6 +97,10 @@ module PgEngine
96
97
  render_my_component(BadUserInputComponent.new(error_msg: error.message), :bad_request)
97
98
  end
98
99
 
100
+ def unknown_format(_error)
101
+ render_my_component(BadUserInputComponent.new(error_msg: 'Formato incorrecto'), :bad_request)
102
+ end
103
+
99
104
  def internal_error(error)
100
105
  pg_err error
101
106
 
@@ -144,7 +149,10 @@ module PgEngine
144
149
  navbar_expanded = cookies[:navbar_expand] != 'false'
145
150
  @navbar_opened_class = navbar_expanded ? 'opened' : ''
146
151
  @navbar_chevron_class = navbar_expanded ? 'bi-chevron-left' : 'bi-chevron-right'
147
- @navbar = Navbar.new(Current.user)
152
+ @navbar = Navbar.new
153
+ PgEngine.configuracion.navigators.each do |navigator|
154
+ navigator.configure(@navbar)
155
+ end
148
156
 
149
157
  if defined?(Rollbar) && Rollbar.configuration.enabled && Rails.application.credentials.rollbar.present?
150
158
  @rollbar_token = Rails.application.credentials.rollbar.access_token_client
@@ -9,6 +9,8 @@ module PgEngine
9
9
  # FIXME: make a POST route
10
10
  return head :bad_request unless dev_user_or_env?
11
11
 
12
+ Current.namespace = nil
13
+
12
14
  usuario = User.find(params[:id])
13
15
  if usuario.confirmed_at.present?
14
16
  sign_in(:user, usuario)
@@ -2,6 +2,12 @@ module Public
2
2
  class WebhooksController < PublicController
3
3
  skip_before_action :verify_authenticity_token
4
4
 
5
+ # TODO: mover a un namespace de webhooks
6
+ around_action :set_without_tenant
7
+ def set_without_tenant(&)
8
+ ActsAsTenant.without_tenant(&)
9
+ end
10
+
5
11
  before_action :verify_signature, only: :mailgun
6
12
 
7
13
  rescue_from StandardError do |err|
@@ -102,6 +102,12 @@ class User < ApplicationRecord
102
102
 
103
103
  class Error < PgEngine::Error; end
104
104
 
105
+ def user_accounts_without_tenant
106
+ ActsAsTenant.without_tenant do
107
+ user_accounts.to_a
108
+ end
109
+ end
110
+
105
111
  def default_account
106
112
  raise Error, 'El usuario debe tener cuenta' if accounts.empty?
107
113
 
@@ -25,3 +25,5 @@ table.table.table-borderless.table-sm.w-auto.mb-0.m-3
25
25
  tr
26
26
  th = t('attributes.discarded_at')
27
27
  td = @account.discarded_at
28
+
29
+ = embed_index @account, :user_accounts
@@ -1,4 +1,4 @@
1
- h1 Cambiar a otra cuenta
1
+ h1 ¿Qué cuenta te gustaría utilizar?
2
2
 
3
3
  / FIXME!: user_accounts add active column
4
4
  - if @user_accounts.empty?
@@ -0,0 +1,7 @@
1
+ ActiveSupport.on_load :action_controller do
2
+ if defined? UsersController
3
+ PgEngine.configurar do |config|
4
+ config.users_controller = UsersController
5
+ end
6
+ end
7
+ end
@@ -44,7 +44,9 @@ Rails.application.routes.draw do
44
44
  end
45
45
  end
46
46
  pg_resource(:users)
47
- pg_resource(:accounts)
47
+ pg_resource(:accounts) do
48
+ pg_resource(:user_accounts)
49
+ end
48
50
  pg_resource(:user_accounts)
49
51
  end
50
52
  if defined? ActiveAdmin
@@ -4,14 +4,11 @@
4
4
 
5
5
  module PgEngine
6
6
  class Configuracion
7
- attr_accessor :users_controller, :global_domains
7
+ attr_accessor :users_controller, :global_domains, :navigators
8
8
 
9
9
  def initialize
10
- if defined? UsersController
11
- @users_controller = UsersController
12
- end
13
-
14
10
  @global_domains = ['app.localhost.com', 'test.host', 'localhost']
11
+ @navigators = [PgEngine::Navigator.new]
15
12
  end
16
13
  end
17
14
  end
@@ -19,6 +19,14 @@ module PgEngine
19
19
  Dir.glob("#{overrides}/**/*.rb").each do |override|
20
20
  load override
21
21
  end
22
+
23
+ ActiveStorage::BaseController.class_eval do
24
+ around_action :set_without_tenant
25
+
26
+ def set_without_tenant(&)
27
+ ActsAsTenant.without_tenant(&)
28
+ end
29
+ end
22
30
  end
23
31
 
24
32
  initializer 'pg_engine.set_exceptions_app' do
@@ -0,0 +1,67 @@
1
+ module PgEngine
2
+ class Navigator
3
+ # rubocop:disable Metrics/MethodLength
4
+ def configure(navbar)
5
+ navbar.add_item('sidebar.not_signed_in', {
6
+ name: 'Crear una cuenta',
7
+ path: 'new_user_registration_path'
8
+ })
9
+ navbar.add_item('sidebar.not_signed_in', {
10
+ name: 'Iniciar sesión',
11
+ path: 'new_user_session_path'
12
+ })
13
+ navbar.add_item('sidebar.not_signed_in', {
14
+ name: 'Contacto',
15
+ path: 'new_public_mensaje_contacto_path'
16
+ })
17
+
18
+ # *****************************************************
19
+
20
+ navbar.add_item('sidebar.signed_in', {
21
+ name: 'Inicio',
22
+ path: 'users_root_path',
23
+ priority: 0
24
+ })
25
+ navbar.add_item('sidebar.signed_in', {
26
+ name: 'Mi perfil',
27
+ path: 'edit_user_registration_path',
28
+ policy: 'policy(Current.user).edit?'
29
+ })
30
+ navbar.add_item('sidebar.signed_in', {
31
+ name: 'Cerrar sesión',
32
+ path: 'destroy_user_session_path',
33
+ attributes: 'data-turbo-method="delete"'
34
+ })
35
+
36
+ # *****************************************************
37
+
38
+ return unless Current.user&.developer?
39
+
40
+ navbar.add_item('sidebar.signed_in', {
41
+ name: 'Eventos',
42
+ path: 'admin_eventos_path'
43
+ })
44
+ navbar.add_item('sidebar.signed_in', {
45
+ name: 'Emails',
46
+ path: 'admin_emails_path'
47
+ })
48
+ navbar.add_item('sidebar.signed_in', {
49
+ name: 'Email logs',
50
+ path: 'admin_email_logs_path'
51
+ })
52
+ navbar.add_item('sidebar.signed_in', {
53
+ name: 'Users',
54
+ path: 'admin_users_path'
55
+ })
56
+ navbar.add_item('sidebar.signed_in', {
57
+ name: 'Accounts',
58
+ path: 'admin_accounts_path'
59
+ })
60
+ navbar.add_item('sidebar.signed_in', {
61
+ name: 'User Accounts',
62
+ path: 'admin_user_accounts_path'
63
+ })
64
+ end
65
+ # rubocop:enable Metrics/MethodLength
66
+ end
67
+ end
@@ -4,6 +4,7 @@ require_relative 'pg_engine/engine'
4
4
  require_relative 'pg_engine/core_ext'
5
5
  require_relative 'pg_engine/error'
6
6
  require_relative 'pg_engine/configuracion'
7
+ require_relative 'pg_engine/navigator'
7
8
  require_relative 'pg_engine/email_observer'
8
9
  require_relative 'pg_engine/mailgun/log_sync'
9
10
  require_relative 'pg_engine/route_helpers'
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'representations controller' do
4
+ let(:file) { File.open("#{PgEngine::Engine.root}/spec/fixtures/test.pdf") }
5
+
6
+ it do
7
+ categoria = create :categoria_de_cosa
8
+ categoria.file.attach(io: file, filename: 'test.pdf')
9
+ path = polymorphic_url(categoria.file.preview(:thumb), only_path: true)
10
+ expect(path).to start_with '/rails/active_storage/representations/redirect/'
11
+ get path
12
+ ActiveStorage::Current.url_options = { host: 'www.example.com' }
13
+ expect(response).to have_http_status(:redirect)
14
+ expect(response.headers['location']).to include '/rails/active_storage/disk/'
15
+ end
16
+ end
@@ -76,4 +76,15 @@ describe 'Base requests' do
76
76
  include_examples 'manda el status correcto'
77
77
  end
78
78
  end
79
+
80
+ describe 'unknown format' do
81
+ subject do
82
+ get '/users/sign_in', headers: { accept: 'application/json' }
83
+ end
84
+
85
+ it 'returns bad request' do
86
+ subject
87
+ expect(response).to have_http_status(:bad_request)
88
+ end
89
+ end
79
90
  end
@@ -26,14 +26,18 @@ def build_body(log_id, signature, timestamp)
26
26
  JSON
27
27
  end
28
28
 
29
- describe Public::WebhooksController do
29
+ describe 'webhooks' do
30
30
  include ActiveSupport::Testing::TimeHelpers
31
31
 
32
- before { travel_to Time.zone.at(1_716_564_587) }
32
+ before do
33
+ travel_to Time.zone.at(1_716_564_587)
34
+ ActsAsTenant.current_tenant = nil
35
+ ActsAsTenant.test_tenant = nil
36
+ end
33
37
 
34
38
  describe '#mailgun' do
35
39
  subject do
36
- post :mailgun, body:, as: :json
40
+ post '/webhook/mailgun', params: body, headers: { 'content-type': 'application/json' }
37
41
  end
38
42
 
39
43
  let(:signature) { 'c524037907046276117758afae8a340e77a43a6e48eb35a9521426e7a3ff675b' }
@@ -114,11 +118,15 @@ describe Public::WebhooksController do
114
118
 
115
119
  context 'cuando ya se usó el token' do
116
120
  subject do
117
- post :mailgun, body: build_body('otro id', signature, timestamp), as: :json
121
+ post '/webhook/mailgun',
122
+ params: build_body('otro id', signature, timestamp),
123
+ headers: { 'content-type': 'application/json' }
118
124
  end
119
125
 
120
126
  before do
121
- post :mailgun, body: build_body(log_id, signature, timestamp), as: :json
127
+ post '/webhook/mailgun',
128
+ params: build_body(log_id, signature, timestamp),
129
+ headers: { 'content-type': 'application/json' }
122
130
  end
123
131
 
124
132
  it_behaves_like 'todo bien pero no guarda el log'
@@ -55,7 +55,7 @@ describe 'redirection' do
55
55
  get '/u/cosas'
56
56
  expect(response).to redirect_to users_account_switcher_path
57
57
  follow_redirect!
58
- expect(response.body).to include 'Cambiar a otra cuenta'
58
+ expect(response.body).to include '¿Qué cuenta te gustaría utilizar?'
59
59
  post "/u/switcher/#{other_user_account.to_param}"
60
60
  expect(response).to redirect_to(root_path)
61
61
  follow_redirect!
@@ -37,7 +37,7 @@ describe 'Tenants' do
37
37
  it 'shows the switcher' do
38
38
  visitar
39
39
 
40
- expect(page).to have_text 'Cambiar a otra cuenta'
40
+ expect(page).to have_text '¿Qué cuenta te gustaría utilizar?'
41
41
  end
42
42
 
43
43
  it 'switches to account' do
@@ -3,11 +3,24 @@ import { Controller } from '@hotwired/stimulus'
3
3
  // Connects to data-controller="clear-timeout"
4
4
  export default class extends Controller {
5
5
  connect () {
6
- this.element.dataset.timeoutId.split(',').forEach((el) => {
7
- const timeoutId = parseInt(el)
8
- clearTimeout(timeoutId)
9
- console.log(`clearedTimeout: ${timeoutId}`)
10
- })
6
+ if (this.element.dataset.timeoutId) {
7
+ this.element.dataset.timeoutId.split(',').forEach((el) => {
8
+ this.clear(el)
9
+ })
10
+ } else {
11
+ const headId = document.head.dataset.timeoutId
12
+ if (headId) {
13
+ headId.split(',').forEach((el) => {
14
+ this.clear(el)
15
+ })
16
+ }
17
+ }
11
18
  this.element.remove()
12
19
  }
20
+
21
+ clear (id) {
22
+ const timeoutId = parseInt(id)
23
+ clearTimeout(timeoutId)
24
+ console.log(`clearedTimeout: ${timeoutId}`)
25
+ }
13
26
  }
@@ -4,10 +4,9 @@ class Navbar
4
4
  attr_reader :extensiones
5
5
  attr_accessor :logo, :logo_xl, :logo_xl_url
6
6
 
7
- def initialize(user)
8
- @user = user
9
- @yaml_data = YAML.load_file("#{Rails.application.root}/config/pg_rails.yml")
10
- @yaml_data = ActiveSupport::HashWithIndifferentAccess.new(@yaml_data)
7
+ def initialize
8
+ @user = Current.user
9
+ @yaml_data = ActiveSupport::HashWithIndifferentAccess.new({})
11
10
  @extensiones = []
12
11
  end
13
12
 
@@ -31,15 +30,21 @@ class Navbar
31
30
  return [] if bar_data.blank?
32
31
 
33
32
  # rubocop:disable Security/Eval
33
+ # rubocop:disable Style/MultilineBlockChain:
34
+ orig_idx = 0
34
35
  bar_data.map do |item|
36
+ orig_idx += 1
35
37
  {
36
38
  title: item['name'],
37
39
  attributes: item['attributes']&.html_safe,
38
40
  path: eval(item['path']),
39
- show: item['policy'] ? eval(item['policy']) : true
41
+ show: item['policy'] ? eval(item['policy']) : true,
42
+ priority: item['priority'] || 999_999,
43
+ orig_idx:
40
44
  }
41
- end
45
+ end.sort_by { |a| [a[:priority], a[:orig_idx]] }
42
46
  # rubocop:enable Security/Eval
47
+ # rubocop:enable Style/MultilineBlockChain:
43
48
  end
44
49
 
45
50
  def all_children_hidden?(entry)
@@ -6,7 +6,7 @@
6
6
  <% if user_signed_in? %>
7
7
  <span class="d-inline-block px-3 text-end text-light"><%= Current.user %></span>
8
8
  <span class="d-block px-3 text-secondary">
9
- <% if Current.user.user_accounts.count > 1 %>
9
+ <% if Current.user.user_accounts_without_tenant.count > 1 %>
10
10
  <%= link_to ActsAsTenant.current_tenant, [:users, ActsAsTenant.current_tenant] if ActsAsTenant.current_tenant.present? %>
11
11
  <%= link_to users_account_switcher_path do %>
12
12
  <% if ActsAsTenant.current_tenant.present? %>
@@ -2,7 +2,11 @@ require 'rails_helper'
2
2
 
3
3
  describe Navbar do
4
4
  let(:user) { create :user }
5
- let(:instancia) { described_class.new(user) }
5
+ let(:instancia) { described_class.new }
6
+
7
+ before do
8
+ Current.user = user
9
+ end
6
10
 
7
11
  describe '#add_html' do
8
12
  subject { instancia.add_html(some_html) }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.5.6'
4
+ VERSION = '7.6.0'
5
5
  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.5.6
4
+ version: 7.6.0
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: 2024-09-19 00:00:00.000000000 Z
11
+ date: 2024-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -779,6 +779,7 @@ files:
779
779
  - pg_engine/app/views/public/mensaje_contactos/new.html.slim
780
780
  - pg_engine/app/views/users/account_switcher/list.html.slim
781
781
  - pg_engine/app/views/users/accounts/show.html.slim
782
+ - pg_engine/config/initializers/action_controller.rb
782
783
  - pg_engine/config/initializers/action_mailer.rb
783
784
  - pg_engine/config/initializers/active_admin.rb
784
785
  - pg_engine/config/initializers/acts_as_tenant.rb
@@ -822,6 +823,7 @@ files:
822
823
  - pg_engine/lib/pg_engine/engine.rb
823
824
  - pg_engine/lib/pg_engine/error.rb
824
825
  - pg_engine/lib/pg_engine/mailgun/log_sync.rb
826
+ - pg_engine/lib/pg_engine/navigator.rb
825
827
  - pg_engine/lib/pg_engine/route_helpers.rb
826
828
  - pg_engine/lib/pg_engine/utils/check_invalid_records.rb
827
829
  - pg_engine/lib/pg_engine/utils/pdf_preview_generator.rb
@@ -847,7 +849,6 @@ files:
847
849
  - pg_engine/spec/controllers/devise/sessions_controller_spec.rb
848
850
  - pg_engine/spec/controllers/pg_engine/base_controller_spec.rb
849
851
  - pg_engine/spec/controllers/public/mensaje_contactos_controller_spec.rb
850
- - pg_engine/spec/controllers/public/webhooks_controller_spec.rb
851
852
  - pg_engine/spec/controllers/users/confirmations_controller_spec.rb
852
853
  - pg_engine/spec/decorators/email_decorator_spec.rb
853
854
  - pg_engine/spec/factories/accounts.rb
@@ -875,10 +876,12 @@ files:
875
876
  - pg_engine/spec/models/user_spec.rb
876
877
  - pg_engine/spec/overrides/audited_audit_spec.rb
877
878
  - pg_engine/spec/pg_engine/pdf_preview_generator_spec.rb
879
+ - pg_engine/spec/requests/active_storage_spec.rb
878
880
  - pg_engine/spec/requests/admin/eventos_spec.rb
879
881
  - pg_engine/spec/requests/base_controller_requests_spec.rb
880
882
  - pg_engine/spec/requests/current_attributes_spec.rb
881
883
  - pg_engine/spec/requests/devise_spec.rb
884
+ - pg_engine/spec/requests/public/webhooks_spec.rb
882
885
  - pg_engine/spec/requests/users/accounts_spec.rb
883
886
  - pg_engine/spec/requests/users/base_controller_spec.rb
884
887
  - pg_engine/spec/requests/users/date_jumper_spec.rb