pg_rails 7.6.20 → 7.6.21.pre.2

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/app/javascript/modal_controller.js +8 -4
  3. data/pg_associable/spec/pg_associable/helpers_spec.rb +8 -13
  4. data/pg_engine/app/components/inline_edit/inline_edit_component.html.slim +1 -1
  5. data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +2 -2
  6. data/pg_engine/app/components/notifications_bell_component.rb +1 -1
  7. data/pg_engine/app/controllers/admin/accounts_controller.rb +2 -2
  8. data/pg_engine/app/controllers/admin/user_accounts_controller.rb +3 -3
  9. data/pg_engine/app/controllers/admin/users_controller.rb +4 -1
  10. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +12 -7
  11. data/pg_engine/app/controllers/concerns/pg_engine/tenant_helper.rb +33 -0
  12. data/pg_engine/app/controllers/pg_engine/base_admin_controller.rb +0 -1
  13. data/pg_engine/app/controllers/pg_engine/base_controller.rb +18 -21
  14. data/pg_engine/app/controllers/pg_engine/base_public_controller.rb +1 -1
  15. data/pg_engine/app/controllers/pg_engine/base_users_controller.rb +5 -3
  16. data/pg_engine/app/controllers/pg_engine/devise_controller.rb +4 -1
  17. data/pg_engine/app/controllers/pg_engine/tenant_controller.rb +22 -0
  18. data/pg_engine/app/controllers/{users → tenant}/dashboard_controller.rb +2 -2
  19. data/pg_engine/app/controllers/tenant/inline_edit_controller.rb +22 -0
  20. data/pg_engine/app/controllers/tenant/user_accounts_controller.rb +56 -0
  21. data/pg_engine/app/controllers/users/accounts_controller.rb +46 -15
  22. data/pg_engine/app/controllers/users/invitations_controller.rb +78 -0
  23. data/pg_engine/app/controllers/users/notifications_controller.rb +1 -0
  24. data/pg_engine/app/controllers/users/registrations_controller.rb +3 -2
  25. data/pg_engine/app/decorators/account_decorator.rb +18 -0
  26. data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +9 -1
  27. data/pg_engine/app/decorators/user_account_decorator.rb +76 -11
  28. data/pg_engine/app/helpers/pg_engine/accounts_helper.rb +9 -0
  29. data/pg_engine/app/helpers/pg_engine/frame_helper.rb +12 -0
  30. data/pg_engine/app/lib/pg_engine/default_url_options.rb +21 -0
  31. data/pg_engine/app/lib/pg_engine/filtros_builder.rb +2 -0
  32. data/pg_engine/app/models/account.rb +28 -1
  33. data/pg_engine/app/models/concerns/pg_engine/child_record.rb +55 -0
  34. data/pg_engine/app/models/current.rb +29 -3
  35. data/pg_engine/app/models/pg_engine/base_record.rb +5 -0
  36. data/pg_engine/app/models/user.rb +56 -14
  37. data/pg_engine/app/models/user_account.rb +74 -9
  38. data/pg_engine/app/policies/account_policy.rb +35 -16
  39. data/pg_engine/app/policies/email_log_policy.rb +0 -4
  40. data/pg_engine/app/policies/email_policy.rb +0 -4
  41. data/pg_engine/app/policies/pg_engine/base_policy.rb +31 -10
  42. data/pg_engine/app/policies/user_account_policy.rb +59 -25
  43. data/pg_engine/app/policies/user_policy.rb +14 -1
  44. data/pg_engine/app/views/admin/user_accounts/_form.html.slim +1 -1
  45. data/pg_engine/app/views/admin/user_accounts/show.html.slim +15 -0
  46. data/pg_engine/app/views/admin/users/show.html.slim +0 -3
  47. data/pg_engine/app/views/pg_engine/base/index.html.slim +2 -2
  48. data/pg_engine/app/views/tenant/dashboard/dashboard.html.slim +2 -0
  49. data/pg_engine/app/views/tenant/user_accounts/_fields.html.slim +13 -0
  50. data/pg_engine/app/views/tenant/user_accounts/_form.html.slim +9 -0
  51. data/pg_engine/app/views/tenant/user_accounts/show.html.slim +20 -0
  52. data/pg_engine/app/views/users/accounts/_form.html.slim +7 -0
  53. data/pg_engine/app/views/users/accounts/show.html.slim +23 -15
  54. data/pg_engine/config/initializers/acts_as_tenant.rb +7 -2
  55. data/pg_engine/config/initializers/devise.rb +10 -0
  56. data/pg_engine/config/initializers/ransack.rb +2 -0
  57. data/pg_engine/config/locales/es.yml +60 -0
  58. data/pg_engine/config/routes.rb +21 -11
  59. data/pg_engine/config/simple_form/simple_form_bootstrap.rb +2 -2
  60. data/pg_engine/db/migrate/20241023203849_devise_invitable.rb +14 -0
  61. data/pg_engine/db/migrate/20241027225618_add_membership_status_to_user_accounts.rb +6 -0
  62. data/pg_engine/db/seeds.rb +6 -6
  63. data/pg_engine/lib/pg_engine/configuracion.rb +36 -1
  64. data/pg_engine/lib/pg_engine/navigator.rb +2 -25
  65. data/pg_engine/lib/pg_engine.rb +1 -0
  66. data/pg_engine/spec/controllers/admin/accounts_controller_spec.rb +3 -2
  67. data/pg_engine/spec/controllers/admin/user_accounts_controller_spec.rb +11 -9
  68. data/pg_engine/spec/factories/accounts.rb +8 -0
  69. data/pg_engine/spec/factories/user_accounts.rb +1 -1
  70. data/pg_engine/spec/factories/users.rb +6 -0
  71. data/pg_engine/spec/models/concerns/pg_engine/child_record_spec.rb +27 -0
  72. data/pg_engine/spec/models/user_account_spec.rb +5 -1
  73. data/pg_engine/spec/models/user_spec.rb +3 -25
  74. data/pg_engine/spec/policies/account_policy_spec.rb +19 -0
  75. data/pg_engine/spec/requests/devise/invitations_spec.rb +196 -0
  76. data/pg_engine/spec/requests/resource_spec.rb +14 -15
  77. data/pg_engine/spec/requests/users/accounts_spec.rb +117 -8
  78. data/pg_engine/spec/requests/users/base_controller_spec.rb +31 -0
  79. data/pg_engine/spec/requests/users/dashboard_spec.rb +4 -9
  80. data/pg_engine/spec/requests/users/date_jumper_spec.rb +2 -1
  81. data/pg_engine/spec/requests/users/inline_edit_spec.rb +6 -5
  82. data/pg_engine/spec/requests/users/registrations_spec.rb +2 -2
  83. data/pg_engine/spec/requests/users/user_accounts_spec.rb +54 -0
  84. data/pg_engine/spec/system/login_spec.rb +2 -2
  85. data/pg_engine/spec/system/noticed_spec.rb +0 -2
  86. data/pg_engine/spec/system/signup_spec.rb +4 -3
  87. data/pg_engine/spec/system/tenants_spec.rb +10 -9
  88. data/pg_layout/app/javascript/application.js +1 -1
  89. data/pg_layout/app/javascript/config/turbo_rails/index.js +1 -1
  90. data/pg_layout/app/lib/navbar.rb +15 -1
  91. data/pg_layout/app/views/devise/invitations/edit.html.erb +34 -0
  92. data/pg_layout/app/views/devise/invitations/new.html.erb +15 -0
  93. data/pg_layout/app/views/devise/mailer/invitation_instructions.html.erb +11 -0
  94. data/pg_layout/app/views/devise/mailer/invitation_instructions.text.erb +11 -0
  95. data/pg_layout/app/views/devise/registrations/edit.html.erb +1 -0
  96. data/pg_layout/app/views/layouts/pg_layout/base.html.slim +7 -5
  97. data/pg_layout/app/views/pg_layout/_navbar.html.erb +7 -6
  98. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +2 -20
  99. data/pg_layout/app/views/pg_layout/_signed_in_links.html.slim +52 -0
  100. data/pg_layout/lib/pg_layout.rb +0 -5
  101. data/pg_rails/lib/pg_rails/pundit_matchers.rb +21 -0
  102. data/pg_rails/lib/pg_rails/tpath_support.rb +73 -0
  103. data/pg_rails/lib/pg_rails.rb +6 -0
  104. data/pg_rails/lib/version.rb +1 -1
  105. data/pg_rails/scss/pg_rails.scss +1 -1
  106. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +1 -1
  107. data/pg_scaffold/lib/generators/pg_slim/templates/index.html.slim +1 -1
  108. metadata +43 -9
  109. data/pg_engine/app/controllers/concerns/pg_engine/require_tenant_set.rb +0 -15
  110. data/pg_engine/app/controllers/users/account_switcher_controller.rb +0 -30
  111. data/pg_engine/app/controllers/users/inline_edit_controller.rb +0 -21
  112. data/pg_engine/app/views/users/account_switcher/list.html.slim +0 -24
  113. data/pg_engine/app/views/users/dashboard/dashboard.html.slim +0 -1
  114. data/pg_engine/spec/requests/users/switcher_spec.rb +0 -84
