Skip to content

Commit

Permalink
fix(client): remove unshared tag from cached notes
Browse files Browse the repository at this point in the history
- rename `removeNoteFromCache` to `removeEntityFromCache`
  • Loading branch information
neopostmodern committed May 6, 2023
1 parent b549b1f commit 87df758
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 7 deletions.
4 changes: 2 additions & 2 deletions client/src/renderer/components/TagWithContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '../generated/graphql';
import { hasPermission } from '../hooks/useHasPermission';
import useUserId from '../hooks/useUserId';
import { removeNoteFromCache } from '../utils/cache';
import { removeEntityFromCache } from '../utils/cache';
import { DisplayOnlyTag } from '../utils/types';
import ErrorSnackbar from './ErrorSnackbar';
import Tag from './Tag';
Expand Down Expand Up @@ -47,7 +47,7 @@ const TagWithContextMenu = ({
}

if (!hasPermission(userId, data.removeTagByIdFromNote, 'notes', 'read')) {
removeNoteFromCache(cache, data.removeTagByIdFromNote);
removeEntityFromCache(cache, data.removeTagByIdFromNote);
if (location.href.includes(data.removeTagByIdFromNote._id)) {
dispatch(goBack());
}
Expand Down
47 changes: 47 additions & 0 deletions client/src/renderer/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,13 @@ export type UpdatedNotesCacheQueryQueryVariables = Exact<{ [key: string]: never;

export type UpdatedNotesCacheQueryQuery = { __typename: 'Query', notes: Array<{ __typename: 'Link', _id: string, name: string, createdAt: any, updatedAt: any, archivedAt?: any | null, deletedAt?: any | null, description: string, url: string, domain: string, tags: Array<{ __typename: 'Tag', _id: string }>, user: { __typename: 'User', _id: string, name: string } } | { __typename: 'Text', _id: string, name: string, createdAt: any, updatedAt: any, archivedAt?: any | null, deletedAt?: any | null, description: string, tags: Array<{ __typename: 'Tag', _id: string }>, user: { __typename: 'User', _id: string, name: string } }> };

export type TagWithNoteIdsQueryVariables = Exact<{
tagId: Scalars['ID'];
}>;


export type TagWithNoteIdsQuery = { __typename: 'Query', tag: { __typename: 'Tag', _id: string, notes?: Array<{ __typename: 'Link', _id: string } | { __typename: 'Text', _id: string } | null> | null } };

export type ToggleArchivedNoteMutationVariables = Exact<{
noteId: Scalars['ID'];
}>;
Expand Down Expand Up @@ -1711,6 +1718,46 @@ export function useUpdatedNotesCacheQueryLazyQuery(baseOptions?: Apollo.LazyQuer
export type UpdatedNotesCacheQueryQueryHookResult = ReturnType<typeof useUpdatedNotesCacheQueryQuery>;
export type UpdatedNotesCacheQueryLazyQueryHookResult = ReturnType<typeof useUpdatedNotesCacheQueryLazyQuery>;
export type UpdatedNotesCacheQueryQueryResult = Apollo.QueryResult<UpdatedNotesCacheQueryQuery, UpdatedNotesCacheQueryQueryVariables>;
export const TagWithNoteIdsDocument = gql`
query TagWithNoteIds($tagId: ID!) {
tag(tagId: $tagId) {
_id
notes {
... on INote {
_id
}
}
}
}
`;

/**
* __useTagWithNoteIdsQuery__
*
* To run a query within a React component, call `useTagWithNoteIdsQuery` and pass it any options that fit your needs.
* When your component renders, `useTagWithNoteIdsQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useTagWithNoteIdsQuery({
* variables: {
* tagId: // value for 'tagId'
* },
* });
*/
export function useTagWithNoteIdsQuery(baseOptions: Apollo.QueryHookOptions<TagWithNoteIdsQuery, TagWithNoteIdsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<TagWithNoteIdsQuery, TagWithNoteIdsQueryVariables>(TagWithNoteIdsDocument, options);
}
export function useTagWithNoteIdsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<TagWithNoteIdsQuery, TagWithNoteIdsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<TagWithNoteIdsQuery, TagWithNoteIdsQueryVariables>(TagWithNoteIdsDocument, options);
}
export type TagWithNoteIdsQueryHookResult = ReturnType<typeof useTagWithNoteIdsQuery>;
export type TagWithNoteIdsLazyQueryHookResult = ReturnType<typeof useTagWithNoteIdsLazyQuery>;
export type TagWithNoteIdsQueryResult = Apollo.QueryResult<TagWithNoteIdsQuery, TagWithNoteIdsQueryVariables>;
export const ToggleArchivedNoteDocument = gql`
mutation ToggleArchivedNote($noteId: ID!) {
toggleArchivedNote(noteId: $noteId) {
Expand Down
4 changes: 2 additions & 2 deletions client/src/renderer/hooks/useDeleteNote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ToggleDeletedNoteMutation,
ToggleDeletedNoteMutationVariables,
} from '../generated/graphql';
import { removeNoteFromCache } from '../utils/cache';
import { removeEntityFromCache } from '../utils/cache';

const TOGGLE_DELETED_NOTE_MUTATION = gql`
mutation ToggleDeletedNote($noteId: ID!) {
Expand Down Expand Up @@ -36,7 +36,7 @@ const useDeleteNote = (note: { _id: string }) => {
throw Error("[useDeletedLink.update] Can't handle un-delete yet.");
}

removeNoteFromCache(cache, data.toggleDeletedNote);
removeEntityFromCache(cache, data.toggleDeletedNote);
},
});

Expand Down
40 changes: 40 additions & 0 deletions client/src/renderer/hooks/useEntitiesUpdatedSince.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
EntitiesUpdatedSinceQueryVariables,
NotesForListQuery,
TagsQuery,
TagWithNoteIdsQuery,
TagWithNoteIdsQueryVariables,
} from '../generated/graphql';
import { removeEntityFromCache } from '../utils/cache';
import {
BASE_NOTE_FRAGMENT,
BASE_TAG_FRAGMENT,
Expand Down Expand Up @@ -173,6 +176,43 @@ const useEntitiesUpdatedSince = () => {
});

