pg_rails 7.6.20 → 7.6.21.pre.1

Sign up to get free protection for your applications and to get access to all the features.
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 +21 -3
  35. data/pg_engine/app/models/pg_engine/base_record.rb +5 -0
  36. data/pg_engine/app/models/user.rb +51 -9
  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 +6 -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
@@ -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: [:cosas__read])