@@ -24,8 +24,4 @@ class EmailPolicy < ApplicationPolicy
24
24
  # def puede_borrar?
25
25
  # acceso_total? && !record.readonly?
26
26
  # end
27
-
28
- # def acceso_total?
29
- # user.developer?
30
- # end
31
27
  end
@@ -14,7 +14,7 @@ module PgEngine
14
14
  end
15
15
 
16
16
  def archived?
17
- base_access_to_collection?
17
+ puede_ver_archivados? && base_access_to_collection?
18
18
  end
19
19
 
20
20
  def show?
@@ -46,11 +46,12 @@ module PgEngine
46
46
  end
47
47
 
48
48
  def archive?
49
- puede_borrar? && !record_discarded?
49
+ puede_ver_archivados? && puede_editar? && record.respond_to?(:discard) && record.kept?
50
50
  end
51
51
 
52
52
  def restore?
53
- puede_borrar? && record.respond_to?(:discarded?) && record.discarded?
53
+ puede_ver_archivados? && puede_editar? && record.respond_to?(:undiscard) && record.discarded? &&
54
+ (!record.parent? || record.parent.kept?)
54
55
  end
55
56
 
56
57
  def scope
@@ -81,27 +82,35 @@ module PgEngine
81
82
  end
82
83
 
