diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index cbb6277c82006d36ec22e188865374b8d085ecee..f5804796033bc287e14d852c998fbb47a15a6925 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,11 @@ Fixed
 
 * Progress page didn't work properly.
 * About page failed to load for apps with an unknown licence.
+* Partial permission checking on the person query was fixed.
+* Some pages couldn't be scrolled when a task progress popup was open.
+* Notification query failed on admin users without persons.
+* Querying for notification caused unnecessary database requests.
+* Loading bar didn't disappear on some pages after loading was finished.
 * Support newer versions of django-oauth-toolkit.
 
 `3.1`_ - 2022-05-30
diff --git a/aleksis/core/frontend/components/LegacyBaseTemplate.vue b/aleksis/core/frontend/components/LegacyBaseTemplate.vue
index 790fc10c592bac5acc1e3bbadabcae63e065804f..0105952fd08792c2cb4a472465d435a1f94a0eb3 100644
--- a/aleksis/core/frontend/components/LegacyBaseTemplate.vue
+++ b/aleksis/core/frontend/components/LegacyBaseTemplate.vue
@@ -71,7 +71,9 @@ export default {
 
       // Show loader if iframe starts to change its content, even if the $route stays the same
       this.$refs.contentIFrame.contentWindow.onpagehide = () => {
-        this.$root.contentLoading = true;
+        if (this.$root.isLegacyBaseTemplate) {
+          this.$root.contentLoading = true;
+        }
       };
 
       // Write title of iframe to SPA window
diff --git a/aleksis/core/frontend/components/celery_progress/CeleryProgressBottom.vue b/aleksis/core/frontend/components/celery_progress/CeleryProgressBottom.vue
index 912fb779241ef577c6f900abc78a26008df008f6..1866c3d819ace7f6d329926f6dbe7bdc3b9b0276 100644
--- a/aleksis/core/frontend/components/celery_progress/CeleryProgressBottom.vue
+++ b/aleksis/core/frontend/components/celery_progress/CeleryProgressBottom.vue
@@ -1,5 +1,11 @@
 <template>
-  <v-bottom-sheet :value="show" persistent hide-overlay max-width="400px">
+  <v-bottom-sheet
+    :value="show"
+    persistent
+    hide-overlay
+    max-width="400px"
+    ref="sheet"
+  >
     <v-expansion-panels accordion v-model="open">
       <v-expansion-panel>
         <v-expansion-panel-header color="primary" class="white--text px-4">
@@ -33,6 +39,13 @@ export default {
   data() {
     return { open: 0 };
   },
+  mounted() {
+    // Vuetify uses the hideScroll method to disable scrolling by setting an event listener
+    // to the window. As event listeners can only be removed by referencing the listener
+    // method and because vuetify this method is called on every state change of the dialog,
+    // we simply replace the method in this component instance
+    this.$refs.sheet.hideScroll = this.$refs.sheet.showScroll;
+  },
   computed: {
     show() {
       return this.celeryProgressByUser && this.celeryProgressByUser.length > 0;
diff --git a/aleksis/core/frontend/components/notifications/NotificationList.vue b/aleksis/core/frontend/components/notifications/NotificationList.vue
index 1c51c00661816fe3e244e6d511a0e70c747dbca6..08914210eefc7ecd2f52ea24342abf1d1467e5c9 100644
--- a/aleksis/core/frontend/components/notifications/NotificationList.vue
+++ b/aleksis/core/frontend/components/notifications/NotificationList.vue
@@ -20,7 +20,7 @@
           v-if="
             myNotifications &&
             myNotifications.person &&
-            myNotifications.person.unreadNotificationsCount > 0
+            myNotifications.person.notifications.length > 0
           "
         >
           mdi-bell-badge-outline
@@ -38,7 +38,7 @@
         v-if="
           myNotifications.person &&
           myNotifications.person.notifications &&
-          myNotifications.person.notifications.length
+          unreadNotifications.length
         "
       >
         <v-subheader>{{ $t("notifications.notifications") }}</v-subheader>
@@ -86,5 +86,10 @@ export default {
       pollInterval: 30000,
     },
   },
+  computed: {
+    unreadNotifications() {
+      return this.myNotifications.filter(n => !n.read);
+    },
+  },
 };
 </script>
diff --git a/aleksis/core/frontend/components/notifications/myNotifications.graphql b/aleksis/core/frontend/components/notifications/myNotifications.graphql
index b8287ea2f50664f556d82bdb58e4b508c7ece1d4..89e91562086607e6c9e7649fa1295d234d189bd3 100644
--- a/aleksis/core/frontend/components/notifications/myNotifications.graphql
+++ b/aleksis/core/frontend/components/notifications/myNotifications.graphql
@@ -1,7 +1,6 @@
 {
   myNotifications: whoAmI {
     person {
-      unreadNotificationsCount
       notifications {
         id
         title
diff --git a/aleksis/core/schema/person.py b/aleksis/core/schema/person.py
index 6eed201487348034b2d9b1cba616046b1794dbf2..90165cceb0fb33676e17aad5caf978ce7c124be5 100644
--- a/aleksis/core/schema/person.py
+++ b/aleksis/core/schema/person.py
@@ -55,14 +55,26 @@ class PersonType(DjangoObjectType):
     full_name = graphene.String()
     username = graphene.String()
     userid = graphene.ID()
-    photo = graphene.Field(FieldFileType)
-    avatar = graphene.Field(FieldFileType)
+    photo = graphene.Field(FieldFileType, required=False)
+    avatar = graphene.Field(FieldFileType, required=False)
     avatar_url = graphene.String()
     avatar_content_url = graphene.String()
-    secondary_image_url = graphene.String()
+    secondary_image_url = graphene.String(required=False)
+
+    street = graphene.String(required=False)
+    housenumber = graphene.String(required=False)
+    postal_code = graphene.String(required=False)
+    place = graphene.String(required=False)
+
+    phone_number = graphene.String(required=False)
+    mobile_number = graphene.String(required=False)
+    email = graphene.String(required=False)
+
+    date_of_birth = graphene.String(required=False)
+    place_of_birth = graphene.String(required=False)
 
     notifications = graphene.List(NotificationType)
-    unread_notifications_count = graphene.Int()
+    unread_notifications_count = graphene.Int(required=False)
 
     is_dummy = graphene.Boolean()
     preferences = graphene.Field(PersonPreferencesType)
@@ -150,7 +162,11 @@ class PersonType(DjangoObjectType):
         return root.user.id if root.user else None
 
     def resolve_unread_notifications_count(root, info, **kwargs):  # noqa
-        return root.unread_notifications_count
+        if root.pk and has_person(info.context) and root == info.context.user.person:
+            return root.unread_notifications_count
+        elif root.pk:
+            return 0
+        return None
 
     def resolve_photo(root, info, **kwargs):
         if info.context.user.has_perm("core.view_photo_rule", root):
@@ -199,11 +215,11 @@ class PersonType(DjangoObjectType):
         return root.is_dummy if hasattr(root, "is_dummy") else False
 
     def resolve_notifications(root: Person, info, **kwargs):
-        if has_person(info.context.user) and info.context.user.person == root:
+        if root.pk and has_person(info.context) and root == info.context.user.person:
             return root.notifications.filter(send_at__lte=timezone.now()).order_by(
                 "read", "-created"
             )
-        raise PermissionDenied()
+        return []
 
     def resolve_can_edit_person(root, info, **kwargs):  # noqa
         return info.context.user.has_perm("core.edit_person_rule", root)