pg_rails 7.6.21.pre.2 → 7.6.21.pre.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +1 -0
  3. data/pg_associable/app/inputs/pg_associable_input.rb +1 -0
  4. data/pg_associable/spec/system/associable_spec.rb +4 -5
  5. data/pg_engine/app/controllers/users/accounts_controller.rb +20 -1
  6. data/pg_engine/app/controllers/users/invitations_controller.rb +2 -0
  7. data/pg_engine/app/decorators/account_decorator.rb +8 -8
  8. data/pg_engine/app/decorators/user_account_decorator.rb +7 -4
  9. data/pg_engine/app/helpers/pg_engine/flash_helper.rb +2 -1
  10. data/pg_engine/app/mailers/pg_engine/base_devise_mailer.rb +9 -0
  11. data/pg_engine/app/mailers/pg_engine/user_mailer.rb +2 -0
  12. data/pg_engine/app/models/account.rb +2 -1
  13. data/pg_engine/app/models/current.rb +1 -0
  14. data/pg_engine/app/models/user.rb +8 -0
  15. data/pg_engine/app/models/user_account.rb +1 -1
  16. data/pg_engine/app/policies/pg_engine/base_policy.rb +8 -8
  17. data/pg_engine/app/views/users/accounts/_form.html.slim +1 -1
  18. data/pg_engine/app/views/users/accounts/show.html.slim +5 -4
  19. data/pg_engine/config/initializers/devise.rb +1 -1
  20. data/pg_engine/config/locales/es.yml +3 -2
  21. data/pg_engine/db/migrate/20241027225618_add_membership_status_to_user_accounts.rb +7 -0
  22. data/pg_engine/lib/pg_engine/engine.rb +9 -0
  23. data/pg_engine/spec/factories/users.rb +5 -2
  24. data/pg_engine/spec/mailers/previews/devise_preview.rb +6 -0
  25. data/pg_engine/spec/models/user_spec.rb +0 -4
  26. data/pg_layout/app/views/devise/mailer/invitation_instructions.html.erb +3 -5
  27. data/pg_layout/app/views/devise/mailer/invitation_instructions.text.erb +3 -5
  28. data/pg_layout/app/views/layouts/pg_layout/base.html.slim +2 -3
  29. data/pg_layout/app/views/layouts/pg_layout/containerized.html.slim +1 -1
  30. data/pg_layout/app/views/layouts/pg_layout/devise_mailer.html.slim +12 -0
  31. data/pg_layout/app/views/layouts/pg_layout/devise_mailer.text.erb +7 -0
  32. data/pg_layout/app/views/pg_layout/_navbar.html.slim +50 -0
  33. data/pg_layout/app/views/pg_layout/_sidebar.html.slim +10 -0
  34. data/pg_layout/app/views/pg_layout/_sidebar_mobile.html.slim +16 -0
  35. data/pg_layout/app/views/pg_layout/_signed_in_links.html.slim +53 -51
  36. data/pg_rails/lib/version.rb +1 -1
  37. metadata +8 -5
  38. data/pg_layout/app/views/pg_layout/_navbar.html.erb +0 -52
  39. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +0 -24
  40. data/pg_layout/app/views/pg_layout/_sidebar_mobile.html.erb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6698336321ce3bb886aa1de70219bab209e2f8b2f1b3f867282a29f1f1ebf5a5
4
- data.tar.gz: fae76eef1209ba3e463740c8818ebd406a0b387eab151d964519fe0f5a389cec
3
+ metadata.gz: 52db938b6aad2006d1815247f8b3f1c4bd297b811ca50db7e800760967942045
4
+ data.tar.gz: 1a095d3501f50d2b3fa9b123bb62a42e5c3472a1f679b4adf5932716f51693de
5
5
  SHA512:
6
- metadata.gz: 55b7bc4417466c09110d4e48c4ee7355fdfc7bcf8e153592f9e0418fe518803953b73a6c3584274992aa3624cf6073b0ddab327e9971d7bb17923fbd176322ed
7
- data.tar.gz: c51ce96d9af18a24111adc2130ae196290df313198561b4d6b23f59447b6d5d7762c5907bb1bcac59c7aabfbfc439b75324e06901d48de98181462b95c7e4582
6
+ metadata.gz: ab9d327f91d9153cf8e2ebc1e602510db545f1f086a23fb7d1ced3f5480b234f0b231327930b3707f972a5524cff80796488d3a762df95ed5d0ad649f52dd21c
7
+ data.tar.gz: 2ca7ae67777a8bac52b5f63642e52d3436fd094c166a97f2c84417bdfcd3305d9f5b5e6a286e2fbd4a655035a69049ddff6ab72ec83abbc6dc5853808ad9d8a9
@@ -2,6 +2,7 @@
2
2
  module PgAssociable
3
3
  module FormBuilderMethods
4
4
  def self.included(mod)
5
+ mod.include PgEngine::DefaultUrlOptions
5
6
  mod.include Rails.application.routes.url_helpers
6
7
  mod.include PgEngine::RouteHelper
7
8
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  class PgAssociableInput < SimpleForm::Inputs::StringInput
4
4
  include ActionView::Helpers::FormTagHelper