83
84
  def puede_editar?
84
- base_access_to_record?
85
+ user_has_profile(:update)
85
86
  end
86
87
 
87
88
  def puede_crear?
88
- base_access_to_collection?
89
+ user_has_profile(:create)
89
90
  end
90
91
 
91
92
  def puede_borrar?
92
- base_access_to_record?
93
+ user_has_profile(:destroy)
93
94
  end
94
95
 
95
- def export?
96
- base_access_to_collection?
96
+ def puede_ver_archivados?
97
+ admits_discard = begin
98
+ model = record.is_a?(ActiveRecord::Base) ? record.class : record
99
+ model.respond_to?(:discarded)
100
+ end
101
+ user_has_profile(:archive) && admits_discard
97
102
  end
98
103
 
99
104
  def base_access_to_record?
100
- user&.developer?
105
+ user_has_profile(:read)
101
106
  end
102
107
 
103
108
  def base_access_to_collection?
104
- user&.developer?
109
+ user_has_profile(:read)
110
+ end
111
+
112
+ def export?
113
+ user_has_profile(:export)
105
114
  end
106
115
 
107
116
  def record_discarded?
@@ -111,5 +120,17 @@ module PgEngine
111
120
  false
112
121
  end
113
122
  end
123
+
124
+ def profile_prefix
125
+ record.model_name.plural
126
+ end
127
+
128
+ def user_has_profile(key)
129
+ return true if Current.namespace == :admin
130
+ return false if ActsAsTenant.current_tenant.blank?
131
+
132
+ full_key = "#{profile_prefix}__#{key}"
133
+ Current.user_account_owner? || Current.active_user_profiles.include?(full_key)
134
+ end
114
135
  end
115
136
  end
