pg_rails 7.0.8.pre.alpha.62 → 7.0.8.pre.alpha.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/pg_engine/app/assets/config/pg_engine_manifest.js +1 -0
  3. data/pg_engine/app/assets/images/plantita-sm.png +0 -0
  4. data/pg_engine/app/assets/images/plantita.png +0 -0
  5. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +8 -3
  6. data/pg_engine/app/controllers/pg_engine/base_controller.rb +1 -1
  7. data/pg_engine/app/controllers/users/registrations_controller.rb +1 -1
  8. data/pg_engine/app/helpers/pg_engine/flash_helper.rb +2 -1
  9. data/pg_engine/app/helpers/pg_engine/print_helper.rb +1 -1
  10. data/pg_engine/app/lib/pg_engine/devise_failure_app.rb +41 -0
  11. data/pg_engine/app/models/email.rb +1 -1
  12. data/pg_engine/app/views/public/mensaje_contactos/_gracias.html.slim +1 -1
  13. data/pg_engine/app/views/public/mensaje_contactos/new.html.slim +4 -0
  14. data/pg_engine/config/routes.rb +1 -1
  15. data/pg_engine/lib/pg_engine/email_observer.rb +6 -9
  16. data/pg_engine/spec/controllers/devise/sessions_controller_spec.rb +23 -0
  17. data/pg_layout/app/javascript/application.js +17 -10
  18. data/pg_layout/app/javascript/controllers/navbar_controller.js +2 -1
  19. data/pg_layout/app/javascript/controllers/pg_form_controller.js +2 -2
  20. data/pg_layout/app/lib/navbar.rb +1 -1
  21. data/pg_layout/app/views/devise/confirmations/new.html.erb +1 -3
  22. data/pg_layout/app/views/layouts/pg_layout/base.html.slim +9 -1
  23. data/pg_layout/app/views/pg_layout/_flash.html.slim +1 -19
  24. data/pg_layout/app/views/pg_layout/_flash_container.html.slim +1 -1
  25. data/pg_layout/app/views/pg_layout/_flash_inner.html.slim +24 -0
  26. data/pg_rails/lib/version.rb +1 -1
  27. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afcf64379ab25a58e3b1d626f71371cc63448503880d182b8ad1e1164dbccf7e
4
- data.tar.gz: 9917f1be640ccdbabbc1d7c12ca561d5714f1b4227e3899c3c1cc96749157284
3
+ metadata.gz: 897b3e763decbc3633e769f5c80b03b2ac4beeb6d7870418205890f07be921a3
4
+ data.tar.gz: bcb3121b4f5c7dbdbf43f7363121617fdc1576b37fae413b508e947e68b1789b
5
5
  SHA512:
6
- metadata.gz: a620ba16efe37ac2794a11676bcecb89ad101053abcb04147a246b2c3d074de03799b01d1d0ad7578855d05347f793aec52a62a6722a4e755ee161aa156a98bf
7
- data.tar.gz: 8d63151e40a4a105137d3a097b9ec09690c159b2130620d078bc5c428895522631c5ffc732acd20b4cd32094470f2e72aca5a05050e13cfc8381207662d61c2a
6
+ metadata.gz: 14f270d418616143ce27842e5ea615760ad472fdd81f758a41303a3cb45173b57beaec9ff54cdea07ef0b1200f02cfe24e2e978476f41d82f74627ce1de4c34c
7
+ data.tar.gz: e66b21ddb42ee202b0bcd62b5e6cb0a22f16e6f5561edbc4e142b12acdcc91bd0131402dfef49f20db159fff99b05b76d5f57db9a53acec4ad92251d3e46ee42
@@ -0,0 +1 @@
1
+ //= link_tree ../images
@@ -20,8 +20,6 @@ module PgEngine
20
20
  def index
21
21
  @collection = filtros_y_policy atributos_para_buscar
22
22
  @collection = sort_collection(@collection)
23
- @records_filtered = policy_scope(clase_modelo).any? if @collection.empty?
24
- # FIXME: si hay pero en páginas anteriores, mostrar texto correspondiente
25
23
  pg_respond_index
26
24
  end
27
25
 
@@ -208,6 +206,7 @@ module PgEngine
208
206
 
209
207
  def render_listing
210
208
  @collection = @collection.page(params[:page]).per(current_page_size)
209
+ @records_filtered = default_scope_for_current_model.any? if @collection.empty?
211
210
  end