5
+ include PgEngine::DefaultUrlOptions
5
6
  include Rails.application.routes.url_helpers
6
7
  include PgEngine::RouteHelper
7
8
 
@@ -1,9 +1,9 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe 'Associable' do
4
- let(:user) { create :user, :developer }
4
+ let(:user) { create :user, :owner }
5
5
 
6
- let(:path) { '/a/cosas/new' }
6
+ let(:path) { '/u/t/cosas/new' }
7
7
 
8
8
  before do
9
9
  login_as user
@@ -16,7 +16,6 @@ describe 'Associable' do
16
16
  find('.cosa_categoria_de_cosa input[type=text]').click
17
17
  expect(page).to have_text :all, 'Nueva categoría de cosa'
18
18
  find('.cosa_categoria_de_cosa .list-group-item').click
19
- select Account.first.to_s
20
19
  fill_in 'categoria_de_cosa_nombre', with: 'la categoría'
21
20
  select 'Completar', from: 'categoria_de_cosa_tipo'
22
21
  click_on 'Agregar Categoría de cosa'
@@ -26,7 +25,7 @@ describe 'Associable' do
26
25
 
27
26
  context 'cuando crea desde el nested' do
28
27
  let!(:categ) { create :categoria_de_cosa }
29
- let(:path) { "/a/categoria_de_cosas/#{categ.hashid}/cosas/new" }
28
+ let(:path) { "/u/t/categoria_de_cosas/#{categ.hashid}/cosas/new" }
30
29
 
31
30
  it do
32
31
  input = find_by_id('cosa_categoria_de_cosa')
@@ -37,7 +36,7 @@ describe 'Associable' do
37
36
  context 'cuando edita desde el nested' do
38
37
  let!(:categ) { create :categoria_de_cosa }
39
38
  let!(:cosa) { create :cosa, categoria_de_cosa: categ }
40
- let(:path) { "/a/categoria_de_cosas/#{categ.hashid}/cosas/#{cosa.id}/edit" }
39
+ let(:path) { "/u/t/categoria_de_cosas/#{categ.hashid}/cosas/#{cosa.id}/edit" }
41
40
 
42
41
  it do
43
42
  ele = find_by_id('cosa_categoria_de_cosa_id', visible: :all)
@@ -17,6 +17,25 @@ module Users
17
17
 
18
18
  add_breadcrumb Account.model_name.human(count: 2), ->(h) { h.users_accounts_path(tid: nil) }
19
19
 
20
+ layout :set_layout
21
+ def set_layout
22
+ if action_name == 'index'
23
+ 'pg_layout/containerized'
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ before_action do
30
+ if action_name.in? %w[index]
31
+ @container_class = 'container border p-0 my-3'
32
+ @container_style = 'max-width: 50em; xborder-left: 1px solid grey'
33
+ elsif action_name.in? %w[edit update]
34
+ @container_class = 'container border pb-3 my-3'
35
+ @container_style = 'max-width: 50em; xborder-left: 1px solid grey'
36
+ end
37
+ end
38
+
20
39
  # La user_account puede estar disabled
21
40
  def show
22
41
  add_breadcrumb @account, users_account_path(@account, tid: nil)
@@ -56,7 +75,7 @@ module Users
56
75
  end
57
76
 
58
77
  def atributos_para_listar
59
- %i[nombre plan owner]
78
+ %i[nombre owner]
60
79
  end
61
80
  end
62
81
  end
@@ -10,6 +10,8 @@ module Users
10
10
  add_breadcrumb 'Agregar usuario'
11
11
  @sidebar = false
12
12
  @no_main_frame = true
13
+ @container_class = 'container border pb-3 my-3'
14
+ @container_style = 'max-width: 50em; xborder-left: 1px solid grey'
13
15
  end
14
16
 
15
17
  def new
@@ -22,13 +22,13 @@ class AccountDecorator < PgEngine::BaseRecordDecorator
22
22
  ua.reject_invitation_link].compact.join.html_safe
23
23
  end
24
24
 
25
- # def show_link(text: '', klass: 'btn-light')
26
- # return unless Pundit.policy!(Current.user, object).show?
25
+ def show_link(text: 'Usuarios', klass: 'btn-secondary')
26
+ return unless Pundit.policy!(Current.user, object).show?
27
27
 
28
- # helpers.content_tag :span, 'data-controller': :tooltip, title: 'Más opciones' do
29
- # helpers.link_to object_url, class: "btn btn-sm #{klass}" do
30
- # helpers.content_tag(:span, nil, class: clase_icono('list')) + text
31
- # end
32
- # end
33
- # end
28
+ helpers.content_tag :span do
29
+ helpers.link_to object_url, class: "btn btn-sm #{klass}" do
30
+ helpers.content_tag(:span, nil, class: clase_icono('person')) + text
31
+ end
32
+ end
33
+ end
34
34
  end
@@ -8,10 +8,13 @@ class UserAccountDecorator < PgEngine::BaseRecordDecorator
8
8
  def ingresar_link
9
9
  return unless Pundit.policy!(Current.user, object).ingresar?
10
10
 