@@ -4,29 +4,63 @@
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
8
- # def resolve
9
- # if policy.acceso_total?
10
- # scope.all
11
- # else
12
- # scope.none
13
- # end
14
- # end
15
- end
16
-
17
- # def puede_editar?
18
- # acceso_total? && !record.readonly?
19
- # end
20
-
21
- # def puede_crear?
22
- # acceso_total? || user.asesor?
23
- # end
24
-
25
- # def puede_borrar?
26
- # acceso_total? && !record.readonly?
27
- # end
28
-
29
- # def acceso_total?
30
- # user.developer?
31
- # end
7
+ def resolve
8
+ if Current.namespace == :admin
9
+ scope.all
10
+ elsif Current.user_account_owner?
11
+ # Account owners only see Users that are not discarded
12
+ scope.kept
13
+ else
14
+ # Regulars users only see active users
15
+ scope.ua_active
16
+ end
17
+ end
18
+ end
19
+
20
+ def index?
21
+ super && (Current.namespace == :admin || Current.active_user_account.present?)
22
+ end
23
+
24
+ def sign_off?
25
+ user_is_user_account_user? &&
26
+ !record.ua_invite_pending? &&
27
+ !record.profiles.account__owner?
28
+ end
29
+
30
+ def puede_crear?
31
+ Current.namespace == :admin
32
+ end
33
+
34
+ def accept_invitation_link?
35
+ user_is_user_account_user? && record.ua_invite_pending?
36
+ end
37
+
38
+ def ingresar?
39
+ user_is_user_account_user? && record.ua_active?
40
+ end
41
+
42
+ def puede_editar?
43
+ Current.namespace == :admin ||
44
+ (user_is_account_owner? && !record.discarded_by_user? && !record.profiles.account__owner?)
45
+ end
46
+
47
+ def destroy?
48
+ Current.namespace == :admin || (user_is_account_owner? && !record.profiles.account__owner?)
49
+ end
50
+
51
+ def show?
52
+ Current.namespace == :admin || (user_is_account_owner? && !record.profiles.account__owner?)
53
+ end
54
+
55
+ def user_is_account_owner?
56
+ record.account.owner == user
57
+ end
58
+
59
+ def user_is_user_account_user?
60
+ user.id == record.user_id
61
+ end
62
+
63
+ def export?
64
+ false
65
+ end
32
66
  end
@@ -4,6 +4,16 @@
4
4
 
5
5
  class UserPolicy < ApplicationPolicy
6
6
  class Scope < ApplicationPolicy::Scope
7
+ def resolve
8
+ if Current.namespace == :admin
9
+ scope.all
10
+ elsif Current.account.present?
11
+ ids = Current.account.user_accounts.ua_active.pluck(:user_id)
12
+ scope.where(id: ids)
13
+ else
14
+ scope.none
15
+ end
16
+ end
7
17
  end
8
18
 
9
19
  # def puede_editar?
@@ -17,13 +27,16 @@ class UserPolicy < ApplicationPolicy
17
27
  # def puede_borrar?
18
28
  # acceso_total? && !record.readonly?
19
29
  # end
30
+ def puede_editar?
31
+ base_access_to_record?
32
+ end
20
33
 
21
34
  def new_from_associable?
22
35
  false
23
36
  end
24
37
 
25
38
  def base_access_to_record?
26
- user.developer? || user == record
39
+ Current.namespace == :admin || user == record
27
40
  end
28
41
 
29
42
  def base_access_to_collection?
@@ -4,6 +4,6 @@ div style="max-width: 22em"
4
4
  = pg_form_for(@user_account || object) do |f|
5
5
  = f.pg_associable :user, preload: 10
6
6
  = f.pg_associable :account, preload: 5
7
- = f.input :profiles
7
+ = f.input :profiles, as: :check_boxes
8
8
  .mt-2
9
9
  = f.button :submit
@@ -1,3 +1,18 @@
1
+ h5 Permisos
2
+ table.table.table-bordered.w-auto
3
+ tr
4
+ - PgEngine.config.profile_groups_options.each do |profile_group|
5
+ td
6
+ h5.text-center = t(profile_group[:name], scope: 'profile_group')
7
+ hr.mt-2
8
+ - profile_group[:options].each do |values|
9
+ .form-check
10
+ - if @user_account.profiles.include?(values.first)
11
+ = check_box_tag nil, nil, true, disabled: true, class: 'form-check-input'
12
+ - else
13
+ = check_box_tag nil, nil, false, disabled: true, class: 'form-check-input'
14
+ label.form-check-label = values.first
15
+
1
16
  table.table.table-borderless.table-sm.w-auto.mb-0.m-3
2
17
  - atributos_para_mostrar.each do |att|
