pg_rails 7.4.3 → 7.5.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/spec/system/associable_spec.rb +5 -4
  3. data/pg_engine/app/controllers/admin/accounts_controller.rb +4 -6
  4. data/pg_engine/app/controllers/admin/email_logs_controller.rb +0 -2
  5. data/pg_engine/app/controllers/admin/emails_controller.rb +0 -2
  6. data/pg_engine/app/controllers/admin/user_accounts_controller.rb +0 -2
  7. data/pg_engine/app/controllers/admin/users_controller.rb +2 -3
  8. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +3 -0
  9. data/pg_engine/app/controllers/pg_engine/base_controller.rb +50 -7
  10. data/pg_engine/app/controllers/pg_engine/require_sign_in.rb +1 -1
  11. data/pg_engine/app/controllers/users/account_switcher_controller.rb +19 -0
  12. data/pg_engine/app/helpers/pg_engine/form_helper.rb +0 -1
  13. data/pg_engine/app/helpers/pg_engine/route_helper.rb +11 -5
  14. data/pg_engine/app/lib/pg_engine/filtros_builder.rb +2 -1
  15. data/pg_engine/app/models/account.rb +4 -0
  16. data/pg_engine/app/models/current.rb +5 -5
  17. data/pg_engine/app/models/user.rb +36 -5
  18. data/pg_engine/app/models/user_account.rb +1 -0
  19. data/pg_engine/app/policies/user_account_policy.rb +1 -0
  20. data/pg_engine/app/policies/user_policy.rb +6 -13
  21. data/pg_engine/app/views/admin/accounts/_form.html.slim +2 -0
  22. data/pg_engine/app/views/users/account_switcher/list.html.slim +6 -0
  23. data/pg_engine/config/initializers/acts_as_tenant.rb +38 -0
  24. data/pg_engine/config/routes.rb +4 -0
  25. data/pg_engine/db/migrate/20240905154330_account_tenant_columns.rb +10 -0
  26. data/pg_engine/db/seeds.rb +13 -4
  27. data/pg_engine/lib/pg_engine/configuracion.rb +3 -17
  28. data/pg_engine/lib/pg_engine/engine.rb +0 -1
  29. data/pg_engine/lib/pg_engine/utils/pg_logger.rb +2 -1
  30. data/pg_engine/lib/pg_engine.rb +5 -0
  31. data/pg_engine/spec/controllers/admin/accounts_controller_spec.rb +2 -2
  32. data/pg_engine/spec/controllers/admin/user_accounts_controller_spec.rb +4 -3
  33. data/pg_engine/spec/controllers/admin/users_controller_spec.rb +9 -3
  34. data/pg_engine/spec/models/user_spec.rb +11 -4
  35. data/pg_engine/spec/requests/base_controller_requests_spec.rb +1 -1
  36. data/pg_engine/spec/requests/users/base_controller_spec.rb +15 -0
  37. data/pg_engine/spec/requests/users/switcher_spec.rb +60 -0
  38. data/pg_engine/spec/system/breadcrumbs_spec.rb +6 -6
  39. data/pg_engine/spec/system/date_selector_spec.rb +1 -1
  40. data/pg_engine/spec/system/destroy_spec.rb +3 -3
  41. data/pg_engine/spec/system/modal_windows_spec.rb +5 -5
  42. data/pg_engine/spec/system/page_sizes_spec.rb +2 -2
  43. data/pg_engine/spec/system/signup_spec.rb +4 -4
  44. data/pg_engine/spec/system/tenants_spec.rb +55 -0
  45. data/pg_engine/spec/system/tooltips_spec.rb +0 -1
  46. data/pg_layout/app/views/devise/sessions/new.html.erb +4 -0
  47. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +8 -0
  48. data/pg_rails/lib/version.rb +1 -1
  49. data/pg_scaffold/lib/generators/pg_pundit/templates/policy.rb +1 -1
  50. data/pg_scaffold/lib/generators/pg_rails/system_spec/templates/system_spec.rb +1 -1
  51. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +0 -2
  52. metadata +23 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c92bec79721ca86a7228a00acdf6ee2e968c240a1739cdd4b7c61a0f2a7784b5
4
- data.tar.gz: 0701cd071509d9ef7a0fbd7ed8d0cc6e4122b40fe865d021e981b94e96a618e5
3
+ metadata.gz: c9044a5f343884a27bcfdb2be81907fcaaa743b4c1419c4dd1646214a50c5f7e
4
+ data.tar.gz: 2542d054eb7ec2ae29e95fdff5a7a0d8cccdef4d57e5a7073b4c0fe945f91fff
5
5
  SHA512:
6
- metadata.gz: 9888c6b99cf12f74e07aee5bcd4b93d84aa8449ff4854926a8ba9357bf9a20144936337d4b9bb6e1bc8a4dc064d45eaccd44a38986a8816a9aef53939a96fd44
7
- data.tar.gz: 8acb411a451cc8685e3a3cf84bfdfe44ea2c90ae9ffe24d3bcf45ae566ae0c3efe2ea79e96dc74ded65c226ac698d6b660e0d4ce5a547984e65c0bba360bfc6c
6
+ metadata.gz: 19ebd2bc479aab28961ba3280a2c0bf276e202501eecfc0474863a00e89882c79bef6c369e9d1ae7a533ad9118716389af0964ae66395a34ff0572011fb5e4ac
7
+ data.tar.gz: 5a37d34ab77355940e8c8988af1a9c4d839069b9b37bf645088ea5325c18f8e4829c99ae31877c53195d08caf22bae6ba01efa0d55cf8d95872056a481d51473
@@ -3,7 +3,7 @@ require 'rails_helper'
3
3
  describe 'Associable' do
4
4
  let(:user) { create :user, :developer }
5
5
 
6
- let(:path) { '/admin/cosas/new' }
6
+ let(:path) { '/a/cosas/new' }
7
7
 
8
8
  before do
9
9
  login_as user
@@ -16,16 +16,17 @@ describe 'Associable' do
16
16
  find('.cosa_categoria_de_cosa input[type=text]').click
17
17
  expect(page).to have_text :all, 'Nuevo'
18
18
  find('.cosa_categoria_de_cosa .list-group-item').click
19
+ select Account.first.to_s
19
20
  fill_in 'categoria_de_cosa_nombre', with: 'la categoría'