11
- h.link_to h.tenant_root_path(tid: object.to_param),
12
- 'data-turbo-frame': :_top,
13
- class: 'btn btn-sm btn-primary' do
14
- '<i class="bi bi-box-arrow-in-right"></i> Ingresar'.html_safe
11
+ # El span es necesario para que el tamaño de los botones sea homogéneo
12
+ helpers.content_tag :span do
13
+ h.link_to h.tenant_root_path(tid: object.to_param),
14
+ 'data-turbo-frame': :_top,
15
+ class: 'btn btn-sm btn-primary' do
16
+ '<i class="bi bi-box-arrow-in-right"></i> Ingresar'.html_safe
17
+ end
15
18
  end
16
19
  end
17
20
 
@@ -9,7 +9,8 @@ module PgEngine
9
9
  end
10
10
 
11
11
  def render_turbo_stream_title
12
- title = [breadcrumbs.last&.name, ActsAsTenant.current_tenant, I18n.t('app_name')].compact.join(' - ')
12
+ title = [breadcrumbs.last&.name, ActsAsTenant.current_tenant,
13
+ I18n.t(Current.app_name, scope: 'app_name')].compact.join(' - ')
13
14
  turbo_stream.update_all 'title', title
14
15
  end
15
16
  end
@@ -0,0 +1,9 @@
1
+ module PgEngine
2
+ class BaseDeviseMailer < ApplicationMailer
3
+ before_action do
4
+ @footer_image_src = 'mail-footer-lg.png'
5
+ end
6
+
7
+ layout 'pg_layout/devise_mailer'
8
+ end
9
+ end
@@ -9,6 +9,8 @@ module PgEngine
9
9
  mail(to: @recipient.email, subject: params[:subject])
10
10
  end
11
11
 
12
+ private
13
+
12
14
  def replace_user(input)
13
15
  # reemplaza todas las ocurrencias de: %{user}
14
16
  format(input, user: @recipient.nombre)
@@ -30,7 +30,7 @@ class Account < ApplicationRecord
30
30
  belongs_to :creado_por, optional: true, class_name: 'User'
31
31
  belongs_to :actualizado_por, optional: true, class_name: 'User'
32
32
 
33
- enumerize :plan, in: { completar: 0, los: 1, valores: 2 }
33
+ enumerize :plan, in: { factura: 0, procura: 1 }
34
34
 
35
35
  validates :plan, :nombre, presence: true
36
36
 
@@ -61,6 +61,7 @@ class Account < ApplicationRecord
61
61
  end
62
62
 
63
63
  def to_s
64
+ # TODO: nombre_in_database?
64
65
  nombre
65
66
  end
66
67
 
@@ -1,5 +1,6 @@
1
1
  class Current < ActiveSupport::CurrentAttributes
2
2
  attribute :user, :namespace, :controller, :active_user_account
3
+ attribute :app_name, default: :procura
3
4
  # attribute :request_id, :user_agent, :ip_address
4
5
 
5
6
  # resets { Time.zone = nil }
@@ -89,6 +89,14 @@ class User < ApplicationRecord
89
89
  user_accounts.first.invitation_status = :ist_invited
90
90
  end
91
91
 
92
+ def invited_to_app
93
+ user_accounts.first.account.plan || 'procura'
94
+ rescue StandardError => e
95
+ pg_err(e)
96
+
97
+ 'procura'
98
+ end
99
+
92
100
  attr_accessor :orphan
93
101
 
94
102
  def active_for_authentication?
@@ -39,7 +39,7 @@ class UserAccount < ApplicationRecord
39
39
  belongs_to :creado_por, optional: true, class_name: 'User'
40
40
  belongs_to :actualizado_por, optional: true, class_name: 'User'
41
41
 
42
- validates :user_id, uniqueness: { scope: :account_id }
42
+ validates_uniqueness_to_tenant :user_id
43
43
 
44
44
  after_destroy :cleanup_invitation
45
45
  def cleanup_invitation
@@ -82,15 +82,15 @@ module PgEngine
82
82
  end
83
83
 
84
84
  def puede_editar?
85
- user_has_profile(:update)
85
+ user_has_profile?(:update)
86
86
  end
87
87
 
88
88
  def puede_crear?
89
- user_has_profile(:create)
89
+ user_has_profile?(:create)
90
90
  end
91
91
 
92
92
  def puede_borrar?
93
- user_has_profile(:destroy)
93
+ user_has_profile?(:destroy)
94
94
  end
95
95
 
96
96
  def puede_ver_archivados?
@@ -98,19 +98,19 @@ module PgEngine
98
98
  model = record.is_a?(ActiveRecord::Base) ? record.class : record
99
99
  model.respond_to?(:discarded)
100
100
  end
101
- user_has_profile(:archive) && admits_discard
101
+ user_has_profile?(:archive) && admits_discard
102
102
  end
103
103
 
104
104
  def base_access_to_record?
105
- user_has_profile(:read)
105
+ user_has_profile?(:read)
106
106
  end
107
107
 
108
108
  def base_access_to_collection?
109
- user_has_profile(:read)
109
+ user_has_profile?(:read)
110
110
  end
111
111
 
112
112
  def export?
113
- user_has_profile(:export)
113
+ user_has_profile?(:export)
114
114
  end