3
18
  tr
@@ -10,9 +10,6 @@ table.table.table-borderless.table-sm.w-auto.mb-0.m-3
10
10
  tr
11
11
  th = @clase_modelo.human_attribute_name(att)
12
12
  td = @user.send(att)
13
- tr
14
- th = t('attributes.confirmed_at')
15
- td = @user.confirmed_at
16
13
  / tr
17
14
  th = t('attributes.creado_por')
18
15
  td = @user.creado_por
@@ -14,7 +14,7 @@
14
14
  type="button" data-bs-toggle="dropdown" aria-expanded="false"]
15
15
  i.bi.bi-list
16
16
  ul.dropdown-menu
17
- - unless action_name == 'archived'
17
+ - if policy(clase_modelo).archived? && action_name != 'archived'
18
18
  li = link_to [:archived, pg_namespace, nested_record, @clase_modelo].compact,
19
19
  class: 'icon-link dropdown-item' do
20
20
  i.bi.bi-archive-fill.lh-1
@@ -53,12 +53,12 @@
53
53
  tr id="#{dom_id(object)}"
54
54
  td.text-nowrap.xtext-end.xps-5
55
55
  .actions-wrapper
56
+ = object.extra_actions(size: :sm) if object.respond_to? :extra_actions
56
57
  = object.show_link(text: '')
57
58
  = object.edit_link(text: '', klass: 'btn-light')
58
59
  = object.archive_link
59
60
  = object.restore_link
60
61
  = object.destroy_link
61
- = object.extra_actions(size: :sm) if object.respond_to? :extra_actions
62
62
  - atributos_para_listar.each do |att, _sort_field|
63
63
  = column_for object, att
64
64
  - if action_name == 'archived'
@@ -0,0 +1,2 @@
1
+ h1 Dashboard
2
+ h2 = ActsAsTenant.current_tenant
@@ -0,0 +1,13 @@
1
+ / # locals: (f:)
2
+
3
+ h5 Permisos
4
+ table.table.table-bordered.w-auto
5
+ tr
6
+ - PgEngine.config.profile_groups_options.each do |profile_group|
7
+ td
8
+ h5.text-center = t(profile_group[:name], scope: 'profile_group')
9
+ hr.mt-2
10
+ = f.collection_check_boxes :profiles, profile_group[:options], :first, :last do |blo|
11
+ .form-check
12
+ = blo.check_box class: 'form-check-input'
13
+ = blo.label class: 'form-check-label'
@@ -0,0 +1,9 @@
1
+ / # locals: (object: nil)
2
+
3
+ div data-controller="pg_form"
4
+ = pg_form_for(@user_account || object) do |f|
5
+ = render partial: 'tenant/user_accounts/fields', locals: { f: }
6
+ = f.input :membership_status, as: :radio_buttons
7
+
8
+ .mt-2
9
+ = f.button :submit
@@ -0,0 +1,20 @@
1
+ h1 = @user_account
2
+
3
+ p = @user_account.user_email_f
4
+
5
+ = @user_account.estado_f
6
+
7
+ h5.mt-4 Permisos
8
+ table.table.table-bordered.w-auto
9
+ tr
10
+ - PgEngine.config.profile_groups_options.each do |profile_group|
11
+ td
12
+ h5.text-center = t(profile_group[:name], scope: 'profile_group')
13
+ hr.mt-2
14
+ - profile_group[:options].each do |values|
15
+ .form-check
16
+ - if @user_account.profiles.include?(values.first)
17
+ = check_box_tag nil, nil, true, disabled: true, class: 'form-check-input'
18
+ - else
19
+ = check_box_tag nil, nil, false, disabled: true, class: 'form-check-input'
20
+ label.form-check-label = values.last
@@ -0,0 +1,7 @@
1
+ div style="max-width: 22em"
2
+ = pg_form_for(@account || object) do |f|
3
+ = f.input :nombre
4
+ = f.input :plan
5
+ = f.input :logo
6
+ .mt-2
7
+ = f.button :submit
@@ -1,15 +1,23 @@
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 Email
10
- th Roles
11
- - @account.user_accounts.kept.each do |user_account|
12
- tr
13
- td = user_account.user
14
- td = user_account.user.email
15
- td = user_account.profiles.texts.join(', ')
1
+ - content_for :actions do
2
+ = @user_account.ingresar_link
3
+ = @user_account.sign_off_link
4
+
5
+ .text-center
6
+ - if @account.logo.present?
7
+ = image_tag @account.logo
8
+ h1
9
+ = @account
10
+
11
+ / h6
12
+ |> Administrado por:
13
+ = @account.owner.nombre_completo
14
+ |< (
15
+ = @account.owner.email
16
+ | )
17
+
18
+ - if @user_account.membership_status.ms_disabled?
19
+ p.text-danger Deshabilitado
20
+
21
+ - if @account.owner == Current.user
22
+ = turbo_frame_tag 'embedded__user_accounts',
23
+ src: tenant_user_accounts_path(tid: Current.user.user_account_for(@account).to_param)
@@ -9,8 +9,13 @@ end
9
9
 
