From 72b76b3d207cf16d3d8abe18d80840972bea4b72 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Tue, 15 Nov 2022 16:25:21 +0100 Subject: [PATCH] Improved performance of API alarms endpoint. see #2660 --- frontend/src/api/alarms.js | 4 +- frontend/src/components/alarms/AlarmList.vue | 70 ++++++++++++++++++-- modoboa/admin/api/v2/viewsets.py | 10 ++- modoboa/admin/models/base.py | 2 +- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/frontend/src/api/alarms.js b/frontend/src/api/alarms.js index 62ac76676..aa655bc31 100644 --- a/frontend/src/api/alarms.js +++ b/frontend/src/api/alarms.js @@ -3,7 +3,7 @@ import repository from './repository' const resource = 'alarms' export default { - getAll () { - return repository.get(`${resource}/`) + getAll (params) { + return repository.get(`${resource}/`, { params }) } } diff --git a/frontend/src/components/alarms/AlarmList.vue b/frontend/src/components/alarms/AlarmList.vue index 842c17147..5d956e949 100644 --- a/frontend/src/components/alarms/AlarmList.vue +++ b/frontend/src/components/alarms/AlarmList.vue @@ -27,9 +27,33 @@ :items="alarms" :search="search" item-key="pk" + :options.sync="options" + :server-items-length="totalAlarms" + :loading="loading" class="elevation-1" show-select > + + @@ -45,19 +69,51 @@ export default { return { alarms: [], headers: [ - { text: this.$gettext('Date'), value: 'created' }, - { text: this.$gettext('Domain'), value: 'domain.name' }, - { text: this.$gettext('Mailbox'), value: 'mailbox.name' }, + { text: this.$gettext('Triggered'), value: 'created' }, + { text: this.$gettext('Status'), value: 'status' }, + { text: this.$gettext('Domain'), value: 'domain.name', sortable: false }, + { text: this.$gettext('Mailbox'), value: 'mailbox', sortable: false }, { text: this.$gettext('Message'), value: 'title' } ], + loading: true, + options: {}, search: '', - selected: [] + selected: [], + totalAlarms: 0 + } + }, + methods: { + fetchAlarms () { + const params = { + page: this.options.page + } + if (this.options.sortBy) { + params.ordering = this.options.sortBy.map(item => this.options.sortDesc[0] ? `-${item}` : item).join(',') + } + if (this.search !== '') { + params.search = this.search + } + this.loading = true + alarms.getAll(params).then(resp => { + this.alarms = resp.data.results + this.totalAlarms = resp.data.count + this.loading = false + }) } }, mounted () { - alarms.getAll().then(resp => { - this.alarms = resp.data - }) + this.fetchAlarms() + }, + watch: { + options: { + handler () { + this.fetchAlarms() + }, + deep: true + }, + search () { + this.fetchAlarms() + } } } diff --git a/modoboa/admin/api/v2/viewsets.py b/modoboa/admin/api/v2/viewsets.py index 1c4400488..4b717dda4 100644 --- a/modoboa/admin/api/v2/viewsets.py +++ b/modoboa/admin/api/v2/viewsets.py @@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django_filters import rest_framework as dj_filters from drf_spectacular.utils import extend_schema, extend_schema_view from rest_framework import ( - filters, mixins, parsers, permissions, response, status, viewsets + filters, mixins, parsers, pagination, permissions, response, status, viewsets ) from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied @@ -326,13 +326,17 @@ class UserAccountViewSet(viewsets.ViewSet): class AlarmViewSet(viewsets.ReadOnlyModelViewSet): """Viewset for Alarm.""" + filter_backends = (filters.OrderingFilter, filters.SearchFilter, ) + ordering_fields = ["created", "status", "title"] + pagination_class = pagination.PageNumberPagination permission_classes = ( permissions.IsAuthenticated, ) + search_fields = ["domain__name", "title"] serializer_class = serializers.AlarmSerializer def get_queryset(self): - return models.Alarm.objects.filter( + return models.Alarm.objects.select_related("domain").filter( domain__in=models.Domain.objects.get_for_admin( self.request.user) - ) + ).order_by("-created") diff --git a/modoboa/admin/models/base.py b/modoboa/admin/models/base.py index 5a23f4944..8a1d33742 100644 --- a/modoboa/admin/models/base.py +++ b/modoboa/admin/models/base.py @@ -20,7 +20,7 @@ class AdminObjectManager(models.Manager): """ if admin.is_superuser: return self.get_queryset() - return self.get_queryset().filter(owners__user=admin) + return self.get_queryset().prefetch_related("owners").filter(owners__user=admin) class AdminObject(models.Model):