115
115
 
116
116
  def record_discarded?
@@ -125,7 +125,7 @@ module PgEngine
125
125
  record.model_name.plural
126
126
  end
127
127
 
128
- def user_has_profile(key)
128
+ def user_has_profile?(key)
129
129
  return true if Current.namespace == :admin
130
130
  return false if ActsAsTenant.current_tenant.blank?
131
131
 
@@ -1,7 +1,7 @@
1
1
  div style="max-width: 22em"
2
2
  = pg_form_for(@account || object) do |f|
3
3
  = f.input :nombre
4
- = f.input :plan
4
+ / = f.input :plan
5
5
  = f.input :logo
6
6
  .mt-2
7
7
  = f.button :submit
@@ -3,10 +3,11 @@
3
3
  = @user_account.sign_off_link
4
4
 
5
5
  .text-center
6
- - if @account.logo.present?
7
- = image_tag @account.logo
8
- h1
9
- = @account
6
+ .d-flex.justify-content-center.gap-2.align-items-center.m-3
7
+ - if @account.logo.present?
8
+ = image_tag @account.logo, style: 'max-height:3em'
9
+ .fs-1
10
+ = @account
10
11
 
11
12
  / h6
12
13
  |> Administrado por:
@@ -30,7 +30,7 @@ Devise.setup do |config|
30
30
  # config.mailer = 'Devise::Mailer'
31
31
 
32
32
  # Configure the parent class responsible to send e-mails.
33
- config.parent_mailer = 'ApplicationMailer'
33
+ config.parent_mailer = 'PgEngine::BaseDeviseMailer'
34
34
 
35
35
  # ==> ORM configuration
36
36
  # Load and configure the ORM. Supports :active_record (default) and
@@ -141,10 +141,11 @@ es:
141
141
  invitation_instructions:
142
142
  subject: "Recibiste una invitación de %{inviter}"
143
143
  hello: "Hola %{email}"
144
- someone_invited_you: "Has sido invitado a %{url}, puedes aceptarlo siguiendo el siguiente enlace"
144
+ someone_invited_you: "Hola! %{inviter} te invitó a su espacio en %{app_name}"
145
+ follow_link: "Podés aceptar la invitación en el siguiente link:"
145
146
  accept: "Aceptar la invitación"
146
147
  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."
148
+ ignore: "Si no te interesa esta invitación, simplemente ignora este correo. No se creará tu cuenta hasta que accedas al enlace anterior."
148
149
  confirmation_instructions:
149
150
  action: Confirmá tu cuenta
150
151
  greeting: "Hola %{recipient}"
@@ -3,4 +3,11 @@ class AddMembershipStatusToUserAccounts < ActiveRecord::Migration[7.2]
3
3
  add_column :user_accounts, :membership_status, :integer, null: false, default: 1
4
4
  add_column :user_accounts, :invitation_status, :integer, null: false, default: 1
5
5
  end
6
+
7
+ def migrate(direction)
8
+ if direction == :up
9
+ UserAccount.update_all(profiles: [0])
10
+ end
11
+ super
12
+ end
6
13
  end
@@ -20,6 +20,15 @@ module PgEngine
20
20
  load override
21
21
  end
22
22
 
23
+ # TODO!: mover a otro lugar?
24
+ Devise.mailer.class_eval do
25
+ def invitation_instructions(record, token, opts = {})
26
+ @token = token
27
+ opts.merge!(subject: I18n.t('devise.mailer.invitation_instructions.subject', inviter: record.invited_by))
28
+ devise_mail(record, :invitation_instructions, opts)
29
+ end
30
+ end
31
+
23
32
  ActiveStorage::BaseController.class_eval do
24
33
  around_action :set_without_tenant
25
34
 
@@ -70,8 +70,11 @@ FactoryBot.define do
70
70
  end
71
71
 
72
72
  trait :owner do
73
- user_accounts do
74
- [build(:user_account, account: ActsAsTenant.current_tenant, profiles: [:account__owner])]
73
+ after(:create) do |model|
74
+ model.user_accounts.create!(profiles: [:account__owner])
75
+ # ActsAsTenant.with_tenant(create(:account)) do
76
+ # model.user_accounts.create!(profiles: [:account__owner])
77
+ # end
75
78
  end
76
79
  end
77
80
  end
@@ -10,4 +10,10 @@ class DevisePreview < ActionMailer::Preview
10
10
  # ClienteMailer.comprobante_recibido(VComprobante.find(params[:]))
11
11
  Devise::Mailer.reset_password_instructions(User.first, 'TOKENN')
12
12
  end
13
+
14
+ def invitation
15
+ # ClienteMailer.comprobante_recibido(VComprobante.find(params[:]))
16
+ invitee = User.invitation_not_accepted.first
17
+ Devise::Mailer.invitation_instructions(invitee, 'TOKENN')
18
+ end
13
19
  end
@@ -13,10 +13,6 @@ RSpec.describe User do
13
13
  expect(UserAccount.first.profiles).to include(:account__owner)
14
14
  end
15
15
 
16
- it do
17
- expect(user.default_account).to be_present
18
- end
19
-
20
16
  describe 'search ransacker' do
