pg_rails 7.4.3 → 7.5.0

Sign up to get free protection for your applications and to get access to all the features.
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