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.
- checksums.yaml +4 -4
- data/pg_associable/app/helpers/pg_associable/form_builder_methods.rb +1 -0
- data/pg_associable/app/inputs/pg_associable_input.rb +1 -0
- data/pg_associable/spec/system/associable_spec.rb +4 -5
- data/pg_engine/app/controllers/users/accounts_controller.rb +20 -1
- data/pg_engine/app/controllers/users/invitations_controller.rb +2 -0
- data/pg_engine/app/decorators/account_decorator.rb +8 -8
- data/pg_engine/app/decorators/user_account_decorator.rb +7 -4
- data/pg_engine/app/helpers/pg_engine/flash_helper.rb +2 -1
- data/pg_engine/app/mailers/pg_engine/base_devise_mailer.rb +9 -0
- data/pg_engine/app/mailers/pg_engine/user_mailer.rb +2 -0
- data/pg_engine/app/models/account.rb +2 -1
- data/pg_engine/app/models/current.rb +1 -0
- data/pg_engine/app/models/user.rb +8 -0
- data/pg_engine/app/models/user_account.rb +1 -1
- data/pg_engine/app/policies/pg_engine/base_policy.rb +8 -8
- data/pg_engine/app/views/users/accounts/_form.html.slim +1 -1
- data/pg_engine/app/views/users/accounts/show.html.slim +5 -4
- data/pg_engine/config/initializers/devise.rb +1 -1
- data/pg_engine/config/locales/es.yml +3 -2
- data/pg_engine/db/migrate/20241027225618_add_membership_status_to_user_accounts.rb +7 -0
- data/pg_engine/lib/pg_engine/engine.rb +9 -0
- data/pg_engine/spec/factories/users.rb +5 -2
- data/pg_engine/spec/mailers/previews/devise_preview.rb +6 -0
- data/pg_engine/spec/models/user_spec.rb +0 -4
- data/pg_layout/app/views/devise/mailer/invitation_instructions.html.erb +3 -5
- data/pg_layout/app/views/devise/mailer/invitation_instructions.text.erb +3 -5
- data/pg_layout/app/views/layouts/pg_layout/base.html.slim +2 -3
- data/pg_layout/app/views/layouts/pg_layout/containerized.html.slim +1 -1
- data/pg_layout/app/views/layouts/pg_layout/devise_mailer.html.slim +12 -0
- data/pg_layout/app/views/layouts/pg_layout/devise_mailer.text.erb +7 -0
- data/pg_layout/app/views/pg_layout/_navbar.html.slim +50 -0
- data/pg_layout/app/views/pg_layout/_sidebar.html.slim +10 -0
- data/pg_layout/app/views/pg_layout/_sidebar_mobile.html.slim +16 -0
- data/pg_layout/app/views/pg_layout/_signed_in_links.html.slim +53 -51
- data/pg_rails/lib/version.rb +1 -1
- metadata +8 -5
- data/pg_layout/app/views/pg_layout/_navbar.html.erb +0 -52
- data/pg_layout/app/views/pg_layout/_sidebar.html.erb +0 -24
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52db938b6aad2006d1815247f8b3f1c4bd297b811ca50db7e800760967942045
|
4
|
+
data.tar.gz: 1a095d3501f50d2b3fa9b123bb62a42e5c3472a1f679b4adf5932716f51693de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab9d327f91d9153cf8e2ebc1e602510db545f1f086a23fb7d1ced3f5480b234f0b231327930b3707f972a5524cff80796488d3a762df95ed5d0ad649f52dd21c
|
7
|
+
data.tar.gz: 2ca7ae67777a8bac52b5f63642e52d3436fd094c166a97f2c84417bdfcd3305d9f5b5e6a286e2fbd4a655035a69049ddff6ab72ec83abbc6dc5853808ad9d8a9
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
|
3
3
|
describe 'Associable' do
|
4
|
-
let(:user) { create :user, :
|
4
|
+
let(:user) { create :user, :owner }
|
5
5
|
|
6
|
-
let(:path) { '/
|
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) { "/
|
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) { "/
|
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
|
78
|
+
%i[nombre owner]
|
60
79
|
end
|
61
80
|
end
|
62
81
|
end
|
@@ -22,13 +22,13 @@ class AccountDecorator < PgEngine::BaseRecordDecorator
|
|
22
22
|
ua.reject_invitation_link].compact.join.html_safe
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
def show_link(text: 'Usuarios', klass: 'btn-secondary')
|
26
|
+
return unless Pundit.policy!(Current.user, object).show?
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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,
|
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
|
@@ -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: {
|
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
|
|
@@ -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
|
-
|
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
|
|
@@ -3,10 +3,11 @@
|
|
3
3
|
= @user_account.sign_off_link
|
4
4
|
|
5
5
|
.text-center
|
6
|
-
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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 = '
|
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: "
|
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
|
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
|
-
|
74
|
-
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
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,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
|
-
-
|
2
|
-
.
|
3
|
-
|
4
|
-
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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'
|
data/pg_rails/lib/version.rb
CHANGED
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.
|
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-
|
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.
|
1025
|
-
- pg_layout/app/views/pg_layout/_sidebar.html.
|
1026
|
-
- pg_layout/app/views/pg_layout/_sidebar_mobile.html.
|
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>
|