diff --git a/aleksis/core/schema.py b/aleksis/core/schema.py index a29ef5ee222ed2ad15a2d28da939d9d7752a0bb0..8841d02d3a446cb99ec3a9c4f147e87dd58ae24e 100644 --- a/aleksis/core/schema.py +++ b/aleksis/core/schema.py @@ -34,6 +34,22 @@ class PersonMutation(DjangoModelFormMutation): form_class = PersonForm +class MarkNotificationReadMutation(graphene.Mutation): + class Arguments: + id = graphene.ID() + + notification = graphene.Field(NotificationType) + + @classmethod + def mutate(cls, root, info, id): + notification = Notification.objects.get(pk=id) + # FIXME permissions + notification.read = True + notification.save() + + return notification + + class Query(graphene.ObjectType): ping = graphene.String(default_value="pong") @@ -64,6 +80,7 @@ class Query(graphene.ObjectType): class Mutation(graphene.ObjectType): update_person = PersonMutation.Field() + mark_notification_read = MarkNotificationReadMutation.Field() def build_global_schema(): """Build global GraphQL schema from all apps.""" diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py index d0243c205c84c61802be00d98594a4966715e190..54e854c8117843e8bd4f5139280bd4c46318a95c 100644 --- a/aleksis/core/urls.py +++ b/aleksis/core/urls.py @@ -97,11 +97,6 @@ urlpatterns = [ path("group/<int:id_>/delete", views.delete_group, name="delete_group_by_id"), path("", views.index, name="index"), path("dashboard/edit/", views.EditDashboardView.as_view(), name="edit_dashboard"), - path( - "notifications/mark-read/<int:id_>", - views.notification_mark_read, - name="notification_mark_read", - ), path("groups/group_type/create", views.edit_group_type, name="create_group_type"), path( "groups/group_type/<int:id_>/delete", diff --git a/aleksis/core/views.py b/aleksis/core/views.py index 8e2d5ef3327f41f50f042bc5965e50244f75b991..df8469036d2e4330f66e92455f4a21156c4d84ca 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -539,20 +539,6 @@ def vue_dummy(request: HttpRequest) -> HttpResponse: # FIXME remove together with URL route and template return render(request, "core/vue_dummy.html", {}) -@permission_required( - "core.mark_notification_as_read_rule", fn=objectgetter_optional(Notification, None, False) -) -def notification_mark_read(request: HttpRequest, id_: int) -> HttpResponse: - """Mark a notification read.""" - notification = objectgetter_optional(Notification, None, False)(request, id_) - - notification.read = True - notification.save() - - # Redirect to dashboard as this is only used from there if JavaScript is unavailable - return redirect("index") - - @permission_required("core.view_announcements_rule") def announcements(request: HttpRequest) -> HttpResponse: """List view of announcements.""" diff --git a/assets/components/notifications/NotificationItem.vue b/assets/components/notifications/NotificationItem.vue index 01e52aa9b4e41194015d242d3b5ea11f0ab60b3f..dea29654a5ddf833ec3433c3f63d4a5d8b0c714d 100644 --- a/assets/components/notifications/NotificationItem.vue +++ b/assets/components/notifications/NotificationItem.vue @@ -1,28 +1,46 @@ <template> - <v-list-item> - <v-list-item-content> - <v-list-item-title>{{ notification.title }}</v-list-item-title> + <ApolloMutation + :mutation="gql => gql` + mutation ($id: ID!) { + markNotificationRead(id: $id) { + notification { + id + read + } + } + } + `" + :variables="{ id: this.notification.id }" + > + <template v-slot="{ mutate, loading, error }"> + <v-list-item + v-intersect="mutate" + > + <v-list-item-content> + <v-list-item-title>{{ notification.title }}</v-list-item-title> - <v-list-item-subtitle> - <v-icon>mdi-clock-outline</v-icon> - {{ notification.created }} - </v-list-item-subtitle> + <v-list-item-subtitle> + <v-icon>mdi-clock-outline</v-icon> + {{ notification.created }} + </v-list-item-subtitle> - <v-list-item-subtitle> - {{ notification.description }} - </v-list-item-subtitle> - </v-list-item-content> + <v-list-item-subtitle> + {{ notification.description }} + </v-list-item-subtitle> + </v-list-item-content> - <v-list-item-action v-if="notification.link"> - <v-btn text :href="notification.link"> - {{ this.$root.django.gettext('More information →') }} - </v-btn> - </v-list-item-action> + <v-list-item-action v-if="notification.link"> + <v-btn text :href="notification.link"> + {{ this.$root.django.gettext('More information →') }} + </v-btn> + </v-list-item-action> - <v-list-item-icon> - <v-chip color="primary">{{ notification.sender }}</v-chip> - </v-list-item-icon> - </v-list-item> + <v-list-item-icon> + <v-chip color="primary">{{ notification.sender }}</v-chip> + </v-list-item-icon> + </v-list-item> + </template> + </ApolloMutation> </template> <script>