21
17
  it 'searchs' do
22
18
  results = described_class.ransack(search_cont: user.nombre).result.to_a
@@ -1,11 +1,9 @@
1
- <p><%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %></p>
1
+ <p><%= t("devise.mailer.invitation_instructions.someone_invited_you", inviter: @resource.invited_by, app_name: I18n.t(@resource.invited_to_app, scope: 'app_name')) %></p>
2
2
 
3
- <p><%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %></p>
3
+ <p><%= t("devise.mailer.invitation_instructions.follow_link") %></p>
4
4
 
5
5
  <p><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token) %></p>
6
6
 
7
- <% if @resource.invitation_due_at %>
7
+ <% if false # @resource.invitation_due_at %>
8
8
  <p><%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %></p>
9
9
  <% end %>
10
-
11
- <p><%= t("devise.mailer.invitation_instructions.ignore") %></p>
@@ -1,11 +1,9 @@
1
- <%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %>
1
+ <%= t("devise.mailer.invitation_instructions.someone_invited_you", inviter: @resource.invited_by, app_name: I18n.t(@resource.invited_to_app, scope: 'app_name')) %>
2
2
 
3
- <%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %>
3
+ <%= t("devise.mailer.invitation_instructions.follow_link") %>
4
4
 
5
5
  <%= accept_invitation_url(@resource, invitation_token: @token) %>
6
6
 
7
- <% if @resource.invitation_due_at %>
7
+ <% if false # @resource.invitation_due_at %>
8
8
  <%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %>
9
9
  <% end %>
10
-
11
- <%= t("devise.mailer.invitation_instructions.ignore") %>
@@ -9,7 +9,7 @@ html
9
9
  meta name="turbo-visit-control" content="reload"
10
10
 
11
11
  - cache :title_icon
12
- title = t('app_name')
12
+ title = t(Current.app_name, scope: 'app_name')
13
13
  - begin
14
14
  = render partial: 'layouts/favicon'
15
15
  - rescue ActionView::MissingTemplate => e
@@ -53,8 +53,7 @@ html
53
53
  body
54
54
  span#tid.d-none data-tid="#{Current.tid}"
55
55
  - sidebar_present = @navbar.present? && @sidebar != false
56
- - if sidebar_present
57
- = render partial: 'pg_layout/sidebar_mobile'
56
+ = render partial: 'pg_layout/sidebar_mobile'
58
57
 
59
58
  div class="#{ 'with-sidebar' if sidebar_present }"
60
59
  - if sidebar_present
@@ -1,5 +1,5 @@
1
1
  - content_for :content do
2
- div class="pt-3 #{modal_targeted? ? '' : 'container-fluid'}"
2
+ div class="pt-3 #{modal_targeted? ? '' : @container_class || 'container-fluid'}" style=@container_style
3
3
  = content_for?(:containerized_content) ? yield(:containerized_content) : yield
4
4
 
5
5
  = render template: 'layouts/pg_layout/base'