212
211
 
213
212
  def buscar_instancia
@@ -272,6 +271,12 @@ module PgEngine
272
271
  @filtros.filtrar(scope)
273
272
  end
274
273
 
274
+ def default_scope_for_current_model
275
+ PgEngine::FiltrosBuilder.new(
276
+ self, clase_modelo, []
277
+ ).filtrar(policy_scope(clase_modelo))
278
+ end
279
+
275
280
  def do_sort(scope, field, direction)
276
281
  # TODO: restringir ciertos campos?
277
282
  unless scope.model.column_names.include?(field.to_s) ||
@@ -306,7 +311,7 @@ module PgEngine
306
311
  direction = options[:default].first[1]
307
312
  do_sort(scope, field, direction)
308
313
  else
309
- scope
314
+ do_sort(scope, 'id', 'desc')
310
315
  end
311
316
  end
312
317
  end
@@ -22,7 +22,7 @@ module PgEngine
22
22
 
23
23
  protect_from_forgery with: :exception
24
24
 
25
- rescue_from PgEngine::Error, with: :internal_error
25
+ rescue_from StandardError, with: :internal_error
26
26
  rescue_from Pundit::NotAuthorizedError, with: :not_authorized
27
27
  rescue_from Redirect do |e|
28
28
  redirect_to e.url
@@ -21,7 +21,7 @@ module Users
21
21
 
22
22
  def render_message
23
23
  msg = <<~HTML
24
- <div class="alert alert-info mt-4">
24
+ <div class="alert alert-info mt-4 d-inline-block">
25
25
  #{I18n.t 'devise.registrations.signed_up_but_unconfirmed'}
26
26
  </div>
27
27
  HTML
@@ -5,8 +5,9 @@ module PgEngine
5
5
  end
6
6
 
7
7
  def render_turbo_stream_title
8
+ title = [breadcrumbs.last&.name, I18n.t('app_name')].compact.join(' - ')
8
9
  # rubocop:disable Rails/SkipsModelValidations
9
- turbo_stream.update_all 'title', "#{breadcrumbs.last&.name} - #{Rails.application.class.module_parent_name}"
10
+ turbo_stream.update_all 'title', title
10
11
  # rubocop:enable Rails/SkipsModelValidations
11
12
  end
12
13
 
@@ -92,7 +92,7 @@ module PgEngine
92
92
  def print_currency(number, simbolo: '$', precision: nil)
93
93
  return if number.blank?
94
94
 
95
- # FIXME: testear
95
+ # TODO!: testear
96
96
  precision ||= if (number % 0.01).positive?
97
97
  3
98
98
  else
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PgEngine
4
+ class DeviseFailureApp < Devise::FailureApp
5
+ def respond
6
+ if warden_message == :unconfirmed
7
+ render_unconfirmed
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def user_email
16
+ params[:user][:email]
17
+ rescue StandardError => e
18
+ pg_warn e, :warn
19
+ end
20
+
21
+ def render_unconfirmed
22
+ self.content_type = 'text/vnd.turbo-stream.html'
23
+ self.status = 200
24
+ self.response_body = <<~HTML
25
+ <turbo-stream action="update" target="flash">
26
+ <template>
27
+ <div class="alert alert-warning d-flex align-items-center">
28
+ <div class="bi bi-exclamation-circle me-3"></div>
29
+ <span>
30
+ Tu cuenta aún no está confirmada.
31
+ <br>
32
+ Revisá tu bandeja de entrada o&nbsp;
33
+ <a href="/users/confirmation/new?email=#{user_email}">hacé click acá para reenviar el correo</a>
34
+ </span>
35
+ </div>
36
+ </template>
37
+ </turbo-stream>
38
+ HTML
39
+ end
40
+ end
41
+ end
@@ -52,7 +52,7 @@ class Email < ApplicationRecord
52
52
 
53
53
  validate do
54
54
  if to.present? && !to.split(/[,;]/).all? { |dest| dest.match(/\A[^@\s]+@[^@\s]+\z/) }
55
- # FIXME: testear
55
+ # TODO!: testear
56
56
  errors.add(:to, 'no es válido')
57
57
  end
58
58
  end
@@ -5,4 +5,4 @@
5
5
  h4 Gracias por tu mensaje
6
6
  p.m-0 Te responderemos a la brevedad
7
7
  .col-auto.fs-2