20
21
  select 'Completar', from: 'categoria_de_cosa_tipo'
21
22
  click_on 'Agregar Categoría de cosa'
22
23
  click_on 'Cargar Coso'
23
- expect(page).to have_text 'Creado por'
24
+ expect(page).to have_text 'La cosa'
24
25
  end
25
26
 
26
27
  context 'cuando crea desde el nested' do
27
28
  let!(:categ) { create :categoria_de_cosa }
28
- let(:path) { "/admin/categoria_de_cosas/#{categ.hashid}/cosas/new" }
29
+ let(:path) { "/a/categoria_de_cosas/#{categ.hashid}/cosas/new" }
29
30
 
30
31
  it do
31
32
  input = find_by_id('cosa_categoria_de_cosa')
@@ -36,7 +37,7 @@ describe 'Associable' do
36
37
  context 'cuando edita desde el nested' do
37
38
  let!(:categ) { create :categoria_de_cosa }
38
39
  let!(:cosa) { create :cosa, categoria_de_cosa: categ }
39
- let(:path) { "/admin/categoria_de_cosas/#{categ.hashid}/cosas/#{cosa.id}/edit" }
40
+ let(:path) { "/a/categoria_de_cosas/#{categ.hashid}/cosas/#{cosa.id}/edit" }
40
41
 
41
42
  it do
42
43
  ele = find_by_id('cosa_categoria_de_cosa_id', visible: :all)
@@ -12,24 +12,22 @@ module Admin
12
12
 
13
13
  before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
14
14
 
15
- add_breadcrumb Account.nombre_plural, :admin_accounts_path
16
-
17
15
  private
18
16
 
19
17
  def atributos_permitidos
20
- %i[plan nombre]
18
+ %i[plan nombre domain subdomain]
21
19
  end
22
20
 
23
21
  def atributos_para_buscar
24
- %i[plan nombre]
22
+ atributos_permitidos
25
23
  end
26
24
 
27
25
  def atributos_para_listar
28
- %i[plan nombre]
26
+ atributos_permitidos
29
27
  end
30
28
 
31
29
  def atributos_para_mostrar
32
- %i[plan nombre]
30
+ atributos_permitidos
33
31
  end
34
32
  end
35
33
  end
@@ -12,8 +12,6 @@ module Admin
12
12
 
13
13
  before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
14
14
 
15
- add_breadcrumb EmailLog.nombre_plural, :admin_email_logs_path
16
-
17
15
  before_action do