@@ -0,0 +1,12 @@
1
+ html
2
+ body style="font-family: sans-serif"
3
+ center
4
+ = yield
5
+
6
+ - if @footer_href.present?
7
+ footer style="margin-top: 2em;"
8
+ = link_to @footer_href, rel: 'noreferrer', target: :_blank do
9
+ - if @footer_image_src.present?
10
+ = image_tag @footer_image_src, alt: @footer_image_alt
11
+ - else
12
+ = @footer_image_alt
@@ -0,0 +1,7 @@
1
+ <%= yield %>
2
+
3
+ <% if @footer_href.present? %>
4
+ ----------------------
5
+ <%= @footer_image_alt %>
6
+ <%= @footer_href %>
7
+ <% end %>
@@ -0,0 +1,50 @@
1
+ nav class="navbar navbar-expand-#{@breakpoint_navbar_expand}" data-bs-theme="dark"
2
+ .container-fluid.xgap-2
3
+ div
4
+ - unless @sidebar == false
5
+ button data-controller="navbar" data-action="navbar#expandNavbar" class="btn btn-outline-light me-2 d-none d-#{@breakpoint_navbar_expand}-inline-block"
6
+ i class="bi #{@navbar_chevron_class}"
7
+ - if @navbar.logo.present?
8
+ span.ms-3
9
+ = render @navbar.logo
10
+ - if user_signed_in? && @notifications_bell.present?
11
+ div class="d-#{@breakpoint_navbar_expand}-none"
12
+ = render @notifications_bell
13
+ div
14
+ - if user_signed_in?
15
+ .collapse.navbar-collapse.justify-content-end
16
+ = render partial: 'pg_layout/signed_in_links'
17
+ - @navbar.extensiones.each do |extension|
18
+ = extension
19
+ div class="d-#{@breakpoint_navbar_expand}-none"
20
+ - if user_signed_in?
21
+ a.d-flex.align-items-center.gap-2 href="#" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample"
22
+ - if Current.account.present?
23
+ - if Current.account.logo.present?
24
+ = image_tag Current.account.logo.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
25
+ - else
26
+ i.bi.bi-bag-fill.me-2 style="font-size: 1.7em"
27
+ - if Current.user.avatar.present?
28
+ = image_tag Current.user.avatar.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
29
+ - else
30
+ i.bi.bi-person-circle.me-2 style="font-size: 1.7em"
31
+ / - else
32
+ button class="btn btn-outline-light d-inline-block d-#{@breakpoint_navbar_expand}-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample"
33
+ i.bi.bi-list
34
+ #notifications-collapse.collapse[data-controller="notifications"]
35
+ #notifications
36
+ #notifications-inner
37
+ - if @notifications&.any?
38
+ = render NotificationComponent.with_collection(@notifications) if @notifications&.any?
39
+ - else
40
+ span.text-light.text-center
41
+ | No hay notificaciones
42
+ .text-center
43
+ button.btn.btn-link.text-light.btn-sm[type="button" data-bs-toggle="collapse" data-bs-target="#notifications-collapse"]
44
+ i.bi-chevron-up.fs-3
45
+ css:
46
+ @media(max-width: 767px) {
47
+ .navbar .navbar-brand {
48
+ visibility:visible!important;
49
+ }
50
+ }
@@ -0,0 +1,10 @@
1
+ div id="sidebar" class="#{@navbar_opened_class} flex-shrink-0 d-none d-#{@breakpoint_navbar_expand}-block"
2
+ .mt-1
3
+ .m-3
4
+ = render @navbar.logo if @navbar.logo.present?
5
+ ul.list-unstyled.ps-0.mt-5
6
+ - @navbar.sidebar.each do |entry|
7
+ - next if @navbar.hide_entry?(entry)
8
+ li.mb-1
9
+ a href=entry[:path] class="d-inline-flex text-decoration-none pg--nav-button #{@navbar.active_entry?(entry, request) ? 'active' : ''} #{entry[:attributes]}"
10
+ = entry[:title]
@@ -0,0 +1,16 @@
1
+ #offcanvasExample.offcanvas.offcanvas-end[tabindex="-1" aria-labelledby="offcanvasExampleLabel" data-bs-theme="dark"]
2
+ .offcanvas-header[data-bs-theme="dark"]
3
+ h5#offcanvasExampleLabel.offcanvas-title
4
+ button.btn-close[type="button" data-bs-dismiss="offcanvas" aria-label="Close"]
5
+ .offcanvas-body.text-end
6
+ - if user_signed_in?
7
+ = render partial: 'pg_layout/signed_in_links'
8
+ ul.list-unstyled.mt-4
9
+ - @navbar.sidebar.each do |entry|
10
+ - next if @navbar.hide_entry?(entry)
11
+ li
12
+ a href=entry[:path] class="pg--nav-button pe-4 text-light #{@navbar.active_entry?(entry, request) ? 'active' : ''} #{entry[:attributes]}"
13
+ = entry[:title]
14
+ css:
15
+ .offcanvas a { text-decoration: none; }
16
+ .offcanvas li { xmargin-top: 0.75em; }
@@ -1,52 +1,54 @@
1
- - if user_signed_in?
2
- .xcollapse.xnavbar-collapse.justify-content-end
3
- ul.navbar-nav.flex-row
4
- - if Current.account.present?
5
- li.nav-item.dropdown
6
- = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
7
- role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
8
- - if Current.account.logo.present?
9
- = image_tag Current.account.logo.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
10
- - else
11
- i.bi.bi-bag-fill.me-2 style="font-size: 1.7em"
12
- = Current.account
13
- ul.dropdown-menu
14
- - if @other_active_accounts&.any?
15
- h6.dropdown-header Cambiar a:
16
- - @other_active_accounts.each do |ua|
17
- li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
18
- li
19
- hr.dropdown-divider
20
- li = link_to "Administrar #{Account.model_name.human(count: 2)}", users_accounts_path(tid: nil), class: 'dropdown-item'
21
- - elsif @other_active_accounts&.any?
22
- li.nav-item.dropdown.d-flex
23
- = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
24
- role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
25
- i.bi.bi-bag-fill.me-2 style="font-size: 1.7em"
26
- = Account.model_name.human(count: 2)
27
- ul.dropdown-menu
28
- - @other_active_accounts.each do |ua|
29
- li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
30
- li
31
- hr.dropdown-divider
32
- li = link_to "Administrar #{Account.model_name.human(count: 2).downcase}", users_accounts_path(tid: nil), class: 'dropdown-item'
1
+ ul.navbar-nav.gap-3.align-items-center class="gap-#{@breakpoint_navbar_expand}-0"
2
+ - if Current.account.present?
3
+ li.nav-item.dropdown
4
+ = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
5
+ role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
6
+ - if Current.account.logo.present?
7
+ = image_tag Current.account.logo.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
8
+ - else
9
+ i.bi.bi-bag-fill.me-2 style="font-size: 1.7em"
10
+ = Current.account
11
+ ul.dropdown-menu
12
+ li = link_to "Administrar #{Current.account}", users_account_path(Current.account, tid: nil), class: 'dropdown-item'
13
+ li
14
+ hr.dropdown-divider
15
+ - if @other_active_accounts&.any?
16
+ h6.dropdown-header Cambiar a:
17
+ - @other_active_accounts.each do |ua|
18
+ li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
19
+ li
20
+ hr.dropdown-divider
21
+ li = link_to "Administrar #{Account.model_name.human(count: 2).downcase}", users_accounts_path(tid: nil), class: 'dropdown-item'
22
+ - elsif @other_active_accounts&.any?
23
+ li.nav-item.dropdown.d-flex
24
+ = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
25
+ role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
26
+ i.bi.bi-bag-fill.me-2 style="font-size: 1.7em"
27
+ = Account.model_name.human(count: 2)
28
+ ul.dropdown-menu
29
+ - @other_active_accounts.each do |ua|
30
+ li = link_to ua.account, tenant_root_path(tid: ua.to_param), class: 'dropdown-item'
31
+ li
32
+ hr.dropdown-divider
33
+ li = link_to "Administrar #{Account.model_name.human(count: 2).downcase}", users_accounts_path(tid: nil), class: 'dropdown-item'
33
34
 