8
- | 🌱
8
+ = image_tag 'plantita-sm', width: '30px'
@@ -1,4 +1,8 @@
1
1
  / # locals: (object: nil, asociable: false)
2
+
3
+ .d-none
4
+ / Preload
5
+ = image_tag 'plantita-sm'
2
6
  .text-center
3
7
  #mensaje_contacto
4
8
  h2 Ponete en contacto
@@ -7,7 +7,7 @@ Rails.application.routes.draw do
7
7
  devise_for :users, controllers: {
8
8
  confirmations: 'users/confirmations',
9
9
  registrations: 'users/registrations'
10
- }
10
+ }, failure_app: PgEngine::DeviseFailureApp
11
11
  namespace :admin, path: 'a' do
12
12
  pg_resource(:emails)
13
13
  pg_resource(:users)
@@ -2,23 +2,20 @@
2
2
 
3
3
  module PgEngine
4
4
  class EmailObserver
5
- def self.delivered_email(message)
5
+ def self.delivered_email(message) # rubocop:disable Metrics/AbcSize
6
6
  message_id = message.message_id
7
7
  mailer = message.delivery_handler.to_s
8
8
  status = get_status(message)
9
-
10
9
  if message['email'].present?
11
10
  email = message['email'].unparsed_value
12
11
  email.update_columns(message_id:, mailer:, status:) # rubocop:disable Rails/SkipsModelValidations
13
- email.encoded_eml.attach({ io: StringIO.new(message.encoded), filename: "email-#{email.id}.eml" })
14
12
  else
15
- pg_warn 'El mail no tenía objeto Email asociado.', :warn
16
- # FIX: el content puede ser TXT
17
- # Email.create!(message_id: message.message_id, body_html: message.encoded,
18
- # subject: subject, recipient: recipient,
19
- # date: DateTime.now, mailer: message.delivery_handler.to_s, associated: associated(message),
20
- # status: get_status(message), observations: get_observations(message))
13
+ to = [message.to].flatten.join(', ')
14
+ from = [message.from].flatten.join(', ')
15
+ email = Email.create!(message_id:, subject: message.subject, to:, mailer:, status:, from_address: from,
16
+ from_name: '')
21
17
  end
18
+ email.encoded_eml.attach({ io: StringIO.new(message.encoded), filename: "email-#{email.id}.eml" })
22
19
  rescue StandardError => e
23
20
  pg_warn e, :error
24
21
  end
@@ -15,4 +15,27 @@ describe Devise::SessionsController do
15
15
  expect(response).to have_http_status(:ok)
16
16
  end
17
17
  end
18
+
19
+ describe '#create' do
20
+ subject do
21
+ post :create, params: { user: { email: user.email, password: } }
22
+ end
23
+
24
+ let(:password) { 'cosas1234' }
25
+ let(:confirmed_at) { nil }
26
+ let(:user) { create :user, confirmed_at:, password: }
27
+
28
+ it do
29
+ subject
30
+ expect(response.body).to include 'Tu cuenta aún no está confirmada.'
31
+ end
32
+
33
+ context 'cuando está confirmado' do
34
+ let(:confirmed_at) { Time.zone.now }
35
+
36
+ it do
37
+ expect { subject }.to change(controller, :user_signed_in?).from(false).to(true)
38
+ end
39
+ end
40
+ end
18
41
  end
@@ -33,8 +33,8 @@ Rollbar.configure({
33
33
  }
34
34
  })
35
35
 
36
- document.addEventListener('turbo:load', bindToasts)
37
- document.addEventListener('turbo:render', bindToasts)
36
+ document.addEventListener('turbo:load', bindAndObserveToasts)
37
+ document.addEventListener('turbo:render', bindAndObserveToasts)
38
38
 