10
10
  SET_TENANT_PROC = lambda do
11
11
  if defined?(Rails::Console)
12
- puts "> ActsAsTenant.current_tenant = Account.first"
13
- ActsAsTenant.current_tenant = Account.first
12
+ if ENV['SET_DEFAULT_TENANT_ON_DEV'].present?
13
+ puts "> ActsAsTenant.current_tenant = Account.first"
14
+ ActsAsTenant.current_tenant = Account.first
15
+ else
16
+ puts "> ActsAsTenant.unscoped = true"
17
+ ActsAsTenant.unscoped = true
18
+ end
14
19
  end
15
20
  end
16
21
 
@@ -310,4 +310,14 @@ Devise.setup do |config|
310
310
  # When set to false, does not sign a user in automatically after their password is
311
311
  # changed. Defaults to true, so a user is signed in automatically after changing a password.
312
312
  # config.sign_in_after_change_password = true
313
+
314
+ # ==> Configuration for :invitable
315
+ # The period the generated invitation token is valid.
316
+ # After this period, the invited resource won't be able to accept the invitation.
317
+ # When invite_for is 0 (the default), the invitation won't expire.
318
+ config.invite_for = 2.weeks
319
+
320
+ # Dont require nombre y apellido on invite
321
+ # config.validate_on_invite = true
322
+ config.require_password_on_accepting = true
313
323
  end
@@ -53,4 +53,6 @@ Ransack.configure do |config|
53
53
  arel_predicate: 'does_not_match_unaccent',
54
54
  formatter: proc { |v| "%#{Ransack::Constants.escape_wildcards(v.downcase)}%" },
55
55
  case_insensitive: true
56
+
57
+ config.add_predicate 'arr_cont', arel_predicate: 'contains', formatter: proc { |v| [v] }
56
58
  end
@@ -1,8 +1,20 @@
1
1
  es:
2
+ profile_group:
3
+ account: Cuenta
4
+ user_accounts: Usuarios
5
+ profile_member:
6
+ owner: Administrador
7
+ read: Ver
8
+ update: Modificar
9
+ create: Crear
10
+ archive: Archivar
11
+ destroy: Eliminar
12
+ export: Exportar
2
13
  ransack:
3
14
  predicates:
4
15
  cont: ''
5
16
  cont_all: ''
17
+ arr_cont: ''
6
18
  cont_any: ''
7
19
  not_cont: 'no contiene'
8
20
  in: ''
@@ -28,6 +40,15 @@ es:
28
40
  creado_por: Creado por
29
41
  accept_terms: Acepto los <a href="/terminos_y_condiciones" target="_blank">Términos y condiciones</a> y la <a href="/privacidad" target="_blank">Política de privacidad</a>
30
42
  enumerize:
43
+ user_account:
44
+ membership_status:
45
+ ms_active: Habilitado
46
+ ms_disabled: Deshabilitado
47
+ invitation_status:
48
+ ist_invited: Invitación aún no aceptada
49
+ ist_accepted: Invitación aceptada
50
+ ist_rejected: Invitación rechazada
51
+ ist_signed_off: Salió de la cuenta
31
52
  email:
32
53
  status:
33
54
  pending: Enviando
@@ -77,6 +98,19 @@ es:
77
98
  sign_in: ¿Ya tenés una cuenta? Iniciar sesión
78
99
  sign_out: Cerrar sesión
79
100
  sign_up: Crear una cuenta
