fix(notifications): sync badges on api recovery

Updates the notification sidebar to properly refresh notification counts (badges) when the API connection is restored or when the user manually retries.

Changes:
- Emit `refetched` event from `NotificationsList` when the query successfully returns data.
- Trigger `recalculateOverview` and `refetch` in `Sidebar` when the list is refreshed or when the API status becomes 'online'.
- Fixes an issue where notification badges would remain at 0 after an API outage, even though the notification list had populated correctly.
This commit is contained in:
Ajit Mehrotra
2025-12-15 18:17:30 -05:00
parent e817d6a317
commit 4abc79a7b5
2 changed files with 31 additions and 4 deletions
+9 -2
View File
@@ -45,6 +45,10 @@ const props = withDefaults(
}
);
const emit = defineEmits<{
(e: 'refetched'): void;
}>();
/** whether we should continue trying to load more notifications */
const canLoadMore = ref(true);
/** reset custom state when props (e.g. props.type filter) change*/
@@ -68,8 +72,11 @@ const { result, error, loading, fetchMore, refetch, subscribeToMore, onResult }
);
onResult((res) => {
if (res.data && unraidApiStore.unraidApiStatus === 'offline') {
unraidApiStore.unraidApiStatus = 'online';
if (res.data) {
emit('refetched');
if (unraidApiStore.unraidApiStatus === 'offline') {
unraidApiStore.unraidApiStatus = 'online';
}
}
});
+22 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMutation, useQuery, useSubscription } from '@vue/apollo-composable';
@@ -25,9 +25,11 @@ import { useFragment } from '~/composables/gql';
import { NotificationImportance as Importance, NotificationType } from '~/composables/gql/graphql';
import { useConfirm } from '~/composables/useConfirm';
import { useThemeStore } from '~/store/theme';
import { useUnraidApiStore } from '~/store/unraidApi';
const toast = useToast();
const themeStore = useThemeStore();
const unraidApiStore = useUnraidApiStore();
const { mutate: archiveAll, loading: loadingArchiveAll } = useMutation(archiveAllNotifications);
const { mutate: deleteArchives, loading: loadingDeleteAll } = useMutation(deleteArchivedNotifications);
@@ -75,7 +77,7 @@ const confirmAndDeleteArchives = async () => {
}
};
const { result, subscribeToMore } = useQuery(notificationsOverview);
const { result, subscribeToMore, refetch } = useQuery(notificationsOverview);
subscribeToMore({
document: notificationOverviewSubscription,
updateQuery: (prev, { subscriptionData }) => {
@@ -84,6 +86,22 @@ subscribeToMore({
return snapshot;
},
});
const handleRefetch = () => {
void recalculateOverview().finally(() => {
void refetch();
});
};
watch(
() => unraidApiStore.unraidApiStatus,
(status) => {
if (status === 'online') {
handleRefetch();
}
}
);
const { latestNotificationTimestamp, haveSeenNotifications } = useTrackLatestSeenNotification();
const { onResult: onNotificationAdded } = useSubscription(notificationAddedSubscription);
@@ -238,12 +256,14 @@ const tabs = computed(() => [
:importance="importance"
:type="NotificationType.UNREAD"
class="flex-1"
@refetched="handleRefetch"
/>
<NotificationsList
v-else
:importance="importance"
:type="NotificationType.ARCHIVE"
class="flex-1"
@refetched="handleRefetch"
/>
</div>
</div>