mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
fix(web): edge case where archived notifications don't appear
if the archive has already been fetched/loaded.
This commit is contained in:
committed by
Pujit Mehrotra
parent
bc4708f405
commit
e40a9ebecd
@@ -1,6 +1,10 @@
|
|||||||
import { InMemoryCache, type InMemoryCacheConfig } from '@apollo/client/core/index.js';
|
import { InMemoryCache, type InMemoryCacheConfig } from '@apollo/client/core/index.js';
|
||||||
import type { NotificationOverview } from '~/composables/gql/graphql';
|
import {
|
||||||
import { NotificationType } from '../../composables/gql/typename';
|
getNotifications,
|
||||||
|
NOTIFICATION_FRAGMENT,
|
||||||
|
} from '~/components/Notifications/graphql/notification.query';
|
||||||
|
import { NotificationType, type NotificationOverview } from '~/composables/gql/graphql';
|
||||||
|
import { NotificationType as NotificationCacheType } from '../../composables/gql/typename';
|
||||||
import { mergeAndDedup } from './merge';
|
import { mergeAndDedup } from './merge';
|
||||||
|
|
||||||
/**------------------------------------------------------------------------
|
/**------------------------------------------------------------------------
|
||||||
@@ -60,9 +64,9 @@ const defaultCacheConfig: InMemoryCacheConfig = {
|
|||||||
overview: {
|
overview: {
|
||||||
/**
|
/**
|
||||||
* Busts notification cache when new unread notifications are detected.
|
* Busts notification cache when new unread notifications are detected.
|
||||||
*
|
*
|
||||||
* This allows incoming notifications to appear in the sidebar without reloading the page.
|
* This allows incoming notifications to appear in the sidebar without reloading the page.
|
||||||
*
|
*
|
||||||
* @param existing - Existing overview data in cache
|
* @param existing - Existing overview data in cache
|
||||||
* @param incoming - New overview data from server
|
* @param incoming - New overview data from server
|
||||||
* @param context - Apollo context containing cache instance
|
* @param context - Apollo context containing cache instance
|
||||||
@@ -106,6 +110,52 @@ const defaultCacheConfig: InMemoryCacheConfig = {
|
|||||||
return incoming; // Return the incoming data so Apollo knows the result of the mutation
|
return incoming; // Return the incoming data so Apollo knows the result of the mutation
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
archiveNotification: {
|
||||||
|
/**
|
||||||
|
* Ensures newly archived notifications appear in the archive list immediately.
|
||||||
|
*
|
||||||
|
* When a notification is archived, we need to manually prepend it to the archive list
|
||||||
|
* in the cache if that list has already been queried. Otherwise, the archived notification
|
||||||
|
* won't appear until the next refetch (usually a page refresh).
|
||||||
|
* Note: the prepended notification may not be in the correct order. This is probably ok.
|
||||||
|
*
|
||||||
|
* This function:
|
||||||
|
* 1. Gets the archived notification's data from the cache using its ID
|
||||||
|
* 2. If the archive list exists in the cache, adds the notification to the beginning of that list
|
||||||
|
* 3. Returns the original mutation result
|
||||||
|
*
|
||||||
|
* @param _ - Existing cache value (unused)
|
||||||
|
* @param incoming - Result (i.e. the archived notification) from the server after archiving
|
||||||
|
* @param cache - Apollo cache instance
|
||||||
|
* @param args - Mutation arguments containing the notification ID
|
||||||
|
* @returns The incoming result to be cached
|
||||||
|
*/
|
||||||
|
merge(_, incoming, { cache, args }) {
|
||||||
|
if (!args?.id) return incoming;
|
||||||
|
const id = cache.identify({ id: args.id, __typename: NotificationCacheType });
|
||||||
|
if (!id) return incoming;
|
||||||
|
|
||||||
|
const notification = cache.readFragment({ id, fragment: NOTIFICATION_FRAGMENT });
|
||||||
|
if (!notification) return incoming;
|
||||||
|
|
||||||
|
cache.updateQuery(
|
||||||
|
{
|
||||||
|
query: getNotifications,
|
||||||
|
// @ts-expect-error the cache only uses the filter type; the limit & offset are superfluous.
|
||||||
|
variables: { filter: { type: NotificationType.Archive } },
|
||||||
|
},
|
||||||
|
(data) => {
|
||||||
|
// no data means the archive hasn't been queried yet, in which case this operation is unnecessary
|
||||||
|
if (!data) return;
|
||||||
|
const updated = structuredClone(data);
|
||||||
|
updated.notifications.list.unshift(notification);
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return incoming;
|
||||||
|
},
|
||||||
|
},
|
||||||
deleteNotification: {
|
deleteNotification: {
|
||||||
/**
|
/**
|
||||||
* Ensures that a deleted notification is removed from the cache +
|
* Ensures that a deleted notification is removed from the cache +
|
||||||
@@ -119,10 +169,7 @@ const defaultCacheConfig: InMemoryCacheConfig = {
|
|||||||
*/
|
*/
|
||||||
merge(_, incoming, { cache, args }) {
|
merge(_, incoming, { cache, args }) {
|
||||||
if (args?.id) {
|
if (args?.id) {
|
||||||
const id = cache.identify({
|
const id = cache.identify({ id: args.id, __typename: NotificationCacheType });
|
||||||
id: args.id,
|
|
||||||
__typename: NotificationType,
|
|
||||||
});
|
|
||||||
cache.evict({ id });
|
cache.evict({ id });
|
||||||
}
|
}
|
||||||
// Removes references to evicted notification, preventing dangling references
|
// Removes references to evicted notification, preventing dangling references
|
||||||
|
|||||||
Reference in New Issue
Block a user