pg_rails 7.0.8.pre.alpha.94 → 7.0.8.pre.alpha.96
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 +4 -4
- data/pg_engine/app/assets/stylesheets/notifications.scss +49 -0
- data/pg_engine/app/assets/stylesheets/pg_rails_b5.scss +3 -0
- data/pg_engine/app/components/notification_component.rb +19 -0
- data/pg_engine/app/controllers/pg_engine/base_controller.rb +5 -0
- data/pg_engine/app/controllers/users/notifications_controller.rb +11 -0
- data/pg_engine/app/models/email_log.rb +0 -1
- data/pg_engine/app/models/user.rb +1 -0
- data/pg_engine/app/notifiers/application_notifier.rb +2 -0
- data/pg_engine/app/notifiers/simple_user_notifier.rb +28 -0
- data/pg_engine/config/initializers/anycable.rb +3 -0
- data/pg_engine/config/routes.rb +3 -0
- data/pg_engine/db/migrate/20240611000219_create_noticed_tables.noticed.rb +37 -0
- data/pg_engine/db/migrate/20240611000220_add_notifications_count_to_noticed_event.noticed.rb +6 -0
- data/pg_engine/spec/system/noticed_spec.rb +36 -0
- data/pg_layout/app/javascript/controllers/index.js +2 -0
- data/pg_layout/app/javascript/controllers/notifications_controller.js +46 -0
- data/pg_layout/app/views/pg_layout/_navbar.html.erb +34 -2
- data/pg_rails/lib/version.rb +1 -1
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c58d9873f250d2dd6439cb23e9a78d04439050bd55834021f46f829f42ea9c6
|
4
|
+
data.tar.gz: a4796df1040075127fcb5045d0ac6841dfd27e49326c17b6189ce41343d14c97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff4ab5046138fc43e3e5e4ffb4e9047bc7082d7a72c67809d42af3dd35027c5eadd27755d7cec9b42cba57d9b43fa68ced6bcce4d10b3615df22af896a275eb3
|
7
|
+
data.tar.gz: 8446251043b39d5180a933cea8bd561d05f17b421951ac69654fcb358075679c0775a06bd2580f82fcd4d0497a65522039ada390cd4422debc5b76258b65a0a8
|
@@ -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
|
+
}
|
@@ -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
|
@@ -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
|
data/pg_engine/config/routes.rb
CHANGED
@@ -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,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"
|
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"
|
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 {
|
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.0.8.pre.alpha.
|
4
|
+
version: 7.0.8.pre.alpha.96
|
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-
|
11
|
+
date: 2024-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -542,6 +542,20 @@ dependencies:
|
|
542
542
|
- - "~>"
|
543
543
|
- !ruby/object:Gem::Version
|
544
544
|
version: 3.12.1
|
545
|
+
- !ruby/object:Gem::Dependency
|
546
|
+
name: noticed
|
547
|
+
requirement: !ruby/object:Gem::Requirement
|
548
|
+
requirements:
|
549
|
+
- - "~>"
|
550
|
+
- !ruby/object:Gem::Version
|
551
|
+
version: '2.3'
|
552
|
+
type: :runtime
|
553
|
+
prerelease: false
|
554
|
+
version_requirements: !ruby/object:Gem::Requirement
|
555
|
+
requirements:
|
556
|
+
- - "~>"
|
557
|
+
- !ruby/object:Gem::Version
|
558
|
+
version: '2.3'
|
545
559
|
- !ruby/object:Gem::Dependency
|
546
560
|
name: vcr
|
547
561
|
requirement: !ruby/object:Gem::Requirement
|
@@ -968,6 +982,7 @@ files:
|
|
968
982
|
- pg_engine/app/assets/images/plantita.png
|
969
983
|
- pg_engine/app/assets/javascripts/active_admin.js
|
970
984
|
- pg_engine/app/assets/stylesheets/active_admin.scss
|
985
|
+
- pg_engine/app/assets/stylesheets/notifications.scss
|
971
986
|
- pg_engine/app/assets/stylesheets/pg_rails_b5.scss
|
972
987
|
- pg_engine/app/components/alert_component.html.slim
|
973
988
|
- pg_engine/app/components/alert_component.rb
|
@@ -975,6 +990,7 @@ files:
|
|
975
990
|
- pg_engine/app/components/base_component.rb
|
976
991
|
- pg_engine/app/components/flash_container_component.rb
|
977
992
|
- pg_engine/app/components/internal_error_component.rb
|
993
|
+
- pg_engine/app/components/notification_component.rb
|
978
994
|
- pg_engine/app/controllers/admin/accounts_controller.rb
|
979
995
|
- pg_engine/app/controllers/admin/email_logs_controller.rb
|
980
996
|
- pg_engine/app/controllers/admin/emails_controller.rb
|
@@ -988,6 +1004,7 @@ files:
|
|
988
1004
|
- pg_engine/app/controllers/public/mensaje_contactos_controller.rb
|
989
1005
|
- pg_engine/app/controllers/public/webhooks_controller.rb
|
990
1006
|
- pg_engine/app/controllers/users/confirmations_controller.rb
|
1007
|
+
- pg_engine/app/controllers/users/notifications_controller.rb
|
991
1008
|
- pg_engine/app/controllers/users/registrations_controller.rb
|
992
1009
|
- pg_engine/app/decorators/account_decorator.rb
|
993
1010
|
- pg_engine/app/decorators/email_decorator.rb
|
@@ -1020,6 +1037,8 @@ files:
|
|
1020
1037
|
- pg_engine/app/models/pg_engine/base_record.rb
|
1021
1038
|
- pg_engine/app/models/user.rb
|
1022
1039
|
- pg_engine/app/models/user_account.rb
|
1040
|
+
- pg_engine/app/notifiers/application_notifier.rb
|
1041
|
+
- pg_engine/app/notifiers/simple_user_notifier.rb
|
1023
1042
|
- pg_engine/app/policies/account_policy.rb
|
1024
1043
|
- pg_engine/app/policies/email_log_policy.rb
|
1025
1044
|
- pg_engine/app/policies/email_policy.rb
|
@@ -1081,6 +1100,8 @@ files:
|
|
1081
1100
|
- pg_engine/db/migrate/20240506194106_create_emails.rb
|
1082
1101
|
- pg_engine/db/migrate/20240517174821_pg_trgm.rb
|
1083
1102
|
- pg_engine/db/migrate/20240523183651_create_email_logs.rb
|
1103
|
+
- pg_engine/db/migrate/20240611000219_create_noticed_tables.noticed.rb
|
1104
|
+
- pg_engine/db/migrate/20240611000220_add_notifications_count_to_noticed_event.noticed.rb
|
1084
1105
|
- pg_engine/db/seeds.rb
|
1085
1106
|
- pg_engine/lib/pg_engine.rb
|
1086
1107
|
- pg_engine/lib/pg_engine/configuracion.rb
|
@@ -1141,6 +1162,7 @@ files:
|
|
1141
1162
|
- pg_engine/spec/system/alerts_spec.rb
|
1142
1163
|
- pg_engine/spec/system/destroy_spec.rb
|
1143
1164
|
- pg_engine/spec/system/login_spec.rb
|
1165
|
+
- pg_engine/spec/system/noticed_spec.rb
|
1144
1166
|
- pg_engine/spec/system/send_mail_spec.rb
|
1145
1167
|
- pg_engine/spec/system/signup_spec.rb
|
1146
1168
|
- pg_layout/app/assets/stylesheets/animations.scss
|
@@ -1161,6 +1183,7 @@ files:
|
|
1161
1183
|
- pg_layout/app/javascript/controllers/index.js
|
1162
1184
|
- pg_layout/app/javascript/controllers/navbar_controller.js
|
1163
1185
|
- pg_layout/app/javascript/controllers/nested_controller.js
|
1186
|
+
- pg_layout/app/javascript/controllers/notifications_controller.js
|
1164
1187
|
- pg_layout/app/javascript/controllers/pg_form_controller.js
|
1165
1188
|
- pg_layout/app/javascript/controllers/switcher_controller.js
|
1166
1189
|
- pg_layout/app/javascript/utils/cookies.js
|