pg_rails 7.5.1 → 7.5.3

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/app/helpers/pg_associable/helpers.rb +19 -2
  3. data/pg_associable/app/javascript/asociable_controller.tsx +1 -1
  4. data/pg_associable/app/javascript/modal_controller.js +8 -3
  5. data/pg_associable/spec/pg_associable/helpers_spec.rb +40 -2
  6. data/pg_engine/app/controllers/admin/user_accounts_controller.rb +5 -1
  7. data/pg_engine/app/controllers/admin/users_controller.rb +0 -17
  8. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +1 -3
  9. data/pg_engine/app/controllers/pg_engine/base_admin_controller.rb +19 -0
  10. data/pg_engine/app/controllers/pg_engine/base_controller.rb +4 -4
  11. data/pg_engine/app/controllers/pg_engine/base_public_controller.rb +17 -0
  12. data/pg_engine/app/controllers/pg_engine/base_users_controller.rb +17 -0
  13. data/pg_engine/app/controllers/users/account_switcher_controller.rb +3 -0
  14. data/pg_engine/app/controllers/users/accounts_controller.rb +35 -0
  15. data/pg_engine/app/helpers/pg_engine/flash_helper.rb +1 -2
  16. data/pg_engine/app/models/account.rb +5 -0
  17. data/pg_engine/app/models/current.rb +2 -0
  18. data/pg_engine/app/models/email.rb +4 -1
  19. data/pg_engine/app/models/email_log.rb +2 -1
  20. data/pg_engine/app/models/pg_engine/base_record.rb +3 -1
  21. data/pg_engine/app/models/user.rb +16 -4
  22. data/pg_engine/app/models/user_account.rb +2 -2
  23. data/pg_engine/app/overrides/audited_audit.rb +15 -0
  24. data/pg_engine/app/policies/account_policy.rb +4 -0
  25. data/pg_engine/app/views/admin/user_accounts/_form.html.slim +2 -2
  26. data/pg_engine/app/views/admin/users/show.html.slim +1 -1
  27. data/pg_engine/app/views/users/account_switcher/list.html.slim +18 -4
  28. data/pg_engine/app/views/users/accounts/show.html.slim +13 -0
  29. data/pg_engine/config/routes.rb +9 -1
  30. data/pg_engine/db/seeds.rb +13 -11
  31. data/pg_engine/lib/pg_engine/configuracion.rb +0 -2
  32. data/pg_engine/spec/controllers/admin/email_logs_controller_spec.rb +3 -1
  33. data/pg_engine/spec/models/user_spec.rb +7 -0
  34. data/pg_engine/spec/overrides/audited_audit_spec.rb +16 -0
  35. data/pg_engine/spec/requests/users/accounts_spec.rb +22 -0
  36. data/pg_engine/spec/requests/users/switcher_spec.rb +9 -1
  37. data/pg_engine/spec/system/breadcrumbs_spec.rb +0 -1
  38. data/pg_engine/spec/system/date_selector_spec.rb +0 -1
  39. data/pg_engine/spec/system/login_spec.rb +1 -1
  40. data/pg_engine/spec/system/modal_windows_spec.rb +0 -1
  41. data/pg_engine/spec/system/tenants_spec.rb +2 -1
  42. data/pg_layout/app/javascript/controllers/popover_toggler_controller.js +5 -1
  43. data/pg_layout/app/javascript/controllers/tooltip_controller.js +5 -1
  44. data/pg_layout/app/views/devise/sessions/new.html.erb +1 -1
  45. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +13 -7
  46. data/pg_rails/lib/version.rb +1 -1
  47. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +1 -0
  48. data/pg_scaffold/spec/generators_spec.rb +4 -4
  49. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99e5df3ed137be9ec63699ccfd381f75f63cf1a7a272c36e49177147be1ad958
4
- data.tar.gz: f95e10f28d40ab3c513e0a9e680baf268fe500f3a740cbde18fe3754b4f6941e
3
+ metadata.gz: b312261e863e04fcc457b8b773531325d1c69f9b4ef0ca1269b39853f737844a
4
+ data.tar.gz: 641bbe1b7b128e67ec7ffb874765dfeae35aac6dadf917fcbe4367b3c98939cb
5
5
  SHA512:
6
- metadata.gz: 69842b1daf20fce9bfb7a62196d44a83e5b16d6f18198fdf7afcaa229e7ce86f51383106e8d4158259af3eebc9190bc26724cd39cb00afb837902c34e45fe7ae
7
- data.tar.gz: d27a734ecdd58f0d552b76a2fbc4225341572b24ba467b398be5e93f489eac4d60a116333a828b3382be9791f830aea715e506f4fda01a923f6d5c00ee41a16f
6
+ metadata.gz: 66f4093830e6a889cf66cfc39e6b0bfb015e93ad8e48c0e33a2c3292363f7511dbc1062b7b9993d0e0e2277ae49986c9eb0390572d63a2100a6057fb6b20e213
7
+ data.tar.gz: dc1b35305080b8bd01dbafeea7453bcf8f7bd85fe4609ee7657f18985402b86f755c170b39ce28b55e5c3939a2f5659f57e9ba3ee8336877ef8c18712fcf01be
@@ -3,7 +3,7 @@ module PgAssociable
3
3
  MAX_RESULTS = 8