18
16
  @actions = [
19
17
  ["Mailgun sync: #{ENV.fetch('MAILGUN_DOMAIN', nil)}", mailgun_sync_admin_email_logs_path, {
@@ -12,8 +12,6 @@ module Admin
12
12
 
13
13
  before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
14
14
 
15
- add_breadcrumb Email.nombre_plural, :admin_emails_path
16
-
17
15
  after_action only: :create do
18
16
  if @saved
19
17
  PgEngine::AdminMailer.with(email_object: @email).admin_mail.deliver_later
@@ -12,8 +12,6 @@ module Admin
12
12
 
13
13
  before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
14
14
 
15
- add_breadcrumb UserAccount.nombre_plural, :admin_user_accounts_path
16
-
17
15
  private
18
16
 
19
17
  def atributos_permitidos
@@ -16,11 +16,10 @@ module Admin
16
16
 
17
17
  before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
18
18
 
19
- add_breadcrumb User.nombre_plural, :admin_users_path
20
-
21
19
  def create
22
20
  @user.skip_confirmation!
23
- @user.user_accounts << UserAccount.new(account: Current.account)
21
+ @user.orphan = true
22
+
24
23
  pg_respond_create
25
24
  end
26
25
 
@@ -91,6 +91,9 @@ module PgEngine
91
91
  return if nested_id.blank?
92
92
 
93
93
  nested_class.find(nested_id)
94
+ rescue ActiveRecord::RecordNotFound => e
95
+ pg_warn(e)
96
+ raise PgEngine::PageNotFoundError
94
97
  end
95
98
 
96
99
  def accepts_turbo_stream?
@@ -2,12 +2,51 @@
2
2
 
3
3
  module PgEngine
4
4
  # rubocop:disable Rails/ApplicationController
5
+ # rubocop:disable Metrics/ClassLength
5
6
  class BaseController < ActionController::Base
7
+ # Importante que esta línea esté al principio
8
+ protect_from_forgery with: :exception
9
+
10
+ set_current_tenant_by_subdomain_or_domain(:account, :subdomain, :domain)
11
+ set_current_tenant_through_filter
12
+
6
13
  before_action do
14
+ Current.user = current_user
7
15
  Current.controller = self
8
- end
9
16
 
17
+ # if ActsAsTenant.current_tenant.blank? && !global_domain?
18
+ # raise ActsAsTenant::Errors::NoTenantSet
19
+ # end
20
+
21
+ if Current.user.present?
22
+ if ActsAsTenant.current_tenant.present?
23
+ unless Current.user.user_accounts.exists?(account: ActsAsTenant.current_tenant)
24
+ sign_out(Current.user)
25
+ throw :warden, scope: :user, message: :invalid
26
+ end
27
+
28
+ 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
32
+ Current.user.user_accounts.first
33
+ end
34
+ set_current_tenant(account)
35
+ # FIXME: un concern que redirija al switcher si no hay current tenant
36
+ end
37
+ Current.account = ActsAsTenant.current_tenant
38
+ end
39
+ end
10
40
  # rubocop:enable Rails/ApplicationController
41
+
42
+ # :nocov:
43
+ def global_domain?
44
+ return true if Rails.env.test?
45
+
46
+ request.host.in? PgEngine.config.global_domains
47
+ end
48
+ # :nocov:
49
+
11
50
  include Pundit::Authorization
12
51
  include PrintHelper
13
52
  include PostgresHelper
@@ -25,10 +64,11 @@ module PgEngine
25
64
  end
26
65
  end
27
66
 
28
- protect_from_forgery with: :exception
29
-
30
67
  rescue_from StandardError, with: :internal_error
68
+ rescue_from ActsAsTenant::Errors::NoTenantSet, with: :no_tenant_set
69
+
31
70
  rescue_from PgEngine::BadUserInput, with: :bad_user_input
71
+
32
72
  rescue_from ActionController::InvalidAuthenticityToken,
33
73
  with: :invalid_authenticity_token
34
74
 
@@ -38,6 +78,12 @@ module PgEngine
38
78
  redirect_to e.url
39
79
  end
40
80
 
81
+ def no_tenant_set(error)
82
+ return internal_error(error) if Current.user.blank?
83
+
84
+ redirect_to users_account_switcher_path
85
+ end
86
+
41
87
  def bad_user_input(error)
42
88
  render_my_component(BadUserInputComponent.new(error_msg: error.message), :bad_request)
43
89
  end
@@ -63,10 +109,6 @@ module PgEngine
63
109
  render_my_component(InternalErrorComponent.new, :ok)
64
110
  end
65
111
 
66
- before_action do
67
- Current.user = current_user
68
- end
69
-
70
112
  helper_method :dev_user_or_env?
71
113
  def dev_user_or_env?
72
114
  Rails.env.development? || dev_user?
@@ -181,4 +223,5 @@ module PgEngine
181
223
  redirect_back fallback_location: root_path
182
224
  end
183
225
  end
226
+ # rubocop:enable Metrics/ClassLength
184
227
  end
@@ -4,7 +4,7 @@ module PgEngine
4
4
  module RequireSignIn
5
5
  def self.included(clazz)
6
6
  clazz.include RansackMemory::Concern
7
- clazz.before_action :authenticate_user!
7
+ clazz.prepend_before_action :authenticate_user!
8
8
  clazz.before_action :save_and_load_filters
9
9
  end
10
10
  end
@@ -0,0 +1,19 @@
1
+ module Users
2
+ class AccountSwitcherController < PgEngine.config.users_controller
3
+ rescue_from ActsAsTenant::Errors::NoTenantSet, with: :internal_error
4
+
5
+ before_action do
6
+ @no_main_frame = true
7
+ end
8
+
9
+ def list
10
+ @user_accounts = Current.user.user_accounts
11
+ end
12
+
13
+ def switch
14
+ user_account = UserAccount.find(params[:user_account_id])
15
+ session['current_user_account'] = user_account.id
16
+ redirect_to root_path
17
+ end
18
+ end
19
+ end
@@ -12,7 +12,6 @@ module PgEngine
12
12
  object.decorator_class <= PgEngine::BaseRecordDecorator
13
13
  object = object.decorate.target_object
14
14
  end
15
- # byebug
16
15
  options = args.extract_options!
17
16
 
18
17
  options[:builder] = PgFormBuilder
@@ -3,21 +3,25 @@
3
3
  module PgEngine
4
4
  module RouteHelper
5
5
  class NamespaceDeductor
6
- def self.request(context)
6
+ def self.controller(context)
7
7
  if context.respond_to?(:request) && context.request
8
8
  # Controllers
9
- context.request
9
+ context
10
10
  elsif context.respond_to?(:helpers) && context.helpers
11
11
  # Decorators
12
- context.helpers.request
12
+ context.helpers.controller
13
13
  elsif context.respond_to?(:template) && context.template
14
14
  # FormBuilders
15
- context.template.request
15
+ context.template.controller
16
16
  end
17
17
  end
18
18
 
19
19
  def self.current_route(context)
20
- req = request(context)
20
+ controller = controller(context)
21
+ # Sólo si hay un controller de verdá
22
+ return if controller.instance_of? ApplicationController
23
+
24
+ req = controller.request
21
25
  Rails.application.routes.recognize_path(req.path, method: req.env['REQUEST_METHOD'])
22
26
  end
23
27
 
@@ -25,6 +29,8 @@ module PgEngine
25
29
  return Current.namespace if Current.namespace.present?
26
30
 
27
31
  route = current_route(context)
32
+ return if route.blank?
33
+
28
34
  parts = route[:controller].split('/')
29
35
  return unless parts.length > 1
30
36
 
@@ -64,7 +64,8 @@ module PgEngine
64
64
  @filtros[campo][:scope_asociacion] = block
65
65
  end
66
66
 
67
- # FIXME: deprecar
67
+ deprecate :filtrar, deprecator: PgEngine.deprecator
68
+
68
69
  def filtrar(query, parametros = nil)
69
70
  parametros_controller if parametros.nil?
70
71
 
@@ -32,4 +32,8 @@ class Account < ApplicationRecord
32
32
  enumerize :plan, in: { completar: 0, los: 1, valores: 2 }
33
33
 
34
34
  validates :plan, :nombre, presence: true
35
+
36
+ def to_s
37
+ nombre
38
+ end
35
39
  end
@@ -4,9 +4,9 @@ class Current < ActiveSupport::CurrentAttributes
4
4
 
5
5
  # resets { Time.zone = nil }
6
6
 
7
- def user=(user)
8
- super
9
- self.account = user&.current_account
10
- # Time.zone = user.time_zone
11
- end
7
+ # def user=(user)
8
+ # super
9
+ #
10
+ # Time.zone = user.time_zone
11
+ # end
12
12
  end
@@ -37,7 +37,22 @@ class User < ApplicationRecord
37
37
  include Discard::Model
38
38
 
39
39
  has_many :user_accounts
40
+
41
+ # Hace falta?
40
42
  has_many :accounts, through: :user_accounts
43
+
44
+ # default_scope lambda {
45
+ # if ActsAsTenant.current_tenant.present?
46
+ # joins(:user_accounts).where('user_accounts.account_id': ActsAsTenant.current_tenant.id)
47
+ # else
48
+ # raise ActsAsTenant::Errors::NoTenantSet unless Current.user.blank? || ActsAsTenant.unscoped?
49
+
50
+ # # Aún no autenticó devise o es el admin
51
+ # all
52
+
53
+ # end
54
+ # }
55
+
41
56
  has_many :notifications, as: :recipient, class_name: 'Noticed::Notification'
42
57
 
43
58
  validates :nombre, :apellido, presence: true
@@ -57,14 +72,23 @@ class User < ApplicationRecord
57
72
  attr_accessor :orphan
58
73
 
59
74
  after_create do
60
- # TODO: si fue invitado, sumar a la account del invitador
61
75
  create_account unless orphan
62
76
  end
63
77
 
64
78
  def create_account
65
- account = Account.create(nombre: email, plan: 0)
79
+ # rubocop:disable Rails/Presence
80
+ account =
81
+ if ActsAsTenant.current_tenant.present?
82
+ # FIXME!: raise PgEngine::Error unless invited
83
+ ActsAsTenant.current_tenant
84
+ else
85
+ Account.create(nombre: email, plan: 0)
86
+ end
87
+ # rubocop:enable Rails/Presence
88
+
66
89
  ua = user_accounts.create(account:)
67
- raise(ActiveRecord::Rollback) unless ua.persisted?
90
+
91
+ raise(Error, 'no se pudo crear la cuenta') unless ua.persisted?
68
92
  end
69
93
 
70
94
  def password_required?
@@ -87,9 +111,16 @@ class User < ApplicationRecord
87
111
 
88
112
  class Error < PgEngine::Error; end
89
113
 
90
- def current_account
114
+ def default_account
91
115
  raise Error, 'El usuario debe tener cuenta' if accounts.empty?
92
116
 
93
- accounts.first
117
+ user_accounts.first.account
118
+ # throw :warden, scope: :user, message: :user_not_belongs_to_account
119
+ end
120
+
121
+ deprecate :current_account, deprecator: PgEngine.deprecator
122
+
123
+ def current_account
124
+ ActsAsTenant.current_tenant
94
125
  end
95
126
  end
@@ -23,6 +23,7 @@
23
23
 
24
24
  class UserAccount < ApplicationRecord
25
25
  audited
26
+ include Hashid::Rails
26
27
 
27
28
  belongs_to :user
28
29
  belongs_to :account
@@ -4,6 +4,7 @@
4
4
 
5
5
  class UserAccountPolicy < ApplicationPolicy
6
6
  class Scope < ApplicationPolicy::Scope
7
+ # FIXME: quizá scopear las user_accounts según user y/o según account
7
8
  # def resolve
8
9
  # if policy.acceso_total?
9
10
  # scope.all
@@ -4,17 +4,6 @@
4
4
 
5
5
  class UserPolicy < ApplicationPolicy
6
6
  class Scope < ApplicationPolicy::Scope
7
- def resolve
8
- if policy.acceso_total?
9
- if Current.account.present?
10
- scope.joins(:user_accounts).where('user_accounts.account_id': Current.account.id)
11
- else
12
- scope.none
13
- end
14
- else
15
- scope.none
16
- end
17
- end
18
7
  end
19
8
 
20
9
  # def puede_editar?
@@ -29,7 +18,11 @@ class UserPolicy < ApplicationPolicy
29
18
  # acceso_total? && !record.readonly?
30
19
  # end
31
20
 
32
- def acceso_total?
33
- user.present?
21
+ def base_access_to_record?
22
+ user.developer? || user == record
34
23
  end
24
+
25
+ # def base_access_to_collection?
26
+ # user&.present?
27
+ # end
35
28
  end
@@ -4,5 +4,7 @@ div style="max-width: 22em"
4
4
  = pg_form_for(@account || object) do |f|
5
5
  = f.input :plan
6
6
  = f.input :nombre
7
+ = f.input :domain
8
+ = f.input :subdomain
7
9
  .mt-2
8
10
  = f.button :submit
@@ -0,0 +1,6 @@
1
+ h1 Switcher
2
+
3
+ ul
4
+ - @user_accounts.each do |user_account|
5
+ li = link_to user_account.account, users_account_switch_path(user_account),
6
+ 'data-turbo-method': :post
@@ -0,0 +1,38 @@
1
+ ActsAsTenant.configure do |config|
2
+ config.require_tenant = true
3
+ # config.require_tenant = lambda do |options|
4
+ # # if options[:scope] == User && true # global_domain?
5
+ # # # tal vez en algunos casos de devise sí requeriría el tenant?
6
+ # # # creería que no, el único lugar en donde se debería queriar
7
+ # # # User es en devise y es para obtener el current_user
8
+ # # # hay que ver luego qué pasa con invitable
9
+ # # false
10
+ # # else
11
+ # # true
12
+ # # end
13
+ # end
14
+
15
+ # Customize the query for loading the tenant in background jobs
16
+ # config.job_scope = ->{ all }
17
+ end
18
+
19
+ SET_TENANT_PROC = lambda do
20
+ if defined?(Rails::Console)
21
+ puts "> ActsAsTenant.current_tenant = Account.first"
22
+ ActsAsTenant.current_tenant = Account.first
23
+ end
24
+ end
25
+
26
+ Rails.application.configure do
27
+ if Rails.env.development?
28
+ # Set the tenant to the first account in development on load
29
+ config.after_initialize do
30
+ SET_TENANT_PROC.call
31
+ end
32
+
33
+ # Reset the tenant after calling 'reload!' in the console
34
+ ActiveSupport::Reloader.to_complete do
35
+ SET_TENANT_PROC.call
36
+ end
37
+ end
38
+ end
@@ -21,6 +21,10 @@ Rails.application.routes.draw do
21
21
  post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
22
22
  post 'notifications/mark_as_unseen', to: 'notifications#mark_as_unseen'
23
23
  get 'date_jumper/jump'
24
+ scope controller: 'account_switcher', path: 'switcher' do
25
+ get '', action: 'list', as: 'account_switcher'
26
+ post ':user_account_id', action: 'switch', as: 'account_switch'
27
+ end
24
28
  end
25
29
  namespace :admin, path: 'a' do
26
30
  pg_resource(:emails)
@@ -0,0 +1,10 @@
1
+ class AccountTenantColumns < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :accounts, :domain, :string
4
+ add_column :accounts, :subdomain, :string
5
+
6
+ add_reference :audits, :account, index: true, foreign_key: true
7
+ add_reference :emails, :account, index: true, foreign_key: true
8
+ add_reference :email_logs, :account, index: true, foreign_key: true
9
+ end
10
+ end
@@ -1,6 +1,15 @@
1
- DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
1
+ ActsAsTenant.without_tenant do
2
+ DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
2
3
 
3
- FactoryBot.create :user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
4
- confirmed_at: Time.now, developer: true
5
4
 
6
- Account.first.users << FactoryBot.create(:user, orphan: true)
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
9
+
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
13
+
14
+ mal.users << otro
15
+ end
@@ -4,30 +4,16 @@
4
4
 
5
5
  module PgEngine
6
6
  class Configuracion
7
- attr_accessor :sistema_iconos, :clase_botones_chicos,
8
- :boton_destroy, :boton_edit, :boton_show,
9
- :boton_light, :icono_destroy, :icono_edit,
10
- :icono_show, :boton_export, :bootstrap_version,
11
- :users_controller
7
+ attr_accessor :users_controller, :global_domains
12
8
 
13
9
  def initialize
14
- @sistema_iconos = 'bi'
15
- @clase_botones_chicos = 'btn-sm'
16
- @boton_destroy = 'light'
17
- @boton_export = 'warning'
18
- @boton_edit = 'light'
19
- @boton_show = 'light'
20
- @boton_light = 'light'
21
- @icono_destroy = 'trash-fill'
22
- @icono_edit = 'pencil'
23
- @icono_show = 'eye-fill'
24
- @bootstrap_version = 5
25
-
26
10
  if defined? UsersController
27
11
  @users_controller = UsersController
28
12
  elsif defined? FrontendController
29
13
  @users_controller = FrontendController
30
14
  end
15
+
16
+ @global_domains = ['app.localhost.com', 'test.host', 'localhost']
31
17
  end
32
18
  end
33
19
  end
@@ -59,7 +59,6 @@ module PgEngine
59
59
 
60
60
  initializer 'byebug_bullet' do
61
61
  if Rails.env.local?
62
- # Byebug
63
62
  # :nocov:
64
63
  if ENV['RUBY_DEBUG_OPEN']
65
64
  require 'byebug/core'
@@ -3,9 +3,10 @@
3
3
  require 'rainbow'
4
4
 
5
5
  # TODO: poder pasar blocks
6
+ # TODO: loguear paralelamente a otro file
6
7
 
7
8
  def pg_err(*args)
8
- if ENV.fetch('RAISE_ERRORS', false)
9
+ if ENV.fetch('RAISE_ERRORS', false) == '1'
9
10
  # :nocov:
10
11
  raise args.first if args.first.is_a?(Exception)
11
12
 
@@ -16,6 +16,7 @@ require 'rails'
16
16
  require 'anycable'
17
17
  require 'anycable-rails'
18
18
  require 'anycable-rails-jwt'
19
+ require 'acts_as_tenant'
19
20
  require 'cable_ready'
20
21
  require 'caxlsx_rails'
21
22
  require 'draper'
@@ -105,4 +106,8 @@ module PgEngine
105
106
  https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;\
106
107
  0,500;0,700;1,300;1,400;1,500;1,700&display=swap
107
108
  URL
109
+
110
+ def self.deprecator
111
+ @deprecator ||= ActiveSupport::Deprecation.new('7.5', 'PgEngine')
112
+ end
108
113
  end
@@ -130,7 +130,7 @@ RSpec.describe Admin::AccountsController do
130
130
 
131
131
  it 'redirects to the created account' do
132
132
  post :create, params: { account: valid_attributes }
133
- expect(response).to redirect_to(Account.last.decorate.target_object)
133
+ expect(response).to redirect_to([:admin, Account.last])
134
134
  end
135
135
  end
136
136
 
@@ -163,7 +163,7 @@ RSpec.describe Admin::AccountsController do
163
163
  it 'redirects to the account' do
164
164
  account = create(:account)
165
165
  put :update, params: { id: account.to_param, account: valid_attributes }
166
- expect(response).to redirect_to(account.decorate.target_object)
166
+ expect(response).to redirect_to([:admin, Account.last])
167
167
  end
168
168
  end
169
169
 
@@ -31,7 +31,7 @@ RSpec.describe Admin::UserAccountsController do
31
31
  render_views
32
32
  let!(:user) { create :user }
33
33
 
34
- let!(:account) { create :account }
34
+ let!(:account) { ActsAsTenant.current_tenant }
35
35
 
36
36
  # This should return the minimal set of attributes required to create a valid
37
37
  # UserAccount. As you add validations to UserAccount, be sure to
@@ -125,7 +125,7 @@ RSpec.describe Admin::UserAccountsController do
125
125
 
126
126
  it 'redirects to the created user_account' do
127
127
  post :create, params: { user_account: valid_attributes }
128
- expect(response).to redirect_to(UserAccount.last.decorate.target_object)
128
+ expect(response).to redirect_to([:admin, UserAccount.last])
129
129
  end
130
130
  end
131
131
 
@@ -151,7 +151,8 @@ RSpec.describe Admin::UserAccountsController do
151
151
  it 'redirects to the user_account' do
152
152
  user_account = create(:user_account)
153
153
  put :update, params: { id: user_account.to_param, user_account: valid_attributes }
154
- expect(response).to redirect_to(user_account.decorate.target_object)
154
+
155
+ expect(response).to redirect_to([:admin, UserAccount.last])
155
156
  end
156
157
  end
157
158
 
@@ -99,12 +99,18 @@ RSpec.describe Admin::UsersController do
99
99
  it 'creates a new User' do
100
100
  expect do
101
101
  post :create, params: { user: valid_attributes }
102
- end.to change(User, :count).by(1)
102
+ end.to change(User.unscoped, :count).by(1)
103
+ end
104
+
105
+ it 'dont creates a new account' do
106
+ expect do
107
+ post :create, params: { user: valid_attributes }
108
+ end.not_to change(Account.unscoped, :count)
103
109
  end
104
110
 
105
111
  it 'redirects to the created user' do
106
112
  post :create, params: { user: valid_attributes }
107
- expect(response).to redirect_to(User.last.decorate.target_object)
113
+ expect(response).to redirect_to([:admin, User.unscoped.last])
108
114
  end
109
115
  end
110
116
 
@@ -137,7 +143,7 @@ RSpec.describe Admin::UsersController do
137
143
  it 'redirects to the user' do
138
144
  user = create(:user)
139
145
  put :update, params: { id: user.to_param, user: valid_attributes }
140
- expect(response).to redirect_to(user.decorate.target_object)
146
+ expect(response).to redirect_to([:admin, user.decorate])
141
147
  end
142
148
  end
143
149
 
@@ -12,7 +12,7 @@ RSpec.describe User do
12
12
  end
13
13
 
14
14
  it do
15
- expect(user.current_account).to be_present
15
+ expect(user.default_account).to be_present
16
16
  end
17
17
 
18
18
  context 'si es orphan' do
@@ -23,11 +23,18 @@ RSpec.describe User do
23
23
  end
24
24
 
25
25
  it do
26
- expect { user.current_account }.to raise_error(User::Error)
26
+ expect { user.default_account }.to raise_error(User::Error)
27
27
  end
28
28
  end
29
29
 
30
30
  context 'Si falla la creación de cuenta, que rollbackee la transaction de create user' do
31
+ # rubocop:disable Lint/SuppressedException
32
+ subject do
33
+ user.save
34
+ rescue User::Error
35
+ end
36
+ # rubocop:enable Lint/SuppressedException
37
+
31
38
  let(:user) do
32
39
  build(:user)
33
40
  end
@@ -41,11 +48,11 @@ RSpec.describe User do
41
48
  end
42
49
 
43
50
  it do
44
- expect { user.save }.not_to change(described_class, :count)
51
+ expect { subject }.not_to change(described_class, :count)
45
52
  end
46
53
 
47
54
  it do
48
- user.save
55
+ subject
49
56
  expect(user).not_to be_persisted
50
57
  end
51
58
  end
@@ -13,7 +13,7 @@ describe 'Base requests' do
13
13
  end
14
14
 
15
15
  describe 'invalid authenticity token' do
16
- subject { get '/admin/cosas', headers: }
16
+ subject { get '/a/cosas', headers: }
17
17
 
18
18
  before do
19
19
  sign_in create(:user, :developer)
@@ -0,0 +1,15 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'redirection' do
4
+ context 'when public controller raises no tenant set' do
5
+ before do
6
+ allow(MensajeContacto).to receive(:new).and_raise(ActsAsTenant::Errors::NoTenantSet)
7
+ end
8
+
9
+ it 'shows the error' do
10
+ get '/contacto'
11
+
12
+ expect(response).to have_http_status(:internal_server_error)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'redirection' do
4
+ let(:logged_user) { create :user }
5
+
6
+ before do
7
+ sign_in logged_user
8
+ end
9
+
10
+ context 'when switcher controller raises no tenant set' do
11
+ # This is to prevent a redirect loop
12
+ before do
13
+ allow_any_instance_of(User).to receive(:user_accounts).and_raise(ActsAsTenant::Errors::NoTenantSet)
14
+ end
15
+
16
+ it 'shows the error' do
17
+ get '/u/switcher'
18
+
19
+ expect(response).to have_http_status(:internal_server_error)
20
+ end
21
+ end
22
+
23
+ it do
24
+ get '/u/cosas'
25
+
26
+ expect(response).to have_http_status(:ok)
27
+ end
28
+
29
+ context 'when has been removed from account' do
30
+ let!(:other_account) { create :account }
31
+ let!(:other_user_account) { logged_user.user_accounts.create(account: other_account) }
32
+
33
+ it 'redirects to switcher' do
34
+ get '/u/cosas'
35
+ expect(response).to redirect_to users_account_switcher_path
36
+ follow_redirect!
37
+ expect(response.body).to include 'Switcher'
38
+ post "/u/switcher/#{other_user_account.to_param}"
39
+ expect(response).to redirect_to(root_path)
40
+ follow_redirect!
41
+ expect(response.body).to include other_account.to_s
42
+ other_user_account.destroy!
43
+ get '/'
44
+ expect(response).to redirect_to users_account_switcher_path
45
+ end
46
+ end
47
+
48
+ context 'when belongs to other account' do
49
+ before do
50
+ create :account, subdomain: 'other'
51
+ host! 'other.example.com'
52
+ end
53
+
54
+ it do
55
+ get '/u/cosas'
56
+
57
+ expect(response).to redirect_to new_user_session_path
58
+ end
59
+ end
60
+ end
@@ -12,7 +12,7 @@ describe 'Breadcrumbs' do
12
12
  visit path
13
13
  end
14
14
 
15
- let(:path) { "/admin/cosas/#{cosa.id}" }
15
+ let(:path) { "/a/cosas/#{cosa.id}" }
16
16
  let(:cosa) { create :cosa }
17
17
  let(:logged_user) { create :user, :developer }
18
18
  let(:account) { logged_user.current_account }
@@ -25,20 +25,20 @@ describe 'Breadcrumbs' do
25
25
  it do
26
26
  visitar
27
27
 
28
- expect(page).to have_css('nav ol.breadcrumb li').exactly(2)
28
+ expect(page).to have_css('nav ol.breadcrumb li').exactly(3)
29
29
  expect(page).to have_css('nav ol.breadcrumb li a').exactly(1)
30
30
  end
31
31
 
32
32
  context 'cuando es con nested' do
33
33
  let(:path) do
34
34
  hashid = cosa.categoria_de_cosa.hashid
35
- "/admin/categoria_de_cosas/#{hashid}/cosas/#{cosa.id}"
35
+ "/a/categoria_de_cosas/#{hashid}/cosas/#{cosa.id}"
36
36
  end
37
37
 
38
38
  it do
39
39
  visitar
40
40
 
41
- expect(page).to have_css('nav ol.breadcrumb li').exactly(3)
41
+ expect(page).to have_css('nav ol.breadcrumb li').exactly(4)
42
42
  expect(page).to have_css('nav ol.breadcrumb li a').exactly(1)
43
43
  end
44
44
  end
@@ -46,14 +46,14 @@ describe 'Breadcrumbs' do
46
46
  context 'cuando es con nested y modal' do
47
47
  let(:path) do
48
48
  hashid = cosa.categoria_de_cosa.hashid
49
- "/admin/categoria_de_cosas/#{hashid}"
49
+ "/a/categoria_de_cosas/#{hashid}"
50
50
  end
51
51
 
52
52
  it do
53
53
  visitar
54
54
  find('td span[title=Ver] a').click
55
55
 
56
- expect(page).to have_css('.modal nav ol.breadcrumb li').exactly(3)
56
+ expect(page).to have_css('.modal nav ol.breadcrumb li').exactly(4)
57
57
  expect(page).to have_no_css('.modal nav ol.breadcrumb li a')
58
58
  end
59
59
  end
@@ -12,7 +12,7 @@ describe 'Date selector' do
12
12
  visit edit_admin_categoria_de_cosa_path(categoria_de_cosa)
13
13
  end
14
14
 
15
- let(:logged_user) { create :user }
15
+ let(:logged_user) { create :user, :developer }
16
16
  let(:account) { logged_user.current_account }
17
17
  let(:categoria_de_cosa) { create :categoria_de_cosa, fecha: }
18
18
  let(:fecha) { Date.new(2024, 8, 12) }
@@ -19,7 +19,7 @@ describe 'Sign in' do
19
19
  before do
20
20
  create_list :cosa, 5
21
21
  login_as user
22
- visit '/frontend/cosas'
22
+ visit '/a/cosas'
23
23
  end
24
24
 
25
25
  it do
@@ -40,12 +40,12 @@ describe 'Sign in' do
40
40
 
41
41
  before do
42
42
  login_as user
43
- visit "/frontend/cosas/#{cosa.to_param}"
43
+ visit "/a/cosas/#{cosa.to_param}"
44
44
  end
45
45
 
46
46
  it 'muestra el flash' do
47
47
  subject
48
- expect(page).to have_current_path('/frontend/cosas')
48
+ expect(page).to have_current_path('/a/cosas')
49
49
  expect(page).to have_text('Coso borrado')
50
50
  end
51
51
  end
@@ -9,7 +9,7 @@ require 'rails_helper'
9
9
  # DRIVER=selenium rspec
10
10
  describe 'Modal windows' do
11
11
  subject(:visitar) do
12
- visit '/admin/cosas'
12
+ visit '/a/cosas'
13
13
  end
14
14
 
15
15
  let(:logged_user) { create :user, :developer }
@@ -38,7 +38,7 @@ describe 'Modal windows' do
38
38
  let!(:cosa) { create :cosa, categoria_de_cosa: }
39
39
 
40
40
  it do
41
- visit '/admin/cosas/' + cosa.to_param
41
+ visit '/a/cosas/' + cosa.to_param
42
42
  click_on 'Ver categoría'
43
43
  expect(page).to have_css '.modal', text: categoria_de_cosa.nombre
44
44
  end
@@ -48,7 +48,7 @@ describe 'Modal windows' do
48
48
  let!(:cosa) { create :cosa, categoria_de_cosa: }
49
49
 
50
50
  it do
51
- visit '/admin/cosas/' + cosa.to_param
51
+ visit '/a/cosas/' + cosa.to_param
52
52
  click_on 'Modificar'
53
53
  fill_in 'Nombre', with: ''
54
54
  find('.modal input[type=submit]').click
@@ -63,7 +63,7 @@ describe 'Modal windows' do
63
63
  before { create :cosa, categoria_de_cosa: }
64
64
 
65
65
  it do
66
- visit '/admin/cosas'
66
+ visit '/a/cosas'
67
67
  find('span[title=Ver] a').click
68
68
  accept_confirm do
69
69
  find('.modal span[title=Eliminar] a').click
@@ -77,7 +77,7 @@ describe 'Modal windows' do
77
77
  end
78
78
 
79
79
  it do
80
- visit '/admin/cosas'
80
+ visit '/a/cosas'
81
81
  find('span[title=Ver] a').click
82
82
  accept_confirm do
83
83
  find('.modal span[title=Eliminar] a').click
@@ -17,9 +17,9 @@ describe 'Page sizes' do
17
17
 
18
18
  describe 'some case' do
19
19
  it do
20
- visit '/admin/cosas?page_size=2'
20
+ visit '/a/cosas?page_size=2'
21
21
  expect(page).to have_css('.page-item', count: 6)
22
- visit '/admin/cosas?page_size=5'
22
+ visit '/a/cosas?page_size=5'
23
23
  expect(page).to have_css('.page-item', count: 4)
24
24
  end
25
25
  end
@@ -34,8 +34,10 @@ describe 'Al Registrarse' do
34
34
  check 'user_accept_terms'
35
35
  end
36
36
 
37
+ pending 'expect new account created also'
38
+
37
39
  it 'guarda el user' do
38
- expect { subject }.to change(User, :count).by(1)
40
+ expect { subject }.to change(User.unscoped, :count).by(1)
39
41
  expect(page).to have_text('Te enviamos un correo electrónico con instrucciones')
40
42
  end
41
43
  end
@@ -57,8 +59,6 @@ describe 'Al Registrarse' do
57
59
  fill_in 'user_nombre', with: 'despues'
58
60
  fill_in 'user_current_password', with: password
59
61
  instance_exec('input[type=submit]', &find_scroll).click
60
- # find('').click
61
- sleep 1
62
62
  end
63
63
 
64
64
  let(:password) { 'pass1234' }
@@ -71,7 +71,7 @@ describe 'Al Registrarse' do
71
71
  end
72
72
 
73
73
  it do
74
- expect { subject }.to change { user.reload.nombre }.to('despues')
74
+ subject
75
75
  expect(page).to have_text('Tu cuenta se ha actualizado')
76
76
  end
77
77
  end
@@ -0,0 +1,55 @@
1
+ # Initially generated with PgRails::SystemSpecGenerator
2
+ # https://github.com/martin-rosso/pg_rails
3
+
4
+ require 'rails_helper'
5
+
6
+ # By default uses selenium_chrome_headless_iphone driver
7
+ # run with DRIVER environment variable to override, eg:
8
+ #
9
+ # DRIVER=selenium rspec
10
+ describe 'Tenants' do
11
+ subject(:visitar) do
12
+ visit '/u/cosas'
13
+ end
14
+
15
+ let(:logged_user) { create :user }
16
+
17
+ before do
18
+ login_as logged_user
19
+ end
20
+
21
+ describe 'switcher' do
22
+ it do
23
+ visitar
24
+
25
+ expect(page).to have_text 'No hay cosos que mostrar'
26
+ end
27
+
28
+ context 'when belongs to multiple accounts' do
29
+ let(:other_account) { create :account }
30
+
31
+ before do
32
+ logged_user.user_accounts.create!(account: other_account)
33
+ end
34
+
35
+ it 'shows the switcher' do
36
+ visitar
37
+
38
+ expect(page).to have_text 'Switcher'
39
+ end
40
+
41
+ it 'switches to account' do
42
+ visitar
43
+
44
+ click_on other_account.to_s
45
+ expect(page).to have_text 'No hay categorías de cosas que mostrar'
46
+ end
47
+
48
+ it 'shows the profile form' do
49
+ visit '/users/edit'
50
+
51
+ expect(page).to have_text 'Editar Usuario'
52
+ end
53
+ end
54
+ end
55
+ end
@@ -3,7 +3,6 @@ require 'rails_helper'
3
3
  describe 'Tooltips' do
4
4
  context 'en desktop' do
5
5
  before do
6
- # byebug
7
6
  driven_by :selenium_chrome_headless
8
7
  # Capybara.current_driver = :selenium_chrome
9
8
  end
@@ -1,3 +1,7 @@
1
+ <% if ActsAsTenant.current_tenant %>
2
+ <h1><%= ActsAsTenant.current_tenant %><h1>
3
+ <% end %>
4
+
1
5
  <h2><%= t(".sign_in") %></h2>
2
6
 
3
7
  <%= render FlashContainerComponent.new %>
@@ -5,6 +5,14 @@
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>
14
+ <% end %>
15
+ <% end %>
8
16
  <hr>
9
17
  <% end %>
10
18
  <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.4.3'
4
+ VERSION = '7.5.0'
5
5
  end
@@ -31,7 +31,7 @@ class <%= class_name %>Policy < ApplicationPolicy
31
31
  # end
32
32
 
33
33
  # def base_access_to_record?
34
- # base_access_to_collection? && record.account == Current.account
34
+ # base_access_to_collection? && record.account == ActsAsTenant.current_tenant
35
35
  # end
36
36
 
37
37
  # def base_access_to_collection?
@@ -13,7 +13,7 @@ describe '<%= name %>' do
13
13
  end
14
14
 
15
15
  let(:logged_user) { create :user }
16
- let(:account) { logged_user.current_account }
16
+ let(:account) { ActsAsTenant.current_tenant }
17
17
 
18
18
  before do
19
19
  login_as logged_user
@@ -170,7 +170,6 @@ RSpec.describe <%= controller_class_name %>Controller do
170
170
  <% else -%>
171
171
  post :create, params: { <%= nombre_tabla_completo_singular %>: valid_attributes }
172
172
  <% end -%>
173
- # FIXME: redirect to target object
174
173
  expect(response).to redirect_to([:<%= ns_prefix.first %>, <%= class_name %>.last])
175
174
  end
176
175
  end
@@ -219,7 +218,6 @@ RSpec.describe <%= controller_class_name %>Controller do
219
218
  <% else -%>
220
219
  put :update, params: { id: <%= file_name %>.to_param, <%= nombre_tabla_completo_singular %>: valid_attributes }
221
220
  <% end -%>
222
- # FIXME: redirect to target object
223
221
  expect(response).to redirect_to([:<%= ns_prefix.first %>, <%= file_name %>])
224
222
  end
225
223
  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.4.3
4
+ version: 7.5.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-04 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: acts_as_tenant
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: caxlsx_rails
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -670,6 +684,7 @@ files:
670
684
  - pg_engine/app/controllers/pg_engine/require_sign_in.rb
671
685
  - pg_engine/app/controllers/public/mensaje_contactos_controller.rb
672
686
  - pg_engine/app/controllers/public/webhooks_controller.rb
687
+ - pg_engine/app/controllers/users/account_switcher_controller.rb
673
688
  - pg_engine/app/controllers/users/confirmations_controller.rb
674
689
  - pg_engine/app/controllers/users/date_jumper_controller.rb
675
690
  - pg_engine/app/controllers/users/notifications_controller.rb
@@ -756,8 +771,10 @@ files:
756
771
  - pg_engine/app/views/pg_engine/user_mailer/notification.text.slim
757
772
  - pg_engine/app/views/public/mensaje_contactos/_gracias.html.slim
758
773
  - pg_engine/app/views/public/mensaje_contactos/new.html.slim
774
+ - pg_engine/app/views/users/account_switcher/list.html.slim
759
775
  - pg_engine/config/initializers/action_mailer.rb
760
776
  - pg_engine/config/initializers/active_admin.rb
777
+ - pg_engine/config/initializers/acts_as_tenant.rb
761
778
  - pg_engine/config/initializers/anycable.rb
762
779
  - pg_engine/config/initializers/cable_ready.rb
763
780
  - pg_engine/config/initializers/devise.rb
@@ -789,6 +806,7 @@ files:
789
806
  - pg_engine/db/migrate/20240611000219_create_noticed_tables.noticed.rb
790
807
  - pg_engine/db/migrate/20240611000220_add_notifications_count_to_noticed_event.noticed.rb
791
808
  - pg_engine/db/migrate/20240614130246_create_action_text_tables.action_text.rb
809
+ - pg_engine/db/migrate/20240905154330_account_tenant_columns.rb
792
810
  - pg_engine/db/seeds.rb
793
811
  - pg_engine/lib/pg_engine.rb
794
812
  - pg_engine/lib/pg_engine/configuracion.rb
@@ -852,7 +870,9 @@ files:
852
870
  - pg_engine/spec/pg_engine/pdf_preview_generator_spec.rb
853
871
  - pg_engine/spec/requests/admin/eventos_spec.rb
854
872
  - pg_engine/spec/requests/base_controller_requests_spec.rb
873
+ - pg_engine/spec/requests/users/base_controller_spec.rb
855
874
  - pg_engine/spec/requests/users/date_jumper_spec.rb
875
+ - pg_engine/spec/requests/users/switcher_spec.rb
856
876
  - pg_engine/spec/system/alerts_spec.rb
857
877
  - pg_engine/spec/system/breadcrumbs_spec.rb
858
878
  - pg_engine/spec/system/date_selector_spec.rb
@@ -863,6 +883,7 @@ files:
863
883
  - pg_engine/spec/system/page_sizes_spec.rb
864
884
  - pg_engine/spec/system/send_mail_spec.rb
865
885
  - pg_engine/spec/system/signup_spec.rb
886
+ - pg_engine/spec/system/tenants_spec.rb
866
887
  - pg_engine/spec/system/tooltips_spec.rb
867
888
  - pg_layout/app/assets/stylesheets/animations.scss
868
889
  - pg_layout/app/assets/stylesheets/sidebar.scss