pg_rails 7.0.8.pre.alpha.93 → 7.0.8.pre.alpha.95

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdf7d3d8c84262ae3dbb580c76a11f33d9cb91a6168ec187dfd0f760a080fde6
4
- data.tar.gz: ebb7a5b8d8680a82f71574c04efe8f517b04134c628e6cd10103828d34d78727
3
+ metadata.gz: 2f8a869085b05c79395519bbd89206705710f949f49304c41f015030c12a125e
4
+ data.tar.gz: 8f1ff6c3b0f428c6b4d7b4b5b9f91b7b5979d9d491a7ca553918abf8fe5de462
5
5
  SHA512:
6
- metadata.gz: 82cc777c32238b7c5430a95c6ebf701b188cb94b885373e43d1b20976e4081f3c6fa7ce0366cd8c5ed455cd9375fac70b2e7c5fdff3ea1d258f6cb546f6709ec
7
- data.tar.gz: 84c40fd802a3681eeb76c11e0de4e5280bc41d9e97cf88a5a74a71b396c02dd7e68af0985a541325a1be9b26e692d0d35e893c37d16849b53a114fc4cebdf522
6
+ metadata.gz: 4fd90973e9c75ed200bdbce2a95cf3d4ef34e47aa9c5ba48105dc8aa34ab8c934eff9f01d4dd7ba735b111968a17dc4c8f24e38294ca71d28c8aec8dd18d62a3
7
+ data.tar.gz: e3dd8ddc322319711e8471b2d9ee5e329d2291c0e2b6ae5cadb023506f53dc960bf7a746349623b9ac38a51a0266ea71fccc9c142e2ad14342548badd9b9c826
@@ -0,0 +1,49 @@
1
+ #notifications {
2
+ display: flex;
3
+ align-items: center;
4
+ flex-direction: column;
5
+ gap: 5px;
6
+ background-color: #6a2a05;
7
+ padding: 1.5em 5px;
8
+ }
9
+
10
+ #notifications-inner {
11
+ max-width: 400px;
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: 0.4em;
15
+ }
16
+ .notification {
17
+ border: 1px solid #0003;
18
+ border-radius: 2px;
19
+ position: relative;
20
+ padding: 0.3em 2.5em;
21
+ xpadding-left: 2.5em;
22
+ display: flex;
23
+ align-items: center;
24
+ background-color: white;
25
+ }
26
+ .notification:not(.unseen) {
27
+ xcolor: #646464;
28
+ }
29
+ .notification.unseen {
30
+ background-color: rgb(230, 225, 251);
31
+ }
32
+ .notification.unseen::before {
33
+ content: '';
34
+ padding: 5px;
35
+ left: 1em;
36
+ vertical-align: middle;
37
+ position: absolute;
38
+ background-color: #079510;
39
+ border-radius: 50%;
40
+ }
41
+ .notifications-unseen-mark {
42
+ border: 1px solid #ffffff9d;
43
+ //background-color: #ea3d2b !important;
44
+ background-color: #079510;
45
+ }
46
+ .notification--time {
47
+ font-size: 0.8em;
48
+ min-width: 6em;
49
+ }
@@ -1,5 +1,8 @@
1
1
  @use 'sass:color';
2
2
 
3
+ @import 'notifications';
4
+
5
+
3
6
  :root,