4
4
 
5
5
  def pg_respond_abrir_modal
6
- src = @clase_modelo.new.decorate.new_object_url
6
+ src = clase_modelo.new.decorate.new_object_url
7
7
  content = ModalContentComponent.new(src:).render_in(view_context)
8
8
  modal = AsociableModalComponent.new(modal_id: params[:id]).with_content(content)
9
9
  render turbo_stream: turbo_stream.append_all('body', modal)
@@ -14,10 +14,27 @@ module PgAssociable
14
14
  resultados_prefix = 'resultados-inline'
15
15
  query = params[:query]
16
16
  timeout_id = params[:timeout_id]
17
- @collection = policy_scope(@clase_modelo).kept.query(query).limit(MAX_RESULTS)
17
+ @collection = search_in_scope(query)
18
18
  render turbo_stream:
19
19
  turbo_stream.update("#{resultados_prefix}-#{params[:id]}",
20
20
  partial:, locals: { collection: @collection, query:, timeout_id: })
21
21
  end
22
+
23
+ def search_in_scope(query)
24
+ scope = policy_scope(clase_modelo).kept
25
+
26
+ if clase_modelo.ransackable_attributes.include?('search')
27
+ scope.ransack(search_cont: query).result
28
+ else
29
+ Rails.logger.warn("WARNING: #{clase_modelo} should implement a 'search' ransacker")
30
+
31
+ if scope.respond_to?(:query)
32
+ Rails.logger.warn("DEPRECATED WARNING: #{clase_modelo}#query is deprecated in favor of 'search' ransacker")
33
+ scope.query(query)
34
+ else
35
+ scope.where(id: query)
36
+ end
37
+ end
38
+ end
22
39
  end
23
40
  end
@@ -66,7 +66,7 @@ export default class extends Controller {
66
66
  }
67
67
  const doSearchBounce = debounce((force) => {
68
68
  this.doSearch(force)
69
- }, 900)
69
+ }, 200)
70
70
 