101
+ invitations:
102
+ send_instructions: "Se envió una invitación a %{email}"
103
+ invitation_token_invalid: "¡La invitación no es válida!"
104
+ updated: ""
105
+ updated_not_active: ""
106
+ no_invitations_remaining: "No quedan invitaciones"
107
+ invitation_removed: "Se ha retirado su invitación"
108
+ new:
109
+ header: "Agregar usuario"
110
+ submit_button: "Agregar"
111
+ edit:
112
+ header: "Aceptar invitación"
113
+ submit_button: "Aceptar"
80
114
  confirmations:
81
115
  confirmed: ¡Tu cuenta está confirmada! Ya podés iniciar sesión
82
116
  sessions:
@@ -87,6 +121,7 @@ es:
87
121
  already_authenticated: ''
88
122
  timeout: ''
89
123
  unauthenticated: ''
124
+ invited: "Tenés una invitación pendiente en tu correo electrónico"
90
125
  registrations:
91
126
  signed_up_but_unconfirmed: Te enviamos un correo electrónico con instrucciones para confirmar tu cuenta.
92
127
  new:
@@ -103,6 +138,13 @@ es:
103
138
  forgot_your_password: ¿Olvidaste tu contraseña?
104
139
  didn_t_receive_confirmation_instructions: ¿No recibiste las instrucciones para confirmar tu cuenta?
105
140
  mailer:
141
+ invitation_instructions:
142
+ subject: "Recibiste una invitación de %{inviter}"
143
+ hello: "Hola %{email}"
144
+ someone_invited_you: "Has sido invitado a %{url}, puedes aceptarlo siguiendo el siguiente enlace"
145
+ accept: "Aceptar la invitación"
146
+ accept_until: "Esta invitación expirará en %{due_date}."
147
+ ignore: "Si no le interesa esta invitación, simplemente ignore este correo. No se creará tu cuenta hasta que accedas al enlace anterior y crees una contraseña."
106
148
  confirmation_instructions:
107
149
  action: Confirmá tu cuenta
108
150
  greeting: "Hola %{recipient}"
@@ -125,9 +167,27 @@ es:
125
167
  instruction_3: Tu contraseña no será cambiada hasta que accedas al link y crees una nueva.
126
168
  subject: Recuperación de contraseña
127
169
  activerecord:
170
+ models:
171
+ user_account:
172
+ one: Cuenta de usuario
173
+ other: Cuentas de usuario
174
+ account:
175
+ one: Espacio
176
+ other: Espacios
177
+ user:
178
+ one: Usuario
179
+ other: Usuarios
128
180
  attributes:
181
+ account:
182
+ owner: Administrado por
183
+ user_account:
184
+ membership_status: Estado
185
+ user: Nombre
186
+ user_email: Email
187
+ profiles: Permisos
129
188
  user:
130
189
  remember_me: Recordarme en este navegador
190
+ avatar: Foto de perfil
131
191
  email:
132
192
  from_name: Remitente
133
193
  to: Destinatario
@@ -18,27 +18,37 @@ Rails.application.routes.draw do
18
18
 
19
19
  devise_for :users, controllers: {
20
20
  confirmations: 'users/confirmations',
21
- registrations: 'users/registrations'
21
+ registrations: 'users/registrations',
22
+ invitations: 'users/invitations'
22
23
  }, failure_app: PgEngine::DeviseFailureApp
24
+
23
25
  namespace :users, path: 'u' do
26
+ post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
27
+ post 'notifications/mark_as_unseen', to: 'notifications#mark_as_unseen'
28
+ get 'date_jumper/jump'
29
+ pg_resource(:accounts, path: 'espacios', only: [:index, :show, :new, :create, :edit, :update]) do
30
+ member do
31
+ put :update_invitation
32
+ end
33
+ end
34
+
35
+ root to: 'accounts#index'
36
+ end
37
+
38
+ namespace :tenant, path: 'u/t(/:tid)' do
39
+ pg_resource(:user_accounts, only: [:index, :show, :edit, :update, :destroy])
24
40
  scope controller: 'inline_edit', path: 'inline', as: :inline do
25
41
  get 'edit'
26
42
  get 'show'
27
43
  end
28
44
  get 'dashboard', to: 'dashboard#dashboard'