if (entitiesUpdatedSince.removedTagIds.length) {
entitiesUpdatedSince.removedTagIds.forEach((tagId) => {
const tagQuery = cache.readQuery<
TagWithNoteIdsQuery,
TagWithNoteIdsQueryVariables
>({
query: gql`
query TagWithNoteIds($tagId: ID!) {
tag(tagId: $tagId) {
_id
notes {
... on INote {
_id
}
}
}
}
`,
variables: { tagId },
});
if (!tagQuery?.tag) {
return;
}
const { tag } = tagQuery;
tag.notes?.forEach((note) => {
cache.modify({
id: cache.identify(note!),
fields: {
tags(currentTagsOnNote: Array<{ __ref: string }> = []) {
return currentTagsOnNote.filter(
({ __ref }) => __ref.split(':')[1] !== tagId
);
},
},
});
});
removeEntityFromCache(cache, tag);
});
cachedTags = cachedTags.filter(
({ _id }) => !entitiesUpdatedSince.removedTagIds.includes(_id)
);
Expand Down
6 changes: 3 additions & 3 deletions client/src/renderer/utils/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export const clearApolloCache = () => {
cachePersistor.purge();
};

export const removeNoteFromCache = (
export const removeEntityFromCache = (
cache: ApolloCache<any>,
note: { _id: string; __typename: string }
entity: { _id: string; __typename: string }
): void => {
const normalizedId = cache.identify(note);
const normalizedId = cache.identify(entity);
cache.evict({ id: normalizedId });
cache.gc(); // https://stackoverflow.com/questions/63192774/apollo-client-delete-item-from-cache#comment121727251_66713628
return;
Expand Down

0 comments on commit 87df758

Please sign in to comment.