4
7
  [data-bs-theme=light] {
5
8
  --bs-form-invalid-color: #b50000;
@@ -0,0 +1,19 @@
1
+ class NotificationComponent < BaseComponent
2
+ def initialize(notification: nil)
3
+ @notification = notification
4
+ super
5
+ end
6
+
7
+ erb_template <<~ERB
8
+ <div class="notification d-flex justify-content-between <%= 'unseen' if @notification.unseen? %>"
9
+ id="<%= dom_id(@notification) %>" data-id="<%= @notification.id %>">
10
+ <div>
11
+ <%= @notification.message %>
12
+ </div>
13
+ <div class="notification--time text-body-tertiary text-end ms-4">
14
+ hace
15
+ <%= distance_of_time_in_words @notification.created_at, Time.zone.now %>
16
+ </div>
17
+ </div>
18
+ ERB
19
+ end
@@ -79,6 +79,11 @@ module PgEngine
79
79
  if Rollbar.configuration.enabled && Rails.application.credentials.rollbar.present?
80
80
  @rollbar_token = Rails.application.credentials.rollbar.access_token_client
81
81
  end
82
+
83
+ if Current.user.present?
84
+ @notifications = Current.user.notifications.order(id: :desc)
85
+ @unseen_notifications = @notifications.unseen.any?
86
+ end
82
87
  end
83
88
 
84
89
  def mobile_device?
@@ -0,0 +1,11 @@
1
+ module Users
2
+ class NotificationsController < ApplicationController
3
+ def mark_as_seen
4
+ # No handleo errores porque no debería fallar, y si falla
5
+ # se notifica a rollbar y al user no le pasa nada
6
+ notifications = Noticed::Notification.where(id: params[:ids].split(','))
7
+ notifications.each(&:mark_as_seen!)
8
+ head :ok
9
+ end
10
+ end
11
+ end
@@ -19,7 +19,6 @@
19
19
  #
20
20
  # fk_rails_... (email_id => emails.id)
21
21
  #
22
- # generado con pg_rails
23
22
 
24
23
  class EmailLog < ApplicationRecord
25
24
  audited
@@ -38,6 +38,7 @@ class User < ApplicationRecord
38
38
 
39
39
  has_many :user_accounts
40
40
  has_many :accounts, through: :user_accounts
41
+ has_many :notifications, as: :recipient, class_name: 'Noticed::Notification'
41
42
 
42
43
  validates :nombre, :apellido, presence: true
43
44
 
@@ -0,0 +1,2 @@
1
+ class ApplicationNotifier < Noticed::Event
2
+ end
@@ -0,0 +1,28 @@
1
+ # To deliver this notification:
2
+ #
3
+ # SimpleUserNotifier.with(message: "New post").deliver(User.all, enqueue_job: false)
4
+
5
+ class SimpleUserNotifier < ApplicationNotifier
6
+ # Add your delivery methods
7
+ #
8
+ # deliver_by :email do |config|
9
+ # config.mailer = "UserMailer"
10
+ # config.method = "new_post"
11
+ # end
12
+ #
13
+ # bulk_deliver_by :slack do |config|
14
+ # config.url = -> { Rails.application.credentials.slack_webhook_url }
15
+ # end
16
+ #
17
+ # deliver_by :custom do |config|
18
+ # config.class = "MyDeliveryMethod"
19
+ # end
20
+ notification_methods do
21
+ def message
22
+ params[:message]
23
+ end
24
+ end
25
+ # Add required params
26
+ #
27
+ required_param :message
28
+ end
@@ -10,4 +10,7 @@ if defined?(AnyCable::Rails)
10
10
  AnyCable::Rails::Rack.middleware.use Warden::Manager do |config|
11
11
  Devise.warden_config = config
12
12
  end
13
+
14
+ # Lo dejo comentado porque no sé si hará falta
15
+ # AnyCable::Rails.extend_adapter!(ActionCable.server.pubsub) unless AnyCable::Rails.enabled?
13
16
  end
@@ -10,6 +10,9 @@ Rails.application.routes.draw do
10
10
  confirmations: 'users/confirmations',
11
11
  registrations: 'users/registrations'
12
12
  }, failure_app: PgEngine::DeviseFailureApp
13
+ namespace :users, path: 'u' do
14
+ post 'notifications/mark_as_seen', to: 'notifications#mark_as_seen'
15
+ end
13
16
  namespace :admin, path: 'a' do
14
17
  pg_resource(:emails)
15
18
  pg_resource(:email_logs) do
