thecore_ui_rails_admin 3.5.8 → 3.6.0

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: 9f3b1d3b931160459500623465f879508c7a8016e8d546ef28a1422ce8d3fa45
4
- data.tar.gz: '0858e5d038ae454a4def611ea66343b7ad928715c9573606a4fcaa9c7c59c891'
3
+ metadata.gz: 5f0f9ff82a9d4a2cc4314ccc51dd88fcfe37059009d1938ed60368da30568813
4
+ data.tar.gz: ff995296978667fe0d7c63195bda829687a5d11d7dc048d139750990e5171ea9
5
5
  SHA512:
6
- metadata.gz: f9cc83f7e2ce4bff365bcaeb833eb4b88df8e56ead10690a5689aa92a18c65d117bc791b1836acc97650cd5cf0222833b085c055f7f75a82ee0d58282f2399c2
7
- data.tar.gz: d9c2c049d9f8fc2a61255794e1825fe660e667105f3b05ba9afad422e2f55ed3c3890075b4bcf6b2dea5b081b7c9e291c5521d0cdd64b11080ba52ff932e0720
6
+ metadata.gz: 9a1f1bc950e6dce9e7cfd85d3353bbd565665c902d796db09d636bb2a624d88bf2cb0ee59753453f42649dbdd6fd40204cdab4fbb8db63b4ddf5499dc431386b
7
+ data.tar.gz: 61a7520b5a29ace19b4d42950484efd0dae62371bd07baf3210d937286478a821afeb2f2ebd80056a1780f1db1d9e41a277f423b6e23fcd5102bc5bc58f5bc1f
data/README.md CHANGED
@@ -1 +1,55 @@
1
- This is part of Thecore framework: https://github.com/gabrieletassoni/thecore/tree/release/3
1
+ This is part of [Thecore framework](https://github.com/gabrieletassoni/thecore/tree/release/3).
2
+
3
+ ---
4
+
5
+ ## Push Notification Test (RailsAdmin root action)
6
+
7
+ A built-in admin UI for sending Web Push test notifications. It lets you pick one or more active subscribers and fire a real notification immediately — useful for verifying the end-to-end VAPID setup without writing any code.
8
+
9
+ ### Prerequisites
10
+
11
+ 1. `rails db:seed` has run (VAPID keys generated in `ThecoreSettings`).
12
+ 2. At least one browser has registered a push subscription (via the React client's `subscribeToPush()` — see the [`model_driven_api` README](../model_driven_api/README.md#web-push-vapid-from-a-react-client)).
13
+ 3. The current RailsAdmin user can `manage :push_message` (or `manage :all`).
14
+
15
+ ### Accessing the action
16
+
17
+ In RailsAdmin, click **Push Notification Test** in the top navigation bar (root actions area).
18
+
19
+ ### Using the form
20
+
21
+ | Field | Required | Description |
22
+ |-------|----------|-------------|
23
+ | Subscribers | Yes | Checkboxes listing all active `PushSubscriber` records — shows endpoint and associated user. Select one or more. |
24
+ | Title | Yes | Notification title (shown in bold in the OS notification). |
25
+ | Body | Yes | Notification body text. |
26
+ | URL | No | URL opened when the user clicks the notification. |
27
+ | Icon | No | URL of the notification icon image. |
28
+
29
+ Click **Send Test** to dispatch. The backend creates one `PushMessage` per selected subscriber and calls `PushNotificationService.dispatch` for each. A flash notice reports how many notifications were sent.
30
+
31
+ ### Troubleshooting
32
+
33
+ | Symptom | Likely cause |
34
+ |---------|-------------|
35
+ | No subscribers listed | No browser has called `POST subscribe` yet, or all subscriptions have expired. |
36
+ | "Subscriber not found" error | The subscriber expired between page load and submit — reload the page. |
37
+ | Notification not delivered | Check `ThecoreSettings vapid.public_key` / `vapid.private_key` are set; check `vapid.contact_email` is a valid `mailto:` address; check the browser's notification permission is "Allow". |
38
+ | `IntegrationLog` shows errors | The push service (browser vendor) returned an error — usually 410 (expired) which auto-expires the subscriber, or 400 (malformed VAPID keys). |
39
+
40
+ ### Sending pushes programmatically
41
+
42
+ The same flow available in the UI can be triggered from anywhere in the backend:
43
+
44
+ ```ruby
45
+ subscriber = PushSubscriber.active.find(42)
46
+ message = subscriber.push_messages.create!(
47
+ title: "Hello",
48
+ body: "This is a test notification",
49
+ url: "https://yourapp.com/tasks/1",
50
+ icon: "https://yourapp.com/icon-192.png"
51
+ )
52
+ ThecoreBackendCommons::PushNotificationService.dispatch(subscriber, message)
53
+ ```
54
+
55
+ Or via the REST API from a privileged client (see [`send_push` in the model_driven_api README](../model_driven_api/README.md#step-5--send-a-push-from-the-backend-optional)).
@@ -0,0 +1,76 @@
1
+ <span class="hide-toolbar"></span>
2
+
3
+ <div class="container mt-4">
4
+ <h2>Push Notification Test</h2>
5
+
6
+ <% if flash[:success].present? %>
7
+ <div class="alert alert-success"><%= flash[:success] %></div>
8
+ <% end %>
9
+ <% if flash[:error].present? %>
10
+ <div class="alert alert-danger"><%= flash[:error] %></div>
11
+ <% end %>
12
+
13
+ <%= form_with url: push_notification_test_path, method: :post, local: true do |form| %>
14
+ <div class="card mb-4">
15
+ <div class="card-header">
16
+ <h5 class="mb-0">Select Subscribers</h5>
17
+ </div>
18
+ <div class="card-body">
19
+ <% if @subscribers.any? %>
20
+ <% @subscribers.each do |subscriber| %>
21
+ <div class="form-check">
22
+ <%= check_box_tag "subscriber_ids[]",
23
+ subscriber.id,
24
+ false,
25
+ class: "form-check-input",
26
+ id: "subscriber_#{subscriber.id}" %>
27
+ <label class="form-check-label" for="subscriber_<%= subscriber.id %>">
28
+ <strong><%= subscriber.user&.email || "user ##{subscriber.user_id}" %></strong>
29
+ &mdash; <code><%= subscriber.endpoint.truncate(80) %></code>
30
+ <% if subscriber.user_agent.present? %>
31
+ <small class="text-muted">(<%= subscriber.user_agent.truncate(50) %>)</small>
32
+ <% end %>
33
+ </label>
34
+ </div>
35
+ <% end %>
36
+ <% else %>
37
+ <p class="text-muted">No active subscribers found.</p>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="card mb-4">
43
+ <div class="card-header">
44
+ <h5 class="mb-0">Message</h5>
45
+ </div>
46
+ <div class="card-body">
47
+ <div class="mb-3">
48
+ <%= form.label :title, "Title", class: "form-label" %>
49
+ <%= form.text_field :title, class: "form-control", required: true,
50
+ placeholder: "Notification title" %>
51
+ </div>
52
+
53
+ <div class="mb-3">
54
+ <%= form.label :body, "Body", class: "form-label" %>
55
+ <%= form.text_area :body, class: "form-control", rows: 3, required: true,
56
+ placeholder: "Notification body text" %>
57
+ </div>
58
+
59
+ <div class="mb-3">
60
+ <%= form.label :url, "URL (optional)", class: "form-label" %>
61
+ <%= form.url_field :url, class: "form-control",
62
+ placeholder: "https://example.com/target-page" %>
63
+ </div>
64
+
65
+ <div class="mb-3">
66
+ <%= form.label :icon, "Icon URL (optional)", class: "form-label" %>
67
+ <%= form.url_field :icon, class: "form-control",
68
+ placeholder: "https://example.com/icon.png" %>
69
+ </div>
70
+
71
+ <%= form.submit "Send Test", class: "btn btn-primary",
72
+ disabled: @subscribers.empty? %>
73
+ </div>
74
+ </div>
75
+ <% end %>
76
+ </div>
@@ -47,6 +47,7 @@ Rails.application.configure do
47
47
 
48
48
  require "root_actions/general_computation"
49
49
  require "root_actions/active_job_monitor"
50
+ require "root_actions/push_notification_test"
50
51
  require "member_actions/change_password"
51
52
  require "member_actions/test_ldap_server"
52
53
  # require 'member_actions/import_users_from_ldap' # Disabled as it's a bit risky to have it in the UI
@@ -54,6 +54,12 @@ en:
54
54
  title: Load Filters
55
55
  breadcrumb: Load Filters
56
56
  menu: Load Filters
57
+ push_notification_test:
58
+ menu: Test Push Notification
59
+ title: Test Push Notification
60
+ breadcrumb: Test Push Notification
61
+ success: "Sent test notification to %{count} subscriber(s)"
62
+ error_blank_title: "Title can't be blank"
57
63
  scopes:
58
64
  _all: All
59
65
  flash:
@@ -1,12 +1,12 @@
1
1
  it:
2
- active_record_range_error: "ActiveRecord::RangeError: Questo potrebbe essere dovuto a un valore fuori intervallo. Si prega di considerare l'uso di filtri specifici sugli attributi per restringere la query."
3
- are_you_sure: Sei sicuro? Questa operazione, se eseguita su una grande quantitá di dati, puó bloccare il server.
2
+ active_record_range_error: "ActiveRecord::RangeError: Questo potrebbe essere dovuto a un valore fuori intervallo. Si prega di usare filtri specifici sugli attributi per restringere la query."
3
+ are_you_sure: Sei sicuro? Questa operazione, se eseguita su una grande quantità di dati, può bloccare il server.
4
4
  export: Esporta
5
5
  export_all: Esporta Tutti
6
6
  export_found: Esporta i Filtrati
7
7
  export_selected: Esporta i Selezionati
8
8
  delete_selected: Elimina i Selezionati
9
- yes: "Si"
9
+ yes: ""
10
10
  no: "No"
11
11
  error: Errore
12
12
  question: Domanda
@@ -41,7 +41,7 @@ it:
41
41
  breadcrumb: Cambia Password
42
42
  menu: Cambia Password
43
43
  success: La tua password è stata cambiata con successo
44
- error: Attenzione! %{errors}
44
+ error: "Attenzione! %{errors}"
45
45
  save_filters:
46
46
  success: Filtri salvati con successo
47
47
  error: Errore durante il salvataggio dei filtri
@@ -54,11 +54,17 @@ it:
54
54
  title: Carica Filtri
55
55
  breadcrumb: Carica Filtri
56
56
  menu: Carica Filtri
57
+ push_notification_test:
58
+ menu: Test Notifica Push
59
+ title: Test Notifica Push
60
+ breadcrumb: Test Notifica Push
61
+ success: "Notifica di test inviata a %{count} sottoscrittore/i"
62
+ error_blank_title: "Il titolo non può essere vuoto"
57
63
  scopes:
58
64
  _all: Tutti
59
65
  flash:
60
66
  error: "Impossibile eseguire l'azione %{action} (%{name})"
61
- model_not_found: Impossibile trovare il modello '%{model}'
67
+ model_not_found: "Impossibile trovare il modello '%{model}'"
62
68
  noaction: Impossibile eseguire l'azione
63
69
  object_not_found: "Impossibile trovare il modello %{model} con id '%{id}'"
64
70
  successful: "Azione eseguita con successo: %{action} (%{name})"
@@ -66,7 +72,7 @@ it:
66
72
  advanced:
67
73
  label: Avanzate
68
74
  logs:
69
- label: Logs
75
+ label: Log
70
76
  registries:
71
77
  label: Anagrafiche
72
78
  operations:
@@ -76,20 +82,20 @@ it:
76
82
  js:
77
83
  true: Vero
78
84
  false: Falso
79
- is_present: Is present
80
- is_blank: Is blank
81
- date: Date ...
82
- between_and_: Between ... and ...
83
- today: Today
84
- yesterday: Yesterday
85
- this_week: This week
86
- last_week: Last week
87
- number: Number ...
88
- contains: Contains
89
- is_exactly: Is exactly
90
- starts_with: Starts with
91
- ends_with: Ends with
92
- too_many_objects: "Too many objects, use search box above"
93
- no_objects: "No objects found"
94
- loading: "Loading..."
95
- toggle_navigation: Toggle navigation
85
+ is_present: È presente
86
+ is_blank: È vuoto
87
+ date: Data...
88
+ between_and_: Tra... e...
89
+ today: Oggi
90
+ yesterday: Ieri
91
+ this_week: Questa settimana
92
+ last_week: La settimana scorsa
93
+ number: Numero...
94
+ contains: Contiene
95
+ is_exactly: È esattamente
96
+ starts_with: Inizia con
97
+ ends_with: Termina con
98
+ too_many_objects: "Troppi oggetti, usa il campo di ricerca sopra"
99
+ no_objects: "Nessun oggetto trovato"
100
+ loading: "Caricamento..."
101
+ toggle_navigation: Mostra/Nascondi navigazione
@@ -0,0 +1,53 @@
1
+ RailsAdmin::Config::Actions.add_action "push_notification_test", :base, :root do
2
+ show_in_sidebar true
3
+ show_in_navigation false
4
+ breadcrumb_parent [nil]
5
+
6
+ member false
7
+ collection false
8
+
9
+ link_icon "fas fa-bell"
10
+
11
+ http_methods [:get, :post]
12
+
13
+ controller do
14
+ proc do
15
+ @subscribers = PushSubscriber.active.includes(:user)
16
+
17
+ if request.post?
18
+ params.permit!
19
+ title = params[:title].to_s.strip
20
+ body = params[:body].to_s.strip
21
+
22
+ if title.blank?
23
+ flash.now[:error] = I18n.t(
24
+ "admin.actions.push_notification_test.error_blank_title",
25
+ default: "Title can't be blank"
26
+ )
27
+ render action: :push_notification_test, status: :unprocessable_entity
28
+ else
29
+ subscriber_ids = Array(params[:subscriber_ids]).map(&:to_i).select(&:positive?)
30
+ subscribers = PushSubscriber.where(id: subscriber_ids)
31
+
32
+ subscribers.each do |subscriber|
33
+ message = PushMessage.create!(
34
+ push_subscriber: subscriber,
35
+ title: title,
36
+ body: body,
37
+ url: params[:url].presence,
38
+ icon: params[:icon].presence
39
+ )
40
+ ThecoreBackendCommons::PushNotificationService.dispatch(subscriber, message)
41
+ end
42
+
43
+ flash[:success] = I18n.t(
44
+ "admin.actions.push_notification_test.success",
45
+ count: subscribers.size,
46
+ default: "Sent test notification to %{count} subscriber(s)"
47
+ )
48
+ redirect_to push_notification_test_path
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module ThecoreUiRailsAdmin
2
- VERSION = "3.5.8".freeze
2
+ VERSION = "3.6.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thecore_ui_rails_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.8
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni
@@ -93,6 +93,7 @@ files:
93
93
  - app/views/rails_admin/main/general_computation.html.erb
94
94
  - app/views/rails_admin/main/import_users_from_ldap.html.erb
95
95
  - app/views/rails_admin/main/load_filters.html.erb
96
+ - app/views/rails_admin/main/push_notification_test.html.erb
96
97
  - app/views/rails_admin/main/save_filter.html.erb
97
98
  - app/views/rails_admin/main/test_ldap_server.html.erb
98
99
  - app/views/rails_admin/main/test_ldap_server.js.erb
@@ -129,6 +130,7 @@ files:
129
130
  - lib/rails_admin_filter_controller_helper.rb
130
131
  - lib/root_actions/active_job_monitor.rb
131
132
  - lib/root_actions/general_computation.rb
133
+ - lib/root_actions/push_notification_test.rb
132
134
  - lib/tasks/thecore_ui_rails_admin_tasks.rake
133
135
  - lib/thecore_ui_rails_admin.rb
134
136
  - lib/thecore_ui_rails_admin/engine.rb