71
71
  this.input.addEventListener('blur', () => {
72
72
  this.input.placeholder = this.originalPlaceholder
@@ -105,9 +105,14 @@ export default class extends Controller {
105
105
  // this.modalPuntero.hide()
106
106
  // pero tiraba a veces error:
107
107
  // TypeError: can't convert null to object, _isWithActiveTrigger
108
- document.querySelectorAll('.modal-backdrop').forEach((el) => {
109
- el.remove()
110
- })
108
+ // document.querySelectorAll('.modal-backdrop').forEach((el) => {
109
+ // el.remove()
110
+ // })
111
+ // UPDATE: 11-09-2024, vuelvo a poner el hide, porque en parece que
112
+ // el problema de _isWithActiveTrigger viene por el lado de los
113
+ // tooltips:
114
+ // https://github.com/twbs/bootstrap/issues/37474
115
+ this.modalPuntero.hide()
111
116
  document.dispatchEvent(new Event('hidden.bs.modal'))
112
117
  this.modalPuntero.dispose()
113
118
  }
@@ -1,7 +1,27 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe PgAssociable::Helpers do
4
- describe '#pg_respond_buscar' do
4
+ # DEPRECATED
5
+ describe '#pg_respond_buscar with query scope' do
6
+ let(:ctrl) do
7
+ Admin::CategoriaDeCosasController.new
8
+ end
9
+ let!(:categoria_de_cosa) { create :categoria_de_cosa }
10
+
11
+ before do
12
+ Current.user = create :user, :developer
13
+ allow(ctrl).to receive_messages(params: { id: 123, query: categoria_de_cosa.nombre })
14
+ allow(ctrl).to receive(:render)
15
+ end
16
+
17
+ it do
18
+ ctrl.pg_respond_buscar
19
+ categoria_de_cosas = ctrl.instance_variable_get(:@collection)
20
+ expect(categoria_de_cosas).to eq [categoria_de_cosa]
21
+ end
22
+ end
23
+
24
+ describe '#pg_respond_buscar with id' do
5
25
  let(:ctrl) do
6
26
  Admin::CosasController.new
7
27
  end
@@ -11,7 +31,6 @@ describe PgAssociable::Helpers do
11
31
  Current.user = create :user, :developer
12
32
  allow(ctrl).to receive_messages(params: { id: 123, query: cosa.id })
13
33
  allow(ctrl).to receive(:render)
14
- ctrl.instance_variable_set(:@clase_modelo, Cosa)
15
34
  end
16
35
 
17
36
  it do
@@ -20,4 +39,23 @@ describe PgAssociable::Helpers do
20
39
  expect(cosas).to eq [cosa]
21
40
  end
22
41
  end
42
+
43
+ describe '#pg_respond_buscar with ransack' do
44
+ let(:ctrl) do
45
+ Admin::AccountsController.new
46
+ end
47
+ let!(:account) { create :account }
48
+
49
+ before do
50
+ Current.user = create :user, :developer
51
+ allow(ctrl).to receive_messages(params: { id: 123, query: account.nombre })
52
+ allow(ctrl).to receive(:render)
53
+ end
54
+
55
+ it do
56
+ ctrl.pg_respond_buscar
57
+ accounts = ctrl.instance_variable_get(:@collection)
58
+ expect(accounts).to eq [account]
59
+ end
60
+ end
23
61
  end
@@ -15,7 +15,11 @@ module Admin
15
15
  private
16
16
 
17
17
  def atributos_permitidos
18
- %i[user_id account_id profiles]
18
+ [
19
+ :user_id,
20
+ :account_id,
21
+ { profiles: [] }
22
+ ]
19
23
  end
20
24
 
21
25
  def atributos_para_buscar
@@ -28,23 +28,6 @@ module Admin
28
28
  pg_respond_update
29
29
  end
30
30
 
31
- # TODO: sacar este método a otro lado, que no sea AdminController
32
- skip_before_action :authenticate_user!, only: [:login_as]
33
-
34
- # :nocov:
35
- def login_as
36
- return unless dev_user_or_env?
37
-
38
- usuario = User.find(params[:id])
39
- if usuario.confirmed_at.present?
40
- sign_in(:user, usuario)
41
- redirect_to after_sign_in_path_for(usuario)
42
- else
43
- go_back('No está confirmado')
44
- end
45
- end
46
- # :nocov:
47
-
48
31
  private
49
32
 
50
33
  def atributos_permitidos
@@ -418,9 +418,7 @@ module PgEngine
418
418
  instancia_modelo.assign_attributes(modelo_params) if action_name.in? %w[update]
419
419
  end
420
420
 
421
- # FIXME: estaría bueno delegar directamente a pundit, pero habría que
422
- # arreglar tema policies
423
- Current.user&.developer? || authorize(instancia_modelo)
421
+ authorize(instancia_modelo)
424
422
 
425
423
  # TODO: problema en create y update cuando falla la validacion
426
424
  # Reproducir el error antes de arreglarlo
@@ -0,0 +1,19 @@
1
+ module PgEngine
2
+ class BaseAdminController < ApplicationController
3
+ include PgEngine::RequireSignIn
4
+
5
+ before_action do
6
+ raise Pundit::NotAuthorizedError unless Current.user&.developer?
7
+
8
+ Current.namespace = :admin
9
+
10
+ add_breadcrumb 'Admin'
11
+ end
12
+
13
+ around_action :set_without_tenant
14
+
15
+ def set_without_tenant(&)
16
+ ActsAsTenant.without_tenant(&)
17
+ end
18
+ end
19
+ end
@@ -25,15 +25,15 @@ module PgEngine
25
25
  throw :warden, scope: :user, message: :invalid
26
26
  end
27
27
 
28
+ @current_tenant_set_by_domain_or_subdomain = true
28
29
  else
29
- account = if session['current_user_account'].present?
30
- UserAccount.where(id: session['current_user_account']).first&.account
31
- elsif Current.user.user_accounts.count == 1
30
+ account = if Current.user.user_accounts.count == 1
32
31
  Current.user.user_accounts.first.account
32
+ elsif session['current_user_account'].present?
33
+ UserAccount.where(id: session['current_user_account']).first&.account
33
34
  end
34
35
  set_current_tenant(account)
35
36
  end
36
- Current.account = ActsAsTenant.current_tenant
37
37
  end
38
38
  end
39
39
  # rubocop:enable Rails/ApplicationController
@@ -0,0 +1,17 @@
1
+ module PgEngine
2
+ class BasePublicController < ApplicationController
3
+ # :nocov:
4
+ def login_as
5
+ return head :bad_request unless dev_user_or_env?
6
+
7
+ usuario = User.find(params[:id])
8
+ if usuario.confirmed_at.present?
9
+ sign_in(:user, usuario)
10
+ redirect_to after_sign_in_path_for(usuario)
11
+ else
12
+ go_back('No está confirmado')
13
+ end
14
+ end
15
+ # :nocov:
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module PgEngine
2
+ class BaseUsersController < ApplicationController
3
+ include PgEngine::RequireSignIn
4
+ include PgEngine::RequireTenantSet
5
+
6
+ before_action do
7
+ # FIXME: requisito que esto esté seteado
8
+ Current.namespace = :users
9
+
10
+ add_breadcrumb 'Inicio', :users_root_path unless using_modal2? || frame_embedded?
11
+ end
12
+
13
+ def home
14
+ render html: '<h1>Inicio</h1>'.html_safe, layout: 'pg_layout/centered'
15
+ end
16
+ end
17
+ end
@@ -1,11 +1,14 @@
1
1
  module Users
2
2
  class AccountSwitcherController < PgEngine.config.users_controller
3
3
  rescue_from ActsAsTenant::Errors::NoTenantSet, with: :internal_error
4
+ skip_before_action :require_tenant_set
4
5
 
5
6
  before_action do
6
7
  @no_main_frame = true
7
8
  end
8
9
 
10
+ layout 'pg_layout/centered'
11
+
9
12
  def list
10
13
  @user_accounts = Current.user.user_accounts
11
14
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # generado con pg_rails
4
+
5
+ module Users
6
+ class AccountsController < UsersController
7
+ include PgEngine::Resource
8
+
9
+ self.clase_modelo = Account
10
+ add_breadcrumb 'Cuentas'
11
+ self.skip_default_breadcrumb = true
12
+
13
+ before_action(only: :index) { authorize Account }
14
+
15
+ before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
16
+
17
+ # private
18
+
19
+ # def atributos_permitidos
20
+ # %i[plan nombre domain subdomain]
21
+ # end
22
+
23
+ # def atributos_para_buscar
24
+ # atributos_permitidos
25
+ # end
26
+
27
+ # def atributos_para_listar
28
+ # atributos_permitidos
29
+ # end
30
+
31
+ # def atributos_para_mostrar
32
+ # atributos_permitidos
33
+ # end
34
+ end
35
+ end
@@ -9,9 +9,8 @@ module PgEngine
9
9
  end
10
10
 
11
11
  def render_turbo_stream_title
12
- title = [breadcrumbs.last&.name, I18n.t('app_name')].compact.join(' - ')
12
+ title = [breadcrumbs.last&.name, ActsAsTenant.current_tenant, I18n.t('app_name')].compact.join(' - ')
13
13
  turbo_stream.update_all 'title', title
14
- # rubocop:enable Rails/SkipsModelValidations
15
14
  end
16
15
  end
17
16
  end
@@ -22,6 +22,7 @@
22
22
  class Account < ApplicationRecord
23
23
  audited
24
24
  include Discard::Model
25
+ include Hashid::Rails
25
26
 
26
27
  has_many :user_accounts
27
28
  has_many :users, through: :user_accounts
@@ -33,6 +34,10 @@ class Account < ApplicationRecord
33
34
 
34
35
  validates :plan, :nombre, presence: true
35
36
 
37
+ ransacker :search do |parent|
38
+ parent.table[:nombre]
39
+ end
40
+
36
41
  def to_s
37
42
  nombre
38
43
  end
@@ -9,4 +9,6 @@ class Current < ActiveSupport::CurrentAttributes
9
9
  #
10
10
  # Time.zone = user.time_zone
11
11
  # end
12
+
13
+ deprecate :account, deprecator: PgEngine.deprecator
12
14
  end
@@ -46,7 +46,10 @@ class Email < ApplicationRecord
46
46
 
47
47
  has_one_attached :encoded_eml
48
48
 
49
- belongs_to :associated, polymorphic: true, optional: true
49
+ acts_as_tenant :account, optional: true
50
+
51
+ tenantable_belongs_to :associated, polymorphic: true, optional: true,
52
+ assign_tenant_from_associated: true
50
53
 
51
54
  belongs_to :creado_por, optional: true, class_name: 'User'
52
55
  belongs_to :actualizado_por, optional: true, class_name: 'User'
@@ -23,7 +23,8 @@
23
23
  class EmailLog < ApplicationRecord
24
24
  audited
25
25
 
26
- belongs_to :email, optional: true
26
+ acts_as_tenant :account, optional: true
27
+ tenantable_belongs_to :email, optional: true, assign_tenant_from_associated: true
27
28
 
28
29
  after_create_commit do
29
30
  email.update_status! if email.present?
@@ -19,7 +19,9 @@ module PgEngine
19
19
  attr_accessor :default_modal
20
20
  end
21
21
 
22
- scope :query, ->(param) { param.present? ? where(id: param) : all }
22
+ # ransacker :search do |parent|
23
+ # parent.table[:nombre]
24
+ # end
23
25
 
24
26
  def self.ransackable_associations(_auth_object = nil)
25
27
  authorizable_ransackable_associations
@@ -76,16 +76,16 @@ class User < ApplicationRecord
76
76
  end
77
77
 
78
78
  def create_account
79
- # rubocop:disable Rails/Presence
80
79
  account =
81
80
  if ActsAsTenant.current_tenant.present?
82
- # FIXME!: raise PgEngine::Error unless invited
81
+ # :nocov:
82
+ raise PgEngine::Error, 'user not invited' unless Rails.env.test?
83
+ # :nocov:
84
+
83
85
  ActsAsTenant.current_tenant
84
86
  else
85
87
  Account.create(nombre: email, plan: 0)
86
88
  end
87
- # rubocop:enable Rails/Presence
88
-
89
89
  ua = user_accounts.create(account:)
90
90
 
91
91
  raise(Error, 'no se pudo crear la cuenta') unless ua.persisted?
@@ -99,8 +99,20 @@ class User < ApplicationRecord
99
99
  # true
100
100
  # end
101
101
 
102
+ # DEPRECATED
102
103
  scope :query, ->(param) { where('email ILIKE ?', "%#{param}%") }
103
104
 
105
+ ransacker :search do |parent|
106
+ Arel::Nodes::InfixOperation.new(
107
+ '||',
108
+ Arel::Nodes::InfixOperation.new(
109
+ '||',
110
+ parent.table[:nombre], parent.table[:apellido]
111
+ ),
112
+ parent.table[:email]
113
+ )
114
+ end
115
+
104
116
  def to_s
105
117
  nombre_completo
106
118
  end
@@ -21,6 +21,7 @@
21
21
  # fk_rails_... (user_id => users.id)
22
22
  #
23
23
 
24
+ # FIXME: add column active?
24
25
  class UserAccount < ApplicationRecord
25
26
  audited
26
27
  include Hashid::Rails
@@ -33,7 +34,6 @@ class UserAccount < ApplicationRecord
33
34
 
34
35
  enumerize :profiles, in: {
35
36
  admin: 1,
36
- dueño: 2,
37
- invitado: 3
37
+ editor: 2
38
38
  }, multiple: true
39
39
  end
@@ -0,0 +1,15 @@
1
+ Audited::Audit.class_eval do
2
+ before_validation do
3
+ if account_id.nil?
4
+ if auditable.respond_to?(:account_id)
5
+ self.account_id = auditable.account_id
6
+ elsif auditable_type == 'Account'
7
+ self.account_id = auditable.id
8
+ elsif ActsAsTenant.current_tenant.present?
9
+ self.account = ActsAsTenant.current_tenant
10
+ end
11
+ end
12
+ end
13
+
14
+ belongs_to :account, optional: true
15
+ end
@@ -28,4 +28,8 @@ class AccountPolicy < ApplicationPolicy
28
28
  # def acceso_total?
29
29
  # user.developer?
30
30
  # end
31
+ def base_access_to_record?
32
+ ActsAsTenant.unscoped? ||
33
+ record.user_accounts.pluck(:user_id).include?(user.id)
34
+ end
31
35
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  div style="max-width: 22em"
4
4
  = pg_form_for(@user_account || object) do |f|
5
- = f.pg_associable :user
6
- = f.pg_associable :account
5
+ = f.pg_associable :user, preload: 10
6
+ = f.pg_associable :account, preload: 5
7
7
  = f.input :profiles
8
8
  .mt-2
9
9
  = f.button :submit
@@ -5,7 +5,7 @@
5
5
  .ms-1
6
6
  = @user.edit_link
7
7
  .ms-1
8
- = link_to admin_login_as_path(id: @user.id), class: 'btn btn-light btn-sm' do
8
+ = link_to login_as_path(id: @user.id), class: 'btn btn-light btn-sm' do
9
9
  span.bi.bi-arrow-right
10
10
  | Login as
11
11
 
@@ -1,6 +1,20 @@
1
- h1 Switcher
1
+ h1 Cambiar a otra cuenta
2
2
 
3
- ul
3
+ - if @current_tenant_set_by_domain_or_subdomain
4
+ p Estás en el dominio de #{ActsAsTenant.current_tenant} (#{request.host})
5
+ p
6
+ | Para cambiar de cuenta vas a tener que iniciar sesión en el dominio
7
+ |< de Bien o de la cuenta específica a la que quieras cambiar
8
+
9
+ ul.m-auto.list-group style="max-width: 20em"
4
10
  - @user_accounts.each do |user_account|
5
- li = link_to user_account.account, users_account_switch_path(user_account),
6
- 'data-turbo-method': :post
11
+ li.list-group-item
12
+ - if @current_tenant_set_by_domain_or_subdomain
13
+ = user_account.account
14
+ - elsif user_account.account == ActsAsTenant.current_tenant
15
+ b
16
+ = user_account.account
17
+ | (Actual)
18
+ - else
19
+ = link_to user_account.account, users_account_switch_path(user_account),
20
+ 'data-turbo-method': :post
@@ -0,0 +1,13 @@
1
+ h1
2
+ |> Usuarios de la cuenta:
3
+ = @account
4
+
5
+ div style="max-width: 30em"
6
+ table.table.table-sm
7
+ tr
8
+ th Nombre
9
+ th Roles
10
+ - @account.user_accounts.each do |user_account|
11
+ tr
12
+ td = user_account.user
13
+ td = user_account.profiles.texts.join(', ')
@@ -13,6 +13,9 @@ Rails.application.routes.draw do
13
13
  pg_resource(:mensaje_contactos, only: [:new, :create], path: 'contacto')
14
14
  post 'webhook/mailgun', to: 'webhooks#mailgun'
15
15
  end
16
+
17
+ get 'login_as', to: 'public#login_as'
18
+
16
19
  devise_for :users, controllers: {
17
20
  confirmations: 'users/confirmations',
18
21
  registrations: 'users/registrations'
@@ -25,7 +28,13 @@ Rails.application.routes.draw do
25
28
  get '', action: 'list', as: 'account_switcher'
26
29
  post ':user_account_id', action: 'switch', as: 'account_switch'
27
30
  end
31
+
32
+ pg_resource(:accounts, path: 'cuentas', only: [:show])
33
+ # get 'account', to: 'accounts#show'
28
34
  end
35
+
36
+ get '/u', to: 'users#home', as: :users_root
37
+
29
38
  namespace :admin, path: 'a' do
30
39
  pg_resource(:emails)
31
40
  pg_resource(:eventos)
@@ -37,7 +46,6 @@ Rails.application.routes.draw do
37
46
  pg_resource(:users)
38
47
  pg_resource(:accounts)
39
48
  pg_resource(:user_accounts)
40
- get 'login_as', to: 'users#login_as'
41
49
  end
42
50
  if defined? ActiveAdmin
43
51
  ActiveAdmin.routes(self)
@@ -1,15 +1,17 @@
1
- ActsAsTenant.without_tenant do
2
- DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
1
+ DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
3
2
 
4
3
 
5
- bien = FactoryBot.create :account, nombre: 'Bien', subdomain: 'bien'
6
- uno = FactoryBot.create :user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
7
- confirmed_at: Time.now, developer: true, orphan: true
8
- bien.users << uno
4
+ bien = FactoryBot.create(:account, nombre: 'Bien', subdomain: 'bien')
5
+ rosso = FactoryBot.create(:user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
6
+ confirmed_at: Time.now, developer: true, orphan: true)
9
7
 
10
- mal = FactoryBot.create :account, nombre: 'Mal', subdomain: 'mal'
11
- otro = FactoryBot.create :user, email: 'mal@gmail.com', nombre: 'Mal', apellido: 'Mal', password: 'admin123',
12
- confirmed_at: Time.now, developer: true, orphan: true
8
+ bien.user_accounts.create(user: rosso, profiles: [:admin])
13
9
 
14
- mal.users << otro
15
- end
10
+ racionalismo = FactoryBot.create(:account, nombre: 'Racionalismo', subdomain: 'racionalismo')
11
+ baruch = FactoryBot.create(:user, email: 'baruch@bien.com', nombre: 'Baruch', apellido: 'Spinoza', password: 'admin123',
12
+ confirmed_at: Time.now, orphan: true)
13
+ rené = FactoryBot.create(:user, email: 'rene@bien.com', nombre: 'René', apellido: 'Descartes', password: 'admin123',
14
+ confirmed_at: Time.now, orphan: true)
15
+
16
+ racionalismo.user_accounts.create(user: baruch, profiles: [:admin])
17
+ racionalismo.user_accounts.create(user: rené, profiles: [:editor])
@@ -9,8 +9,6 @@ module PgEngine
9
9
  def initialize
10
10
  if defined? UsersController
11
11
  @users_controller = UsersController
12
- elsif defined? FrontendController
13
- @users_controller = FrontendController
14
12
  end
15
13
 
16
14
  @global_domains = ['app.localhost.com', 'test.host', 'localhost']
@@ -33,9 +33,11 @@ RSpec.describe Admin::EmailLogsController do
33
33
  # EmailLog. As you add validations to EmailLog, be sure to
34
34
  # adjust the attributes here as well.
35
35
  let(:valid_attributes) do
36
- attributes_for(:email_log)
36
+ attributes_for(:email_log).merge(email_id: email.id)
37
37
  end
38
38
 
39
+ let(:email) { create :email }
40
+
39
41
  let(:logged_user) { create :user, :developer }
40
42
 
41
43
  before do
@@ -56,4 +56,11 @@ RSpec.describe User do
56
56
  expect(user).not_to be_persisted
57
57
  end
58
58
  end
59
+
60
+ describe 'search ransacker' do
61
+ it 'searchs' do
62
+ results = described_class.ransack(search_cont: user.nombre).result.to_a
63
+ expect(results).to eq [user]
64
+ end
65
+ end
59
66
  end
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'Audited::Audit' do
4
+ subject do
5
+ create :categoria_de_cosa
6
+ end
7
+
8
+ it 'creates the audits' do
9
+ expect { subject }.to change(Audited::Audit, :count).by(1)
10
+ end
11
+
12
+ it 'assigns the tenant to audits' do
13
+ subject
14
+ expect(Audited::Audit.last.account).to eq ActsAsTenant.current_tenant
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'Users::AccountsController' do
4
+ let(:account) { ActsAsTenant.current_tenant }
5
+ let(:user) { create :user }
6
+
7
+ before do
8
+ sign_in user
9
+ end
10
+
11
+ it 'shows the owned account' do
12
+ get "/u/cuentas/#{account.to_param}"
13
+ expect(response).to have_http_status(:ok)
14
+ end
15
+
16
+ it 'denies foreign account' do
17
+ other_account = create :account
18
+ get "/u/cuentas/#{other_account.to_param}"
19
+ expect(response).to have_http_status(:redirect)
20
+ expect(flash[:alert]).to eq 'Acceso no autorizado'
21
+ end
22
+ end
@@ -30,15 +30,23 @@ describe 'redirection' do
30
30
  let!(:other_account) { create :account }
31
31
  let!(:other_user_account) { logged_user.user_accounts.create(account: other_account) }
32
32
 
33
+ before do
34
+ third_account = create :account
35
+ logged_user.user_accounts.create(account: third_account)
36
+ end
37
+
33
38
  it 'redirects to switcher' do
34
39
  get '/u/cosas'
35
40
  expect(response).to redirect_to users_account_switcher_path
36
41
  follow_redirect!
37
- expect(response.body).to include 'Switcher'
42
+ expect(response.body).to include 'Cambiar a otra cuenta'
38
43
  post "/u/switcher/#{other_user_account.to_param}"
39
44
  expect(response).to redirect_to(root_path)
40
45
  follow_redirect!
46
+ get '/u/cosas'
47
+ expect(response).to have_http_status(:ok)
41
48
  expect(response.body).to include other_account.to_s
49
+ expect(response.body).to include 'No hay cosos que mostrar'
42
50
  other_user_account.destroy!
43
51
  get '/'
44
52
  expect(response).to redirect_to users_account_switcher_path
@@ -15,7 +15,6 @@ describe 'Breadcrumbs' do
15
15
  let(:path) { "/a/cosas/#{cosa.id}" }
16
16
  let(:cosa) { create :cosa }
17
17
  let(:logged_user) { create :user, :developer }
18
- let(:account) { logged_user.current_account }
19
18
 
20
19
  before do
21
20
  login_as logged_user
@@ -13,7 +13,6 @@ describe 'Date selector' do
13
13
  end
14
14
 
15
15
  let(:logged_user) { create :user, :developer }
16
- let(:account) { logged_user.current_account }
17
16
  let(:categoria_de_cosa) { create :categoria_de_cosa, fecha: }
18
17
  let(:fecha) { Date.new(2024, 8, 12) }
19
18
 
@@ -5,7 +5,7 @@ require 'rails_helper'
5
5
  describe 'Sign in' do
6
6
  shared_examples 'sign_in' do
7
7
  subject do
8
- visit '/users/sign_in'
8
+ visit '/u/categoria_de_cosas'
9
9
  fill_in 'user_email', with: user.email
10
10
  fill_in 'user_password', with: password
11
11
  find('input[type=submit]').click
@@ -13,7 +13,6 @@ describe 'Modal windows' do
13
13
  end
14
14
 
15
15
  let(:logged_user) { create :user, :developer }
16
- let(:account) { logged_user.current_account }
17
16
  let!(:categoria_de_cosa) { create :categoria_de_cosa }
18
17
 
19
18
  before do
@@ -35,13 +35,14 @@ describe 'Tenants' do
35
35
  it 'shows the switcher' do
36
36
  visitar
37
37
 
38
- expect(page).to have_text 'Switcher'
38
+ expect(page).to have_text 'Cambiar a otra cuenta'
39
39
  end
40
40
 
41
41
  it 'switches to account' do
42
42
  visitar
43
43
 
44
44
  click_on other_account.to_s
45
+ visit '/u/categoria_de_cosas'
45
46
  expect(page).to have_text 'No hay categorías de cosas que mostrar'
46
47
  end
47
48
 
@@ -24,7 +24,11 @@ export default class extends Controller {
24
24
 
25
25
  disconnect () {
26
26
  if (this.popover) {
27
- this.popover.dispose()
27
+ // setTimeout because of:
28
+ // https://github.com/twbs/bootstrap/issues/37474
29
+ setTimeout(() => {
30
+ this.popover.dispose()
31
+ }, 300)
28
32
  }
29
33
  }
30
34
  }
@@ -30,7 +30,11 @@ export default class extends Controller {
30
30
 
31
31
  disconnect () {
32
32
  if (this.tooltip) {
33
- this.tooltip.dispose()
33
+ // setTimeout because of:
34
+ // https://github.com/twbs/bootstrap/issues/37474
35
+ setTimeout(() => {
36
+ this.tooltip.dispose()
37
+ }, 300)
34
38
  }
35
39
  }
36
40
  }
@@ -33,7 +33,7 @@
33
33
  <br>
34
34
  <ul style="max-width: 500px">
35
35
  <% User.order(:id).each do |user| %>
36
- <li><%= link_to user, admin_login_as_path(id: user.id) %></li>
36
+ <li><%= link_to user, login_as_path(id: user.id) %></li>
37
37
  <% end %>
38
38
  </ul>
39
39
  </div>
@@ -5,14 +5,20 @@
5
5
  </div>
6
6
  <% if user_signed_in? %>
7
7
  <span class="d-inline-block px-3 text-end text-light"><%= Current.user %></span>
8
- <%= link_to users_account_switcher_path do %>
9
- <% if Rails.env.development? %>
10
- <span class="d-block px-3 text-secondary">Tenant: <%= ActsAsTenant.current_tenant || 'Global' %></span>
11
- <span class="d-block px-3 text-secondary">Cuenta: <%= Current.account || 'Global' %></span>
12
- <% elsif Current.account.present? %>
13
- <span class="d-block px-3 text-secondary"><%= Current.account %></span>
8
+ <span class="d-block px-3 text-secondary">
9
+ <% if Current.user.user_accounts.count > 1 %>
10
+ <%= link_to ActsAsTenant.current_tenant, [:users, ActsAsTenant.current_tenant] if ActsAsTenant.current_tenant.present? %>
11
+ <%= link_to users_account_switcher_path do %>
12
+ <% if ActsAsTenant.current_tenant.present? %>
13
+ (Cambiar)
14
+ <% else %>
15
+ Elegir cuenta
16
+ <% end %>
17
+ <% end %>
18
+ <% else %>
19
+ <%= link_to ActsAsTenant.current_tenant, [:users, ActsAsTenant.current_tenant] if ActsAsTenant.current_tenant.present? %>
14
20
  <% end %>
15
- <% end %>
21
+ </span>
16
22
  <hr>
17
23
  <% end %>
18
24
  <ul class="list-unstyled ps-0">
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.5.1'
4
+ VERSION = '7.5.3'
5
5
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # FIXME: reemplazar por requests spec
3
4
  # generado con pg_rails
4
5
 
5
6
  require 'rails_helper'
@@ -17,7 +17,7 @@ describe 'Generators', type: :generator do
17
17
  before { prepare_destination }
18
18
 
19
19
  it do
20
- run_generator(['Frontend/Modelo', 'bla:integer'])
20
+ run_generator(['users/modelo', 'bla:integer'])
21
21
 
22
22
  my_assert_file 'app/decorators/modelo_decorator.rb' do |content|
23
23
  expect(content).to match(/delegate_all/)
@@ -31,9 +31,9 @@ describe 'Generators', type: :generator do
31
31
  before { prepare_destination }
32
32
 
33
33
  it do
34
- run_generator(['Frontend/Modelo', 'bla:integer'])
34
+ run_generator(['users/modelo', 'bla:integer'])
35
35
 
36
- my_assert_file 'spec/controllers/frontend/modelos_controller_spec.rb' do |content|
36
+ my_assert_file 'spec/controllers/users/modelos_controller_spec.rb' do |content|
37
37
  expect(content).to match(/routing/)
38
38
  expect(content).to match(/sign_in/)
39
39
  end
@@ -46,7 +46,7 @@ describe 'Generators', type: :generator do
46
46
  before { prepare_destination }
47
47
 
48
48
  it do
49
- run_generator(['Frontend/Modelo', 'bla:integer', 'cosa:references', '--activeadmin'])
49
+ run_generator(['users/modelo', 'bla:integer', 'cosa:references', '--activeadmin'])
50
50
 
51
51
  my_assert_file 'app/admin/modelos.rb' do |content|
52
52
  expect(content).to match(/permit_params.*cosa_id/)
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.1
4
+ version: 7.5.3
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-10 00:00:00.000000000 Z
11
+ date: 2024-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -679,13 +679,17 @@ files:
679
679
  - pg_engine/app/controllers/admin/users_controller.rb
680
680
  - pg_engine/app/controllers/concerns/pg_engine/require_tenant_set.rb
681
681
  - pg_engine/app/controllers/concerns/pg_engine/resource.rb
682
+ - pg_engine/app/controllers/pg_engine/base_admin_controller.rb
682
683
  - pg_engine/app/controllers/pg_engine/base_controller.rb
684
+ - pg_engine/app/controllers/pg_engine/base_public_controller.rb
685
+ - pg_engine/app/controllers/pg_engine/base_users_controller.rb
683
686
  - pg_engine/app/controllers/pg_engine/devise_controller.rb
684
687
  - pg_engine/app/controllers/pg_engine/health_controller.rb
685
688
  - pg_engine/app/controllers/pg_engine/require_sign_in.rb
686
689
  - pg_engine/app/controllers/public/mensaje_contactos_controller.rb
687
690
  - pg_engine/app/controllers/public/webhooks_controller.rb
688
691
  - pg_engine/app/controllers/users/account_switcher_controller.rb
692
+ - pg_engine/app/controllers/users/accounts_controller.rb
689
693
  - pg_engine/app/controllers/users/confirmations_controller.rb
690
694
  - pg_engine/app/controllers/users/date_jumper_controller.rb
691
695
  - pg_engine/app/controllers/users/notifications_controller.rb
@@ -730,6 +734,7 @@ files:
730
734
  - pg_engine/app/notifiers/email_user_notifier.rb
731
735
  - pg_engine/app/notifiers/simple_user_notifier.rb
732
736
  - pg_engine/app/overrides/activestorage_direct_uploads.rb
737
+ - pg_engine/app/overrides/audited_audit.rb
733
738
  - pg_engine/app/policies/account_policy.rb
734
739
  - pg_engine/app/policies/email_log_policy.rb
735
740
  - pg_engine/app/policies/email_policy.rb
@@ -773,6 +778,7 @@ files:
773
778
  - pg_engine/app/views/public/mensaje_contactos/_gracias.html.slim
774
779
  - pg_engine/app/views/public/mensaje_contactos/new.html.slim
775
780
  - pg_engine/app/views/users/account_switcher/list.html.slim
781
+ - pg_engine/app/views/users/accounts/show.html.slim
776
782
  - pg_engine/config/initializers/action_mailer.rb
777
783
  - pg_engine/config/initializers/active_admin.rb
778
784
  - pg_engine/config/initializers/acts_as_tenant.rb
@@ -868,9 +874,11 @@ files:
868
874
  - pg_engine/spec/models/pg_engine/base_record_spec.rb
869
875
  - pg_engine/spec/models/user_account_spec.rb
870
876
  - pg_engine/spec/models/user_spec.rb
877
+ - pg_engine/spec/overrides/audited_audit_spec.rb
871
878
  - pg_engine/spec/pg_engine/pdf_preview_generator_spec.rb
872
879
  - pg_engine/spec/requests/admin/eventos_spec.rb
873
880
  - pg_engine/spec/requests/base_controller_requests_spec.rb
881
+ - pg_engine/spec/requests/users/accounts_spec.rb
874
882
  - pg_engine/spec/requests/users/base_controller_spec.rb
875
883
  - pg_engine/spec/requests/users/date_jumper_spec.rb
876
884
  - pg_engine/spec/requests/users/switcher_spec.rb