@@ -0,0 +1,37 @@
1
+ # This migration comes from noticed (originally 20231215190233)
2
+ class CreateNoticedTables < ActiveRecord::Migration[6.1]
3
+ def change
4
+ primary_key_type, foreign_key_type = primary_and_foreign_key_types
5
+ create_table :noticed_events, id: primary_key_type do |t|
6
+ t.string :type
7
+ t.belongs_to :record, polymorphic: true, type: foreign_key_type
8
+ if t.respond_to?(:jsonb)
9
+ t.jsonb :params
10
+ else
11
+ t.json :params
12
+ end
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ create_table :noticed_notifications, id: primary_key_type do |t|
18
+ t.string :type
19
+ t.belongs_to :event, null: false, type: foreign_key_type
20
+ t.belongs_to :recipient, polymorphic: true, null: false, type: foreign_key_type
21
+ t.datetime :read_at
22
+ t.datetime :seen_at
23
+
24
+ t.timestamps
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def primary_and_foreign_key_types
31
+ config = Rails.configuration.generators
32
+ setting = config.options[config.orm][:primary_key_type]
33
+ primary_key_type = setting || :primary_key
34
+ foreign_key_type = setting || :bigint
35
+ [primary_key_type, foreign_key_type]
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ # This migration comes from noticed (originally 20240129184740)
2
+ class AddNotificationsCountToNoticedEvent < ActiveRecord::Migration[6.1]
3
+ def change
4
+ add_column :noticed_events, :notifications_count, :integer
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'Notifications' do
4
+ subject do
5
+ visit '/'
6
+ end
7
+
8
+ let(:user) { create :user }
9
+
10
+ before do
11
+ driven_by ENV['DRIVER']&.to_sym || :selenium_chrome_headless_iphone
12
+ login_as user
13
+ end
14
+
15
+ context 'no notifications' do
16
+ it do
17
+ subject
18
+ expect(page).to have_no_css('.notifications-unseen-mark')
19
+ end
20
+ end
21
+
22
+ context 'with unseen notifications' do
23
+ before do
24
+ SimpleUserNotifier.with(message: 'probandooo').deliver(User.all)
25
+ end
26
+
27
+ it do
28
+ subject
29
+ expect(page).to have_css('.notifications-unseen-mark')
30
+ find('.bi-bell-fill').click
31
+ expect(page).to have_no_css('.notifications-unseen-mark', wait: 5)
32
+ end
33
+ end
34
+
35
+ pending 'with read notifications'
36
+ end
@@ -7,6 +7,7 @@ import FadeinOnloadController from './fadein_onload_controller'
7
7
  import ClearTimeoutController from './clear_timeout_controller'
8
8
  import SwitcherController from './switcher_controller'
9
9
  import FiltrosController from './filtros_controller'
10
+ import NotificationsController from './notifications_controller'
10
11
 
11
12
  application.register('navbar', NavbarController)
12
13
  application.register('nested', NestedController)
@@ -15,5 +16,6 @@ application.register('fadein_onload', FadeinOnloadController)
15
16
  application.register('clear-timeout', ClearTimeoutController)
16
17
  application.register('switcher', SwitcherController)
17
18
  application.register('filtros', FiltrosController)
19
+ application.register('notifications', NotificationsController)
18
20
 
19
21
  // TODO: testear con capybara todo lo que se pueda
@@ -0,0 +1,46 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { post } from '@rails/request.js'
3
+ import { Rollbar } from 'rollbar'
4
+
5
+ // Connects to data-controller="notifications"
6
+ export default class extends Controller {
7
+ timeoutId = null
8
+
9
+ connect () {
10
+ this.element.addEventListener('shown.bs.collapse', event => {
11
+ this.timeoutId = setTimeout(() => {
12
+ this.markAsSeen()
13
+ }, 2000)
14
+ document.addEventListener('turbo:load', () => { this.cancelTimeout() })
15
+ })
16
+ this.element.addEventListener('hide.bs.collapse', event => {
17
+ clearTimeout(this.timeoutId)
18
+ })
19
+ }
20
+
21
+ async markAsSeen () {
22
+ const ids = []
23
+ document.querySelectorAll('.notification')
24
+ .forEach((e) => { ids.push(e.dataset.id) })
25
+ const response = await post('/u/notifications/mark_as_seen',
26
+ { query: { ids }, responseKind: 'turbo-stream' })
27
+
28
+ if (response.ok) {
29
+ document.querySelectorAll('.notification.unseen').forEach(
30
+ (notif) => {
31
+ notif.classList.remove('unseen')
32
+ }
33
+ )
34
+ document.querySelector('.notifications-unseen-mark').remove()
35
+ } else {
36
+ const text = await response.text
37
+ Rollbar.error('Error marking as seen: ', text)
38
+ }
39
+ }
40
+
41
+ cancelTimeout () {
42
+ if (this.timeoutId) {
43
+ clearTimeout(this.timeoutId)
44
+ }
45
+ }
46
+ }
@@ -1,7 +1,8 @@
1
1
  <nav class="navbar navbar-expand-<%= @breakpoint_navbar_expand %>" data-bs-theme="dark">
