Skip to content

Commit

Permalink
Notifications - When a notification is dispatched to many users, ensu…
Browse files Browse the repository at this point in the history
…re that if one of them acknowledges it, the notification is removed for all users.
  • Loading branch information
csavelief committed Sep 11, 2024
1 parent 0964908 commit 27bdb26
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 17 deletions.
5 changes: 5 additions & 0 deletions app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,13 @@ public function index(Request $request)
return [
'id' => $notification->id,
'data' => $notification->data,
'timestamp' => $notification->updated_at->format('Y-m-d H:i') . ' UTC',
];
})
->sortBy([
['timestamp', 'desc']
])
->values()
->all();

return view('home.index', compact(
Expand Down
4 changes: 4 additions & 0 deletions app/Notifications/HealthCheckIssue.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@
use App\Models\YnhServer;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;

class HealthCheckIssue extends Notification
{
use Queueable;

private YnhServer $server;
private string $group;

/**
* Create a new notification instance.
*/
public function __construct(YnhServer $server)
{
$this->server = $server;
$this->group = Str::random(10);
}

/**
Expand Down Expand Up @@ -50,6 +53,7 @@ public function via(object $notifiable): array
public function toArray(object $notifiable): array
{
return [
'group' => $this->group,
'type' => NotificationTypeEnum::HEALTHCHECK_ISSUE->value,
'level' => NotificationLevelEnum::DANGER->value,
'message' => "A health check issue has been detected: no metrics have been recorded in the past 20 minutes.",
Expand Down
15 changes: 9 additions & 6 deletions resources/views/layouts/_notifications.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
let notifications = @json($notifications);
function dismissNotification(notificationId) {
axios.get(`{{ url('/notification/${notificationId}/dismiss') }}`).then(response => {
axios.get(`{{ url('/notifications/${notificationId}/dismiss') }}`).then(response => {
toaster.el.toast('The notification has been dismissed!', 'success');
}).catch(error => {
toaster.el.toast('An error occurred.', 'danger');
console.error('Error:', error);
});
notifications = notifications.filter(notification => notification.id !== notificationId);
drawer25.redraw();
const notification = notifications.find(notif => notif.id === notificationId);
if (notification) {
notifications = notifications.filter(notif => notif.data.group !== notification.data.group);
}
drawer33.redraw();
}
function showNotifications() {
drawer25.render = () => {
drawer33.render = () => {
const rows = notifications.map(notification => {
let details = '';
for (let key in notification.data.details) {
Expand All @@ -40,7 +43,7 @@ function showNotifications() {
return `
<div class="card border-${notification.data.level} m-1">
<div class="card-body p-2">
<h6 class="card-title">${notification.data.type}</h6>
<h6 class="card-title">${notification.data.type}&nbsp;<span style="color:#f8b502">/</span>&nbsp;${notification.timestamp}</h6>
<p class="card-text">${notification.data.message}</p>
<h6 class="card-title">DETAILS</h6>
<ul>
Expand All @@ -60,6 +63,6 @@ function showNotifications() {
});
return `<div class="container p-0 overflow-y-scroll" style="height:100vh;">${rows.join('')}</div>`;
};
drawer25.el.show = true;
drawer33.el.show = true;
}
</script>
18 changes: 9 additions & 9 deletions resources/views/layouts/app.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
</main>
</div>
<div id="toaster"></div>
<div id="drawer-25"></div>
<div id="drawer-33"></div>

<!-- Scripts -->
@stack('alpine')
Expand All @@ -179,21 +179,21 @@
el: new com.computablefacts.blueprintjs.MinimalToaster(document.getElementById('toaster')),
toast: (msg, intent) => toaster.el.toast(msg, intent)
};
const drawer25 = {
el: new com.computablefacts.blueprintjs.MinimalDrawer(document.getElementById('drawer-25'), '25%'),
const drawer33 = {
el: new com.computablefacts.blueprintjs.MinimalDrawer(document.getElementById('drawer-33'), '33%'),
redraw: null,
render: null
};
drawer25.el.onOpen(el => {
drawer33.el.onOpen(el => {
// console.log(drawer);
const div = document.createElement('div');
div.innerHTML = drawer25.render ? drawer25.render() : '';
div.innerHTML = drawer33.render ? drawer33.render() : '';
el.appendChild(div);
drawer25.redraw = () => div.innerHTML = drawer25.render ? drawer25.render() : '';
drawer33.redraw = () => div.innerHTML = drawer33.render ? drawer33.render() : '';
});
drawer25.el.onClose(() => {
drawer25.redraw = null;
drawer25.render = null;
drawer33.el.onClose(() => {
drawer33.redraw = null;
drawer33.render = null;
});
</script>
Expand Down
7 changes: 5 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,11 @@
return view('auth.passwords.email', compact('email'));
})->middleware('auth')->name('reset-password');

Route::get('/notification/{notification}/dismiss', function (\Illuminate\Notifications\DatabaseNotification $notification, \Illuminate\Http\Request $request) {
$notification->markAsRead();
Route::get('/notifications/{notification}/dismiss', function (\Illuminate\Notifications\DatabaseNotification $notification, \Illuminate\Http\Request $request) {
\Illuminate\Notifications\DatabaseNotification::query()
->whereJsonContains('data->group', $notification->data['group'])
->get()
->each(fn($notif) => $notif->markAsRead());
})->middleware('auth');

Route::group(['prefix' => 'ynh', 'as' => 'ynh.'], function () {
Expand Down

0 comments on commit 27bdb26

Please sign in to comment.