From 276690672b41bd50f074e834df181899e46e222b Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 5 Jun 2024 09:29:08 +0200 Subject: [PATCH 01/18] Add new route for mass update --- resources/assets/js/core/api/notifications.js | 8 +++++++- routes/api.php | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/assets/js/core/api/notifications.js b/resources/assets/js/core/api/notifications.js index ed94f8038..2f046c6ea 100644 --- a/resources/assets/js/core/api/notifications.js +++ b/resources/assets/js/core/api/notifications.js @@ -14,5 +14,11 @@ * @type {Vue.resource} */ export default Vue.resource('api/v1/notifications{/id}', {}, { - markRead: {method: 'PUT'} + markRead: { + method: 'PUT' + }, + markReadAll:{ + method: 'PUT', + } }); + diff --git a/routes/api.php b/routes/api.php index c24cb026c..89bfa6ffd 100644 --- a/routes/api.php +++ b/routes/api.php @@ -147,6 +147,8 @@ 'only' => ['update', 'destroy'], ]); +$router->put('notifications', 'NotificationController@updateAll'); + $router->resource('projects', 'ProjectController', [ 'only' => ['index', 'show', 'update', 'store', 'destroy'], 'parameters' => ['projects' => 'id'], From 85a0aba5b394cd12a1b79e3316fa0debeab1f022 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 5 Jun 2024 09:30:54 +0200 Subject: [PATCH 02/18] Add button to mark all notifications as read --- .../assets/js/core/notifications/list.vue | 18 ++++++++++++++++++ resources/views/notifications/index.blade.php | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/resources/assets/js/core/notifications/list.vue b/resources/assets/js/core/notifications/list.vue index bb019462d..fc37c3612 100644 --- a/resources/assets/js/core/notifications/list.vue +++ b/resources/assets/js/core/notifications/list.vue @@ -73,6 +73,24 @@ export default { return Store.countUnread > 0; }, }, + methods:{ + markAllAsRead(userId) { + this.isLoading = true; + return NotificationsApi.markReadAll({}, {user_id: userId}) + .then(() => { + this.notifications.map(item => { + item.read_at = new Date(); + if (this.removeItem) { + Store.remove(this.item.id); + } + }) + }) + .catch(Messages.handleErrorResponse) + .finally(() => { + this.isLoading = false; + }); + } + }, created() { Store.initialize(); this.notifications = Store.all; diff --git a/resources/views/notifications/index.blade.php b/resources/views/notifications/index.blade.php index 25430efe7..4c6444955 100644 --- a/resources/views/notifications/index.blade.php +++ b/resources/views/notifications/index.blade.php @@ -19,6 +19,12 @@
+ @if (!$all) +

+ +

+ @endif +
@@ -36,6 +42,7 @@
+
@if ($all)

You have no notifications. From ef7a77f15e2f56b46a9a3098d4476976b967441f Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 12:21:12 +0200 Subject: [PATCH 03/18] Add form request --- app/Http/Requests/UpdateAllNotifications.php | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 app/Http/Requests/UpdateAllNotifications.php diff --git a/app/Http/Requests/UpdateAllNotifications.php b/app/Http/Requests/UpdateAllNotifications.php new file mode 100644 index 000000000..c7cd5ee7a --- /dev/null +++ b/app/Http/Requests/UpdateAllNotifications.php @@ -0,0 +1,34 @@ +input('user_id')) || !is_numeric($this->input('user_id'))) { + // Skip authorization if the user id could not be found. The validation rules + // will take care of rejecting this request with the proper response code. + return true; + } + + return $this->user()->id === $this->input('user_id'); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'user_id' => 'required|numeric' + ]; + } +} From 464ef3649dddf6ffcf1cd873c53dcdcc719fa04b Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 12:21:49 +0200 Subject: [PATCH 04/18] Add controller method to mark all notifications --- .../Api/NotificationController.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index eaf180442..0417e77a2 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -3,6 +3,8 @@ namespace Biigle\Http\Controllers\Api; use Illuminate\Http\Request; +use Biigle\Http\Requests\UpdateAllNotifications; +use Illuminate\Notifications\DatabaseNotification; class NotificationController extends Controller { @@ -28,6 +30,29 @@ public function update(Request $request, $id) $notification->markAsRead(); } + /** + * Mark all notification as read. + * + * @api {put} notifications/ Mark all notifications as read + * @apiGroup Notifications + * @apiName UpdateReadNotifications + * @apiPermission user + * + * @apiParamExample {String} Request example: + * id: "0972569c-2d3e-444d-8e7d-2054e7ab20e9" + * + * @param Request $request + * @return \Illuminate\Http\Response + */ + public function updateAll(UpdateAllNotifications $request) + { + $userId = $request->input('user_id'); + $notifications = DatabaseNotification::where('notifiable_id', '=', $userId)->whereNull('read_at')->get(); + $notifications->map(function ($n) { + $n->markAsRead(); + }); + } + /** * Delete a read notification. * From c8061d3b0a0227f74230e583146ee5c58edaecf1 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 12:22:16 +0200 Subject: [PATCH 05/18] Return user id to notification index view --- .../Controllers/Views/Notifications/NotificationsController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Views/Notifications/NotificationsController.php b/app/Http/Controllers/Views/Notifications/NotificationsController.php index fe9e9c541..d12c3d7b0 100644 --- a/app/Http/Controllers/Views/Notifications/NotificationsController.php +++ b/app/Http/Controllers/Views/Notifications/NotificationsController.php @@ -28,6 +28,7 @@ public function index(Request $request, Guard $auth) return view('notifications.index', [ 'all' => $all, 'notifications' => $notifications, + 'user_id' => $user->id, ]); } } From b68db34c1600d008bc94ba6dfa6c96b610433ae9 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 12:23:03 +0200 Subject: [PATCH 06/18] Update test --- .../Api/NotificationControllerTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/php/Http/Controllers/Api/NotificationControllerTest.php b/tests/php/Http/Controllers/Api/NotificationControllerTest.php index babedae0d..741f888de 100644 --- a/tests/php/Http/Controllers/Api/NotificationControllerTest.php +++ b/tests/php/Http/Controllers/Api/NotificationControllerTest.php @@ -47,4 +47,27 @@ public function testDestroy() ->assertStatus(200); $this->assertEquals(0, $user->notifications()->count()); } + + public function testUpdateAll(){ + $user = UserTest::create(); + $user->notify(new InAppNotification('test', 'test')); + $user->notify(new InAppNotification('test', 'test')); + $user->notify(new InAppNotification('test', 'test')); + + $this->doTestApiRoute('PUT', '/api/v1/notifications', ['user_id' => $user->id]); + $this->assertEquals(3, $user->unreadNotifications()->count()); + + $this->be(UserTest::create()); + $this->put('/api/v1/notifications/', ['user_id' => $user->id]) + ->assertForbidden(); + + $this->be($user); + $this->put('/api/v1/notifications/', ['user_id' => $user->id]) + ->assertStatus(200); + $this->assertEquals(0, $user->unreadNotifications()->count()); + + // invalid data + $this->put('/api/v1/notifications/', ['test'])->assertInvalid(); + $this->put('/api/v1/notifications/', ['user_id' => 'test'])->assertInvalid(); + } } From dfa97ae3b5f54e20289055402715ea80bae92e14 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 12:42:11 +0200 Subject: [PATCH 07/18] Fix lint error --- app/Http/Controllers/Api/NotificationController.php | 2 +- tests/php/Http/Controllers/Api/NotificationControllerTest.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 0417e77a2..f340d5e00 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -2,8 +2,8 @@ namespace Biigle\Http\Controllers\Api; -use Illuminate\Http\Request; use Biigle\Http\Requests\UpdateAllNotifications; +use Illuminate\Http\Request; use Illuminate\Notifications\DatabaseNotification; class NotificationController extends Controller diff --git a/tests/php/Http/Controllers/Api/NotificationControllerTest.php b/tests/php/Http/Controllers/Api/NotificationControllerTest.php index 741f888de..e111c1570 100644 --- a/tests/php/Http/Controllers/Api/NotificationControllerTest.php +++ b/tests/php/Http/Controllers/Api/NotificationControllerTest.php @@ -48,7 +48,8 @@ public function testDestroy() $this->assertEquals(0, $user->notifications()->count()); } - public function testUpdateAll(){ + public function testUpdateAll() + { $user = UserTest::create(); $user->notify(new InAppNotification('test', 'test')); $user->notify(new InAppNotification('test', 'test')); From ecba17b22151b632d996f030ae7393e25d8b33d2 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Thu, 6 Jun 2024 13:04:06 +0200 Subject: [PATCH 08/18] Format code --- resources/assets/js/core/api/notifications.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/resources/assets/js/core/api/notifications.js b/resources/assets/js/core/api/notifications.js index 2f046c6ea..8ace67982 100644 --- a/resources/assets/js/core/api/notifications.js +++ b/resources/assets/js/core/api/notifications.js @@ -14,11 +14,7 @@ * @type {Vue.resource} */ export default Vue.resource('api/v1/notifications{/id}', {}, { - markRead: { - method: 'PUT' - }, - markReadAll:{ - method: 'PUT', - } + markRead: {method: 'PUT'}, + markReadAll: {method: 'PUT'} }); From 14d59b8d44fe908477eb2a61e833d83de295e2ae Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 08:23:35 +0200 Subject: [PATCH 09/18] Simplify controller --- app/Http/Controllers/Api/NotificationController.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index f340d5e00..740585388 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -2,9 +2,7 @@ namespace Biigle\Http\Controllers\Api; -use Biigle\Http\Requests\UpdateAllNotifications; use Illuminate\Http\Request; -use Illuminate\Notifications\DatabaseNotification; class NotificationController extends Controller { @@ -33,7 +31,7 @@ public function update(Request $request, $id) /** * Mark all notification as read. * - * @api {put} notifications/ Mark all notifications as read + * @api {put} notifications/all Mark all notifications as read * @apiGroup Notifications * @apiName UpdateReadNotifications * @apiPermission user @@ -42,15 +40,10 @@ public function update(Request $request, $id) * id: "0972569c-2d3e-444d-8e7d-2054e7ab20e9" * * @param Request $request - * @return \Illuminate\Http\Response */ - public function updateAll(UpdateAllNotifications $request) + public function updateAll(Request $request) { - $userId = $request->input('user_id'); - $notifications = DatabaseNotification::where('notifiable_id', '=', $userId)->whereNull('read_at')->get(); - $notifications->map(function ($n) { - $n->markAsRead(); - }); + $request->user()->unreadNotifications()->eachById(fn ($n) => $n->markAsRead()); } /** From 437c4157ed1d645cfb3016a34e60bcd6f25a29f6 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 08:27:23 +0200 Subject: [PATCH 10/18] Remove unused user id --- .../Views/Notifications/NotificationsController.php | 1 - resources/assets/js/core/notifications/list.vue | 4 ++-- resources/views/notifications/index.blade.php | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Views/Notifications/NotificationsController.php b/app/Http/Controllers/Views/Notifications/NotificationsController.php index d12c3d7b0..fe9e9c541 100644 --- a/app/Http/Controllers/Views/Notifications/NotificationsController.php +++ b/app/Http/Controllers/Views/Notifications/NotificationsController.php @@ -28,7 +28,6 @@ public function index(Request $request, Guard $auth) return view('notifications.index', [ 'all' => $all, 'notifications' => $notifications, - 'user_id' => $user->id, ]); } } diff --git a/resources/assets/js/core/notifications/list.vue b/resources/assets/js/core/notifications/list.vue index fc37c3612..4548f5b83 100644 --- a/resources/assets/js/core/notifications/list.vue +++ b/resources/assets/js/core/notifications/list.vue @@ -74,9 +74,9 @@ export default { }, }, methods:{ - markAllAsRead(userId) { + markAllAsRead() { this.isLoading = true; - return NotificationsApi.markReadAll({}, {user_id: userId}) + return NotificationsApi.markReadAll({}, {}) .then(() => { this.notifications.map(item => { item.read_at = new Date(); diff --git a/resources/views/notifications/index.blade.php b/resources/views/notifications/index.blade.php index 4c6444955..f6b2d99c5 100644 --- a/resources/views/notifications/index.blade.php +++ b/resources/views/notifications/index.blade.php @@ -21,7 +21,7 @@

@if (!$all)

- +

@endif
From fa996cdbfbe73349bfdc809ea4aba19af696dda0 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 08:33:23 +0200 Subject: [PATCH 11/18] Prevent element overflow --- resources/views/notifications/index.blade.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/resources/views/notifications/index.blade.php b/resources/views/notifications/index.blade.php index f6b2d99c5..07396fbf8 100644 --- a/resources/views/notifications/index.blade.php +++ b/resources/views/notifications/index.blade.php @@ -20,11 +20,10 @@
@if (!$all) -

+

@endif -
@@ -42,7 +41,6 @@
-
@if ($all)

You have no notifications. From 6bde1cdf36fe7ca29db8152282c7525467a25097 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 09:36:55 +0200 Subject: [PATCH 12/18] Change route path --- resources/assets/js/core/api/notifications.js | 4 +++- routes/api.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/assets/js/core/api/notifications.js b/resources/assets/js/core/api/notifications.js index 8ace67982..f4a89c12f 100644 --- a/resources/assets/js/core/api/notifications.js +++ b/resources/assets/js/core/api/notifications.js @@ -15,6 +15,8 @@ */ export default Vue.resource('api/v1/notifications{/id}', {}, { markRead: {method: 'PUT'}, - markReadAll: {method: 'PUT'} + markReadAll: { + method: 'PUT', + url: 'api/v1/notifications/all'} }); diff --git a/routes/api.php b/routes/api.php index 89bfa6ffd..1c4997bc0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -143,12 +143,12 @@ 'parameters' => ['media-types' => 'id'], ]); +$router->put('notifications/all', 'NotificationController@updateAll'); + $router->resource('notifications', 'NotificationController', [ 'only' => ['update', 'destroy'], ]); -$router->put('notifications', 'NotificationController@updateAll'); - $router->resource('projects', 'ProjectController', [ 'only' => ['index', 'show', 'update', 'store', 'destroy'], 'parameters' => ['projects' => 'id'], From 4be4cc37d314db09ae872a23475441ac667867aa Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 09:46:10 +0200 Subject: [PATCH 13/18] Disable button on loading --- resources/views/notifications/index.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/notifications/index.blade.php b/resources/views/notifications/index.blade.php index 07396fbf8..cea6cfacd 100644 --- a/resources/views/notifications/index.blade.php +++ b/resources/views/notifications/index.blade.php @@ -21,7 +21,7 @@

@if (!$all)

- +

@endif From da57655f873667c1b1ba72b684255e4f66b5b547 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Tue, 18 Jun 2024 10:02:19 +0200 Subject: [PATCH 14/18] Update test --- .../Api/NotificationControllerTest.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/php/Http/Controllers/Api/NotificationControllerTest.php b/tests/php/Http/Controllers/Api/NotificationControllerTest.php index e111c1570..e8310f3c0 100644 --- a/tests/php/Http/Controllers/Api/NotificationControllerTest.php +++ b/tests/php/Http/Controllers/Api/NotificationControllerTest.php @@ -55,20 +55,11 @@ public function testUpdateAll() $user->notify(new InAppNotification('test', 'test')); $user->notify(new InAppNotification('test', 'test')); - $this->doTestApiRoute('PUT', '/api/v1/notifications', ['user_id' => $user->id]); - $this->assertEquals(3, $user->unreadNotifications()->count()); + $this->doTestApiRoute('PUT', '/api/v1/notifications/all'); - $this->be(UserTest::create()); - $this->put('/api/v1/notifications/', ['user_id' => $user->id]) - ->assertForbidden(); - $this->be($user); - $this->put('/api/v1/notifications/', ['user_id' => $user->id]) - ->assertStatus(200); + $this->assertEquals(3, $user->unreadNotifications()->count()); + $this->put('/api/v1/notifications/all')->assertSuccessful(); $this->assertEquals(0, $user->unreadNotifications()->count()); - - // invalid data - $this->put('/api/v1/notifications/', ['test'])->assertInvalid(); - $this->put('/api/v1/notifications/', ['user_id' => 'test'])->assertInvalid(); } } From 55c0d14f43aed21f13ecdb97f27bb8fd0dddf5c4 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 19 Jun 2024 07:37:57 +0200 Subject: [PATCH 15/18] Add missing data property --- resources/assets/js/core/notifications/list.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/assets/js/core/notifications/list.vue b/resources/assets/js/core/notifications/list.vue index 4548f5b83..a86e693e8 100644 --- a/resources/assets/js/core/notifications/list.vue +++ b/resources/assets/js/core/notifications/list.vue @@ -63,6 +63,7 @@ export default { data() { return { notifications: [], + isLoading: false, }; }, computed: { From 8c59dd0ed89b302e849c08681d7348e1a975f596 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 19 Jun 2024 07:38:47 +0200 Subject: [PATCH 16/18] Remove unused request form validation --- app/Http/Requests/UpdateAllNotifications.php | 34 -------------------- 1 file changed, 34 deletions(-) delete mode 100644 app/Http/Requests/UpdateAllNotifications.php diff --git a/app/Http/Requests/UpdateAllNotifications.php b/app/Http/Requests/UpdateAllNotifications.php deleted file mode 100644 index c7cd5ee7a..000000000 --- a/app/Http/Requests/UpdateAllNotifications.php +++ /dev/null @@ -1,34 +0,0 @@ -input('user_id')) || !is_numeric($this->input('user_id'))) { - // Skip authorization if the user id could not be found. The validation rules - // will take care of rejecting this request with the proper response code. - return true; - } - - return $this->user()->id === $this->input('user_id'); - } - - /** - * Get the validation rules that apply to the request. - * - * @return array|string> - */ - public function rules(): array - { - return [ - 'user_id' => 'required|numeric' - ]; - } -} From cd0281b3058369155f0d0ead6bff2f019928afc5 Mon Sep 17 00:00:00 2001 From: Martin Zurowietz Date: Wed, 19 Jun 2024 16:22:51 +0200 Subject: [PATCH 17/18] Update app/Http/Controllers/Api/NotificationController.php --- app/Http/Controllers/Api/NotificationController.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 740585388..f2ec45f7a 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -36,9 +36,6 @@ public function update(Request $request, $id) * @apiName UpdateReadNotifications * @apiPermission user * - * @apiParamExample {String} Request example: - * id: "0972569c-2d3e-444d-8e7d-2054e7ab20e9" - * * @param Request $request */ public function updateAll(Request $request) From 39de4ee32f2d3e871f75730ab3fe16cc86d1c54c Mon Sep 17 00:00:00 2001 From: Martin Zurowietz Date: Wed, 19 Jun 2024 16:27:40 +0200 Subject: [PATCH 18/18] Fix removal of notification --- resources/assets/js/core/notifications/list.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/assets/js/core/notifications/list.vue b/resources/assets/js/core/notifications/list.vue index a86e693e8..51b749b44 100644 --- a/resources/assets/js/core/notifications/list.vue +++ b/resources/assets/js/core/notifications/list.vue @@ -81,10 +81,8 @@ export default { .then(() => { this.notifications.map(item => { item.read_at = new Date(); - if (this.removeItem) { - Store.remove(this.item.id); - } - }) + Store.remove(item.id); + }); }) .catch(Messages.handleErrorResponse) .finally(() => {