34
- .vr.bg-white.mx-3
35
- - if Current.user.present? && @notifications_bell.present?
36
- = render @notifications_bell
37
- .vr.bg-white.mx-3
38
- li.nav-item.dropdown.me-3
39
- = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
40
- role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
41
- - if Current.user.avatar.present?
42
- = image_tag Current.user.avatar.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
43
- - else
44
- i.bi.bi-person-circle.me-2 style="font-size: 1.7em"
45
- = Current.user
46
- ul.dropdown-menu
47
- li = link_to 'Perfil', edit_user_registration_path(tid: nil), class: 'dropdown-item'
48
- li = link_to Account.model_name.human(count: 2), users_accounts_path(tid: nil), class: 'dropdown-item'
49
- - if Current.user.developer?
50
- li = link_to 'Admin', admin_users_path, class: 'dropdown-item'
51
- li = link_to 'Cerrar sesión', destroy_user_session_path(tid: nil),
52
- 'data-turbo-method': :delete, class: 'dropdown-item'
35
+ .vr.bg-white.mx-3.d-none class="d-#{@breakpoint_navbar_expand}-inline-block"
36
+ - if Current.user.present? && @notifications_bell.present?
37
+ .d-none class="d-#{@breakpoint_navbar_expand}-inline-block"
38
+ = render @notifications_bell
39
+ .vr.bg-white.mx-3.d-none class="d-#{@breakpoint_navbar_expand}-inline-block"
40
+ li.nav-item.dropdown.me-3
41
+ = link_to '#', class: 'nav-link dropdown-toggle py-0 d-flex align-items-center',
42
+ role: :button, 'data-bs-toggle': :dropdown, 'aria-expanded': 'false' do
43
+ - if Current.user.avatar.present?
44
+ = image_tag Current.user.avatar.variant(:thumb), class: 'rounded-circle border border-2 me-2', width: 40, height: 40
45
+ - else
46
+ i.bi.bi-person-circle.me-2 style="font-size: 1.7em"
47
+ = Current.user
48
+ ul.dropdown-menu
49
+ li = link_to 'Mi cuenta', edit_user_registration_path(tid: nil), class: 'dropdown-item'
50
+ li = link_to Account.model_name.human(count: 2), users_accounts_path(tid: nil), class: 'dropdown-item'
51
+ - if Current.user.developer?
52
+ li = link_to 'Admin', admin_users_path, class: 'dropdown-item'
53
+ li = link_to 'Cerrar sesión', destroy_user_session_path(tid: nil),
54
+ 'data-turbo-method': :delete, class: 'dropdown-item'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.6.21.pre.2'
4
+ VERSION = '7.6.21-4'
5
5
  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.6.21.pre.2
4
+ version: 7.6.21.pre.4
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-11-02 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -757,6 +757,7 @@ files:
757
757
  - pg_engine/app/lib/pg_engine/filtros_builder.rb
758
758
  - pg_engine/app/lib/pg_form_builder.rb
759
759
  - pg_engine/app/mailers/pg_engine/admin_mailer.rb
760
+ - pg_engine/app/mailers/pg_engine/base_devise_mailer.rb
760
761
  - pg_engine/app/mailers/pg_engine/base_mailer.rb
761
762
  - pg_engine/app/mailers/pg_engine/user_mailer.rb
762
763
  - pg_engine/app/models/account.rb
@@ -1017,13 +1018,15 @@ files:
1017
1018
  - pg_layout/app/views/layouts/pg_layout/container_logo.html.slim
1018
1019
  - pg_layout/app/views/layouts/pg_layout/containerized.html.slim
1019
1020
  - pg_layout/app/views/layouts/pg_layout/devise.html.slim
1021
+ - pg_layout/app/views/layouts/pg_layout/devise_mailer.html.slim
1022
+ - pg_layout/app/views/layouts/pg_layout/devise_mailer.text.erb
1020
1023
  - pg_layout/app/views/layouts/pg_layout/mailer.html.slim
1021
1024
  - pg_layout/app/views/layouts/pg_layout/mailer.text.erb
1022
1025
  - pg_layout/app/views/layouts/pg_layout/show.html.slim
1023
1026
  - pg_layout/app/views/pg_layout/_flash.html.slim
