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

Sign up to get free protection for your applications and to get access to all the features.
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