29
- post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
30
- post 'notifications/mark_as_unseen', to: 'notifications#mark_as_unseen'
31
- get 'date_jumper/jump'
32
- scope controller: 'account_switcher', path: 'switcher' do
33
- get '', action: 'list', as: 'account_switcher'
34
- post ':user_account_id', action: 'switch', as: 'account_switch'
35
- end
36
45
 
37
- pg_resource(:accounts, path: 'cuentas', only: [:show])
38
- # get 'account', to: 'accounts#show'
46
+ # get '/u', to: 'users/dashboard#dashboard', as: :users_root
47
+ root to: 'dashboard#dashboard'
39
48
  end
40
49
 
41
- get '/u', to: 'users/dashboard#dashboard', as: :users_root
50
+ # root to: 'users/accounts#index'
51
+ root to: redirect('/u')
42
52
 
43
53
  namespace :admin, path: 'a' do
44
54
  pg_resource(:emails)
@@ -92,7 +92,7 @@ SimpleForm.setup do |config|
92
92
  tag: 'fieldset', class: 'mb-3' do |b|
93
93
  b.use :html5
94
94
  b.optional :readonly
95
- b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
95
+ b.wrapper :legend_tag, tag: 'div', class: 'col-form-label pt-0' do |ba|
96
96
  ba.use :label_text
97
97
  end
98
98
  b.use :input, class: 'form-check-input', error_class: 'is-invalid'
@@ -105,7 +105,7 @@ SimpleForm.setup do |config|
105
105
  item_label_class: 'form-check-label', tag: 'fieldset', class: 'mb-3' do |b|
106
106
  b.use :html5
107
107
  b.optional :readonly
108
- b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
108
+ b.wrapper :legend_tag, tag: 'div', class: 'col-form-label pt-0' do |ba|
109
109
  ba.use :label_text
110
110
  end
111
111
  b.use :input, class: 'form-check-input', error_class: 'is-invalid'
@@ -0,0 +1,14 @@
1
+ class DeviseInvitable < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :users, :invitation_token, :string
4
+ add_column :users, :invitation_created_at, :datetime
5
+ add_column :users, :invitation_sent_at, :datetime
6
+ add_column :users, :invitation_accepted_at, :datetime
7
+ add_column :users, :invitation_limit, :integer
8
+ add_column :users, :invited_by_id, :integer
9
+ add_column :users, :invited_by_type, :string
10
+ add_index :users, :invitation_token, unique: true
11
+ change_column_null :users, :nombre, true
12
+ change_column_null :users, :apellido, true
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ class AddMembershipStatusToUserAccounts < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :user_accounts, :membership_status, :integer, null: false, default: 1
4
+ add_column :user_accounts, :invitation_status, :integer, null: false, default: 1
5
+ end
6
+ end
@@ -2,15 +2,15 @@ DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
2
2
 
3
3
  bien = FactoryBot.create(:account, nombre: 'Bien', subdomain: 'bien')
4
4
  rosso = FactoryBot.create(:user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
5
- confirmed_at: Time.now, developer: true, orphan: true)
5
+ confirmed_at: Time.now, developer: true)
6
6
 
7
- bien.user_accounts.create(user: rosso, profiles: [:administracion])
7
+ bien.user_accounts.create!(user: rosso, profiles: [:account__owner])
8
8
 
9
9
  racionalismo = FactoryBot.create(:account, nombre: 'Racionalismo', subdomain: 'racionalismo')
10
10
  baruch = FactoryBot.create(:user, email: 'baruch@bien.com', nombre: 'Baruch', apellido: 'Spinoza', password: 'admin123',
11
- confirmed_at: Time.now, orphan: true)
11
+ confirmed_at: Time.now)
12
12
  rené = FactoryBot.create(:user, email: 'rene@bien.com', nombre: 'René', apellido: 'Descartes', password: 'admin123',
13
- confirmed_at: Time.now, orphan: true)
13
+ confirmed_at: Time.now)
14
14
 
15
- racionalismo.user_accounts.create(user: baruch, profiles: [:administracion])
16
- racionalismo.user_accounts.create(user: rené, profiles: [:operacion])
15
+ racionalismo.user_accounts.create!(user: baruch, profiles: [:account__owner])
16
+ racionalismo.user_accounts.create!(user: rené, profiles: [])