2
2
  <div class="container-fluid">
3
3
  <% unless @sidebar == false %>
4
- <button data-controller="navbar" data-action="navbar#expandNavbar" class="btn btn-outline-light me-2 d-none d-<%= @breakpoint_navbar_expand %>-inline-block">
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">
5
6
  <i class="bi <%= @navbar_chevron_class %>"></i>
6
7
  </button>
7
8
 
@@ -9,12 +10,43 @@
9
10
  <% @navbar.extensiones.each do |extension| %>
10
11
  <%= extension %>
11
12
  <% end %>
13
+ <% if Current.user.present? %>
14
+ <button type="button" class="btn btn-primary btn-sm position-relative"
15
+ data-bs-toggle="collapse" data-bs-target="#notifications-collapse">
16
+ <i class="bi-bell-fill fs-5 text-light"></i>
17
+ <% if @unseen_notifications %>
18
+ <span class="position-absolute p-1 xbg-danger bg-gradient rounded-circle start-50 notifications-unseen-mark">
19
+ </span>
20
+ <% end %>
21
+ </button>
22
+ <% end %>
12
23
  <%= @navbar.logo if @navbar.logo.present? %>
13
- <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">
24
+ <button class="btn btn-outline-light d-inline-block d-<%= @breakpoint_navbar_expand %>-none"
25
+ type="button"
26
+ data-bs-toggle="offcanvas"
27
+ data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
14
28
  <i class="bi bi-list"></i>
15
29
  </button>
16
30
  </div>
17
31
  </nav>
32
+ <div class="collapse" id="notifications-collapse" data-controller="notifications">
33
+ <div id="notifications">
34
+ <div id="notifications-inner">
35
+ <% if @notifications&.any? %>
36
+ <%= render NotificationComponent.with_collection(@notifications) if @notifications&.any? %>
37
+ <% else %>
38
+ <span class="text-light">
39
+ No hay notificaciones
40
+ </span>
41
+ <% end %>
42
+ <div class="text-center">
43
+ <button type="button" class="btn btn-link text-light btn-sm" data-bs-toggle="collapse" data-bs-target="#notifications-collapse">
44
+ <i class="bi-chevron-up fs-3"></i>
45
+ </button>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
18
50
 
19
51
  <style type="text/css" media="(max-width: 767px)">