39
39
  document.addEventListener('turbo:before-cache', () => {
40
40
  document.querySelectorAll('.offcanvas-backdrop').forEach((el) => {
@@ -45,9 +45,20 @@ document.addEventListener('turbo:before-cache', () => {
45
45
  })
46
46
  })
47
47
 
48
- function bindToasts () {
49
- const toastElList = document.querySelectorAll('.toast:not(.hide):not(.show)')
50
- Array.from(toastElList).map(toastEl => new bootstrap.Toast(toastEl).show())
48
+ function bindToastElements () {
49
+ const toastQuery = '.pg-toast:not(.hide):not(.show)'
50
+
51
+ const toastElList = document.querySelectorAll(toastQuery)
52
+ Array.from(toastElList).each(toastEl => {
53
+ new bootstrap.Toast(toastEl).show()
54
+ toastEl.addEventListener('hidden.bs.toast', () => {
55
+ toastEl.remove()
56
+ })
57
+ })
58
+ }
59
+
60
+ function bindAndObserveToasts () {
61
+ bindToastElements()
51
62
 
52
63
  // Select the node that will be observed for mutations
53
64
  const targetNode = document.getElementById('flash')
@@ -59,11 +70,7 @@ function bindToasts () {
59
70
  const callback = (mutationList, observer) => {
60
71
  for (const mutation of mutationList) {
61
72
  if (mutation.type === 'childList') {
62
- // console.log('A child node has been added or removed.')
63
- const toastElList = document.querySelectorAll('.toast:not(.hide):not(.show)')
64
- Array.from(toastElList).map(toastEl => new bootstrap.Toast(toastEl).show())
65
- } else if (mutation.type === 'attributes') {
66
- // console.log(`The ${mutation.attributeName} attribute was modified.`)
73
+ bindToastElements()
67
74
  }
68
75
  }
69
76
  }
@@ -5,7 +5,8 @@ import { fadeOut, fadeIn } from './../utils/utils'
5
5
  export default class extends Controller {
6
6
  connect () {
7
7
  if (document.getElementById('sidebar').classList.contains('opened')) {
8
- document.querySelector('.navbar .navbar-brand').style.visibility = 'hidden'
8
+ const brand = document.querySelector('.navbar .navbar-brand')
9
+ if (brand) brand.style.visibility = 'hidden'
9
10
  }
10
11
  }
11
12
 
@@ -16,9 +16,9 @@ export default class extends Controller {
16
16
  const baseAlert = document.querySelector('.alert-danger')
17
17
  if (!invalidField && !baseAlert) {
18
18
  const errorTitle = this.element.querySelector('.error-title')
19
- // FIXME: testear con capybara
19
+ // TODO!: testear con capybara
20
20
  errorTitle.innerText = 'Lo lamentamos mucho pero ocurrió algo inesperado. Por favor, intentá nuevamente o ponete en contacto con nosotros.'
21
- // FIXME: link a contacto
21
+ // TODO!: link a contacto
22
22
  const form = this.element.querySelector('form')
23
23
  const errorMsg = `${form.id} - ${form.action} - ${form.dataset.errors}`
24
24
  console.error(errorMsg)
@@ -39,7 +39,7 @@ class Navbar
39
39
  show: item['policy'] ? eval(item['policy']) : true
40
40
  }
41
41
  rescue StandardError
42
- # FIXME: testear
42
+ # TODO!: testear
43
43
  pg_err item
44
44
  return []
45
45
  end
@@ -1,5 +1,3 @@
1
- <h2><%= t(".resend_confirmation_instructions") %></h2>
2
-
3
1
  <%= pg_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4
2
  <%= f.mensajes_de_error %>
5
3
  <%= f.full_error :confirmation_token %>
@@ -9,7 +7,7 @@
9
7
  required: true,
10
8
  autofocus: true,
11
9
  value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email),
12
- input_html: { autocomplete: "email" } %>
10
+ input_html: { value: params[:email], autocomplete: "email" } %>
13
11
  </div>
14
12
 
15
13
  <div class="form-actions">
@@ -1,8 +1,16 @@
1
1
  doctype html
2
2
  html
3
3
  head
4
- title = Rails.application.class.module_parent_name
4
+ meta charset="UTF-8"
5
+ meta http-equiv="X-UA-Compatible" content="IE=edge"
5
6
  meta name="viewport" content="width=device-width,initial-scale=1"
7
+ - cache :title_icon
8
+ title = t('app_name')
9
+ - begin
10
+ = render partial: 'layouts/favicon'
11
+ - rescue ActionView::MissingTemplate => e
12
+ - pg_err e
13
+
6
14
  - if @turbo_no_cache
7
15
  meta name="turbo-cache-control" content="no-cache"
8
16
  / El morph no estaría siendo de utilidad
@@ -2,22 +2,4 @@
2
2
  - flash_to_show = flash.select { |fm| fm[0].to_sym.in?(ApplicationController._flash_types) && fm[1].present? }
3
3
  / slim-lint:enable LineLength
4
4
  - flash_to_show.each do |flash_type, message|
5
- .alert.alert-dismissible[
6
- class="mt-2 d-flex align-items-center alert-#{flash_type_to_class(flash_type)}"
7
- data-turbo-temporary="true"
8
- aria-live="assertive" aria-atomic="true" role="alert"
9
- ]
10
- - case flash_type
11
- - when 'critical'
12
- / .bi.bi-emoji-dizzy.me-3.fs-2
13
- .bi.bi-exclamation-triangle-fill.me-3.fs-2
14
- - when 'alert'
15
- .bi.bi-exclamation-triangle-fill.me-2
16
- - when 'warning'
17
- .bi.bi-exclamation-circle.me-2
18
- - when 'success'
19
- .bi.bi-check-lg.me-2
20
- - when 'notice'
21
- .bi.bi-info-circle.me-2
22
- = message
23
- button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"
5
+ = render partial: 'pg_layout/flash_inner', locals: { flash_type:, message:, toast: flash[:toast] }
@@ -1,3 +1,3 @@
1
1
  #flash-wrapper.d-flex.justify-content-around
2
- #flash.flash
2
+ #flash.flash.position-relative.w-100.d-flex.justify-content-center
3
3
  = render partial: 'pg_layout/flash'
@@ -0,0 +1,24 @@
1
+ / # locals: (flash_type:, message:, toast: false)
2
+
3
+ .alert.alert-dismissible[
4
+ class="
5
+ mt-2 d-flex align-items-center
6
+ alert-#{flash_type_to_class(flash_type)}
7
+ #{'position-absolute pg-toast' if toast}"
8
+ data-turbo-temporary="true" data-bs-autohide="true"
9
+ aria-live="assertive" aria-atomic="true" role="alert"
10
+ ]
11
+ - case flash_type
12
+ - when 'critical'
13
+ / .bi.bi-emoji-dizzy.me-3.fs-2
14
+ .bi.bi-exclamation-triangle-fill.me-3.fs-2
15
+ - when 'alert'
16
+ .bi.bi-exclamation-triangle-fill.me-2
17
+ - when 'warning'
18
+ .bi.bi-exclamation-circle.me-2
19
+ - when 'success'
20
+ .bi.bi-check-lg.me-2
21
+ - when 'notice'
22
+ .bi.bi-info-circle.me-2
23
+ = message
24
+ button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.0.8-alpha.62'
4
+ VERSION = '7.0.8-alpha.64'
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.0.8.pre.alpha.62
4
+ version: 7.0.8.pre.alpha.64
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-05-08 00:00:00.000000000 Z
11
+ date: 2024-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -906,6 +906,9 @@ files:
906
906
  - pg_engine/app/admin/mensaje_contactos.rb
907
907
  - pg_engine/app/admin/user_accounts.rb
908
908
  - pg_engine/app/admin/users.rb
909
+ - pg_engine/app/assets/config/pg_engine_manifest.js
910
+ - pg_engine/app/assets/images/plantita-sm.png
911
+ - pg_engine/app/assets/images/plantita.png
909
912
  - pg_engine/app/assets/javascripts/active_admin.js
910
913
  - pg_engine/app/assets/stylesheets/active_admin.scss
911
914
  - pg_engine/app/assets/stylesheets/pg_rails_b5.scss
@@ -935,6 +938,7 @@ files:
935
938
  - pg_engine/app/helpers/pg_engine/print_helper.rb
936
939
  - pg_engine/app/helpers/pg_engine/route_helper.rb
937
940
  - pg_engine/app/inputs/pg_engine/fecha_input.rb
941
+ - pg_engine/app/lib/pg_engine/devise_failure_app.rb
938
942
  - pg_engine/app/lib/pg_engine/error_helper.rb
939
943
  - pg_engine/app/lib/pg_engine/filtros_builder.rb
940
944
  - pg_engine/app/lib/pg_form_builder.rb
@@ -1089,6 +1093,7 @@ files:
1089
1093
  - pg_layout/app/views/pg_layout/_error.html.erb
1090
1094
  - pg_layout/app/views/pg_layout/_flash.html.slim
1091
1095
  - pg_layout/app/views/pg_layout/_flash_container.html.slim
1096
+ - pg_layout/app/views/pg_layout/_flash_inner.html.slim
1092
1097
  - pg_layout/app/views/pg_layout/_navbar.html.erb
1093
1098
  - pg_layout/app/views/pg_layout/_sidebar.html.erb
1094
1099
  - pg_layout/app/views/pg_layout/_sidebar_mobile.html.erb