1024
- - pg_layout/app/views/pg_layout/_navbar.html.erb
1025
- - pg_layout/app/views/pg_layout/_sidebar.html.erb
1026
- - pg_layout/app/views/pg_layout/_sidebar_mobile.html.erb
1027
+ - pg_layout/app/views/pg_layout/_navbar.html.slim
1028
+ - pg_layout/app/views/pg_layout/_sidebar.html.slim
1029
+ - pg_layout/app/views/pg_layout/_sidebar_mobile.html.slim
1027
1030
  - pg_layout/app/views/pg_layout/_signed_in_links.html.slim
1028
1031
  - pg_layout/lib/pg_layout.rb
1029
1032
  - pg_layout/lib/pg_layout/engine.rb
@@ -1,52 +0,0 @@
1
- <nav class="navbar navbar-expand-<%= @breakpoint_navbar_expand %>" data-bs-theme="dark">
2
- <div class="container-fluid xgap-2">
3
- <% unless @sidebar == false %>
4
- <button data-controller="navbar" data-action="navbar#expandNavbar"
5
- class="btn btn-outline-light me-2 d-none d-<%= @breakpoint_navbar_expand %>-inline-block">
6
- <i class="bi <%= @navbar_chevron_class %>"></i>
7
- </button>
8
- <% end %>
9
- <% if @navbar.logo.present? %>
10
- <span class="ms-3">
11
- <%= render @navbar.logo %>
12
- </span>
13
- <% end %>
14
- <%= render partial: 'pg_layout/signed_in_links' %>
15
- <% @navbar.extensiones.each do |extension| %>
16
- <%= extension %>
17
- <% end %>
18
- <% unless @sidebar == false %>
19
- <button class="btn btn-outline-light d-inline-block
20
- d-<%= @breakpoint_navbar_expand %>-none"
21
- type="button"
22
- data-bs-toggle="offcanvas"
23
- data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
24
- <i class="bi bi-list"></i>
25
- </button>
26
- <% end %>
27
- </div>
28
- </nav>
29
- <div class="collapse" id="notifications-collapse" data-controller="notifications">
30
- <div id="notifications">
31
- <div id="notifications-inner">
32
- <% if @notifications&.any? %>
33
- <%= render NotificationComponent.with_collection(@notifications) if @notifications&.any? %>
34
- <% else %>
35
- <span class="text-light text-center">
36
- No hay notificaciones
37
- </span>
38
- <% end %>
39
- <div class="text-center">
40
- <button type="button" class="btn btn-link text-light btn-sm" data-bs-toggle="collapse" data-bs-target="#notifications-collapse">
41
- <i class="bi-chevron-up fs-3"></i>
42
- </button>
43
- </div>
44
- </div>
45
- </div>
46
- </div>
47
-
48
- <style type="text/css" media="(max-width: 767px)">
49
- .navbar .navbar-brand {
50
- visibility:visible!important;
51
- }
52
- </style>
@@ -1,24 +0,0 @@
1
- <div id="sidebar" class="<%= @navbar_opened_class %> flex-shrink-0 d-none d-<%= @breakpoint_navbar_expand %>-block">
2
- <div class="mt-1">
3
- <div class="m-3">
4
- <%= render @navbar.logo if @navbar.logo.present? %>
5
- </div>
6
- <ul class="list-unstyled ps-0 mt-5">
7
- <% @navbar.sidebar.each do |entry| %>
8
- <% next if @navbar.hide_entry?(entry) %>
9
-
10
- <li class="mb-1">
11
- <a
12
- href="<%= entry[:path] %>"
13
- class="
14
- d-inline-flex text-decoration-none pg--nav-button
15
- <%= @navbar.active_entry?(entry, request) ? 'active' : '' %>"
16
- <%= entry[:attributes] %>
17
- >
18
- <%= entry[:title] %>
19
- </a>
20
- </li>
21
- <% end %>
22
- </ul>
23
- </div>
24
- </div>
@@ -1,35 +0,0 @@
1
- <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
2
- <div class="offcanvas-header" data-bs-theme="dark">
3
- <h5 class="offcanvas-title" id="offcanvasExampleLabel"></h5>
4
- <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
5
- </div>
6
- <div class="offcanvas-body text-end">
7
- <% if user_signed_in? %>
8
- <span class="text-light pe-4 mt-4 d-inline-block"><%= Current.user %></span>
9
- <hr>
10
- <% end %>
11
- <ul class="list-unstyled mt-4">
12
- <% @navbar.sidebar.each do |entry| %>
13
- <% next if @navbar.hide_entry?(entry) %>
14
-
15
- <li>
16
- <a
17
- href="<%= entry[:path] %>"
18
- class="pg--nav-button pe-4 text-light <%= @navbar.active_entry?(entry, request) ? 'active' : '' %>"
19
- <%= entry[:attributes] %>
20
- >
21
- <%= entry[:title] %>
22
- </a>
23
- </li>
24
- <% end %>
25
- </ul>
26
- </div>
27
- </div>
28
- <style type="text/css">
29
- .offcanvas a {
30
- text-decoration: none;
31
- }
32
- .offcanvas li {
33
- xmargin-top: 0.75em;
34
- }
35
- </style>