20
52
  .navbar .navbar-brand {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.0.8-alpha.93'
4
+ VERSION = '7.0.8-alpha.95'
5
5
  end
@@ -11,12 +11,16 @@ $teal: #20c997 !default;
11
11
  $cyan: #0dcaf0 !default;
12
12
 
13
13
  // Overriding some of the default colours
14
+ $yellow: #ffb401;
14
15
  $orange: #e35b17;
15
16
  $red: #a70101;
16
17
 
17
- $warning: $orange;
18
+ $warning: $yellow;
18
19
  $info: #87accc;
19
20
 
21
+ $warning-text-emphasis: $orange;
22
+ $danger-text-emphasis: #910303;
23
+
20
24
  $font-size-base: 0.9rem;
21
25
  $enable-validation-icons: false;
22
26
  $focus-ring-width: .05rem;
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.93
4
+ version: 7.0.8.pre.alpha.95
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-06-09 00:00:00.000000000 Z
11
+ date: 2024-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -968,6 +968,7 @@ files:
968
968
  - pg_engine/app/assets/images/plantita.png
969
969
  - pg_engine/app/assets/javascripts/active_admin.js
970
970
  - pg_engine/app/assets/stylesheets/active_admin.scss
971
+ - pg_engine/app/assets/stylesheets/notifications.scss
971
972
  - pg_engine/app/assets/stylesheets/pg_rails_b5.scss
972
973
  - pg_engine/app/components/alert_component.html.slim
973
974
  - pg_engine/app/components/alert_component.rb
@@ -975,6 +976,7 @@ files:
975
976
  - pg_engine/app/components/base_component.rb
976
977
  - pg_engine/app/components/flash_container_component.rb
977
978
  - pg_engine/app/components/internal_error_component.rb
979
+ - pg_engine/app/components/notification_component.rb
978
980
  - pg_engine/app/controllers/admin/accounts_controller.rb
979
981
  - pg_engine/app/controllers/admin/email_logs_controller.rb
980
982
  - pg_engine/app/controllers/admin/emails_controller.rb
@@ -988,6 +990,7 @@ files:
988
990
  - pg_engine/app/controllers/public/mensaje_contactos_controller.rb
989
991
  - pg_engine/app/controllers/public/webhooks_controller.rb
990
992
  - pg_engine/app/controllers/users/confirmations_controller.rb
993
+ - pg_engine/app/controllers/users/notifications_controller.rb
991
994
  - pg_engine/app/controllers/users/registrations_controller.rb
992
995
  - pg_engine/app/decorators/account_decorator.rb
993
996
  - pg_engine/app/decorators/email_decorator.rb
@@ -1020,6 +1023,8 @@ files:
1020
1023
  - pg_engine/app/models/pg_engine/base_record.rb
1021
1024
  - pg_engine/app/models/user.rb
1022
1025
  - pg_engine/app/models/user_account.rb
1026
+ - pg_engine/app/notifiers/application_notifier.rb
1027
+ - pg_engine/app/notifiers/simple_user_notifier.rb
1023
1028
  - pg_engine/app/policies/account_policy.rb
1024
1029
  - pg_engine/app/policies/email_log_policy.rb
1025
1030
  - pg_engine/app/policies/email_policy.rb
@@ -1081,6 +1086,8 @@ files:
1081
1086
  - pg_engine/db/migrate/20240506194106_create_emails.rb
1082
1087
  - pg_engine/db/migrate/20240517174821_pg_trgm.rb
1083
1088
  - pg_engine/db/migrate/20240523183651_create_email_logs.rb
1089
+ - pg_engine/db/migrate/20240611000219_create_noticed_tables.noticed.rb
1090
+ - pg_engine/db/migrate/20240611000220_add_notifications_count_to_noticed_event.noticed.rb
1084
1091
  - pg_engine/db/seeds.rb
1085
1092
  - pg_engine/lib/pg_engine.rb
1086
1093
  - pg_engine/lib/pg_engine/configuracion.rb
@@ -1141,6 +1148,7 @@ files:
1141
1148
  - pg_engine/spec/system/alerts_spec.rb
1142
1149
  - pg_engine/spec/system/destroy_spec.rb
1143
1150
  - pg_engine/spec/system/login_spec.rb
1151
+ - pg_engine/spec/system/noticed_spec.rb
1144
1152
  - pg_engine/spec/system/send_mail_spec.rb
1145
1153
  - pg_engine/spec/system/signup_spec.rb
1146
1154
  - pg_layout/app/assets/stylesheets/animations.scss
@@ -1161,6 +1169,7 @@ files:
1161
1169
  - pg_layout/app/javascript/controllers/index.js
1162
1170
  - pg_layout/app/javascript/controllers/navbar_controller.js
1163
1171
  - pg_layout/app/javascript/controllers/nested_controller.js
1172
+ - pg_layout/app/javascript/controllers/notifications_controller.js
1164
1173
  - pg_layout/app/javascript/controllers/pg_form_controller.js
1165
1174
  - pg_layout/app/javascript/controllers/switcher_controller.js
1166
1175
  - pg_layout/app/javascript/utils/cookies.js