Skip to content

Commit

Permalink
fix: argument in useDeleteItemLike and refactor to use custom mutatio…
Browse files Browse the repository at this point in the history
…n hook (#284)

fix: type useKeywordSearch hook and enable query when the fields have a value
fix: add invalidation of itemLikeForItem
  • Loading branch information
spaenleh authored Jun 23, 2023
1 parent bbdd666 commit 2623486
Show file tree
Hide file tree
Showing 7 changed files with 2,243 additions and 1,853 deletions.
4 changes: 3 additions & 1 deletion src/api/search.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DiscriminatedItem } from '@graasp/sdk';

import { QueryClientConfig } from '../types';
import configureAxios from './axios';
import { buildGetItemsByKeywordRoute } from './routes';
Expand All @@ -14,7 +16,7 @@ export const getItemsByKeywords = async (
creator?: string;
},
{ API_HOST }: QueryClientConfig,
) =>
): Promise<DiscriminatedItem[]> =>
axios
.get(`${API_HOST}/${buildGetItemsByKeywordRoute(fields)}`)
.then(({ data }) => data);
6 changes: 4 additions & 2 deletions src/hooks/search.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { List } from 'immutable';
import { useQuery } from 'react-query';

import { convertJs } from '@graasp/sdk';
import { ItemRecord } from '@graasp/sdk/frontend';

import * as Api from '../api';
import { buildSearchByKeywordKey } from '../config/keys';
Expand All @@ -14,12 +16,12 @@ export default (queryConfig: QueryClientConfig) => {
useKeywordSearch: (fields: SearchFields) =>
useQuery({
queryKey: buildSearchByKeywordKey(fields),
queryFn: () =>
queryFn: (): Promise<List<ItemRecord>> =>
Api.getItemsByKeywords(fields, queryConfig).then((data) =>
convertJs(data),
),
...defaultQueryOptions,
enabled: Boolean(fields),
enabled: Object.values(fields).some((v) => v),
}),
};
};
11 changes: 6 additions & 5 deletions src/mutations/itemFavorite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ export default (queryConfig: QueryClientConfig) => {
const useAddFavoriteItem = () => {
const queryClient = useQueryClient();
return useMutation(
(itemId: UUID) =>
Api.addFavoriteItem(itemId, queryConfig),
(itemId: UUID) => Api.addFavoriteItem(itemId, queryConfig),
{
onSuccess: () => {
notifier?.({ type: addFavoriteItemRoutine.SUCCESS });
},
onError: (error: Error) => {
notifier?.({ type: addFavoriteItemRoutine.FAILURE, payload: { error } });
notifier?.({
type: addFavoriteItemRoutine.FAILURE,
payload: { error },
});
},
onSettled: () => {
queryClient.invalidateQueries(FAVORITE_ITEMS_KEY);
Expand All @@ -32,8 +34,7 @@ export default (queryConfig: QueryClientConfig) => {
const useRemoveFavoriteItem = () => {
const queryClient = useQueryClient();
return useMutation(
(itemId: UUID) =>
Api.removeFavoriteItem(itemId, queryConfig),
(itemId: UUID) => Api.removeFavoriteItem(itemId, queryConfig),
{
onSuccess: () => {
notifier?.({ type: deleteFavoriteItemRoutine.SUCCESS });
Expand Down
11 changes: 8 additions & 3 deletions src/mutations/itemLike.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { act } from 'react-test-renderer';

import { HttpMethod } from '@graasp/sdk';

import { ITEMS, ITEM_LIKES, UNAUTHORIZED_RESPONSE } from '../../test/constants';
import {
ITEMS,
ITEM_LIKES,
MOCK_MEMBER,
UNAUTHORIZED_RESPONSE,
} from '../../test/constants';
import { mockMutation, setUpTest, waitForMutation } from '../../test/utils';
import {
buildDeleteItemLikeRoute,
Expand All @@ -29,7 +34,7 @@ describe('Item Like Mutations', () => {

describe('usePostItemLike', () => {
const itemId = ITEMS.first()!.id;
const memberId = 'member-id';
const memberId = MOCK_MEMBER.id;
const likedItemsKey = buildGetLikesForMemberKey(memberId);
const route = `/${buildPostItemLikeRoute(itemId)}`;
const mutation = mutations.usePostItemLike;
Expand Down Expand Up @@ -97,7 +102,7 @@ describe('Item Like Mutations', () => {

describe('useDeleteItemLike', () => {
const itemId = ITEMS.first()!.id;
const memberId = 'member-id';
const memberId = MOCK_MEMBER.id;
const likedItemsKey = buildGetLikesForMemberKey(memberId);
const route = `/${buildDeleteItemLikeRoute(itemId)}`;
const mutation = mutations.useDeleteItemLike;
Expand Down
85 changes: 48 additions & 37 deletions src/mutations/itemLike.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,60 @@
import { QueryClient, useMutation } from 'react-query';
import { QueryClient, useMutation, useQueryClient } from 'react-query';

import { UUID } from '@graasp/sdk';
import { ItemLike, Member, UUID } from '@graasp/sdk';

import * as Api from '../api';
import { MUTATION_KEYS, buildGetLikesForMemberKey } from '../config/keys';
import {
buildGetLikesForItem,
buildGetLikesForMemberKey,
} from '../config/keys';
import { deleteItemLikeRoutine, postItemLikeRoutine } from '../routines';
import { QueryClientConfig } from '../types';

const { POST_ITEM_LIKE, DELETE_ITEM_LIKE } = MUTATION_KEYS;

export default (queryClient: QueryClient, queryConfig: QueryClientConfig) => {
export default (_queryClient: QueryClient, queryConfig: QueryClientConfig) => {
const { notifier } = queryConfig;

queryClient.setMutationDefaults(MUTATION_KEYS.POST_ITEM_LIKE, {
mutationFn: ({ itemId }) => Api.postItemLike(itemId, queryConfig),
onSuccess: () => {
notifier?.({ type: postItemLikeRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({ type: postItemLikeRoutine.FAILURE, payload: { error } });
},
onSettled: (_data, _error, { memberId }) => {
queryClient.invalidateQueries(buildGetLikesForMemberKey(memberId));
},
});
const usePostItemLike = () =>
useMutation<void, unknown, { itemId: UUID }>(POST_ITEM_LIKE);
const usePostItemLike = () => {
const queryClient = useQueryClient();
return useMutation<
ItemLike,
Error,
{ itemId: UUID; memberId: Member['id'] }
>(({ itemId }) => Api.postItemLike(itemId, queryConfig), {
onSuccess: () => {
notifier?.({ type: postItemLikeRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({ type: postItemLikeRoutine.FAILURE, payload: { error } });
},
onSettled: (_data, _error, { memberId, itemId }) => {
queryClient.invalidateQueries(buildGetLikesForMemberKey(memberId));
queryClient.invalidateQueries(buildGetLikesForItem(itemId));
},
});
};

queryClient.setMutationDefaults(DELETE_ITEM_LIKE, {
mutationFn: ({ itemId }) => Api.deleteItemLike(itemId, queryConfig),
onSuccess: () => {
notifier?.({ type: deleteItemLikeRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({
type: deleteItemLikeRoutine.FAILURE,
payload: { error },
});
},
onSettled: (_data, _error, { memberId }) => {
queryClient.invalidateQueries(buildGetLikesForMemberKey(memberId));
},
});
const useDeleteItemLike = () =>
useMutation<void, unknown, { id: UUID }>(DELETE_ITEM_LIKE);
const useDeleteItemLike = () => {
const queryClient = useQueryClient();
return useMutation<
ItemLike,
Error,
{ itemId: UUID; memberId: Member['id'] }
>(({ itemId }) => Api.deleteItemLike(itemId, queryConfig), {
onSuccess: () => {
notifier?.({ type: deleteItemLikeRoutine.SUCCESS });
},
onError: (error) => {
notifier?.({
type: deleteItemLikeRoutine.FAILURE,
payload: { error },
});
},
onSettled: (_data, _error, { memberId, itemId }) => {
queryClient.invalidateQueries(buildGetLikesForMemberKey(memberId));
queryClient.invalidateQueries(buildGetLikesForItem(itemId));
},
});
};

return {
usePostItemLike,
Expand Down
34 changes: 20 additions & 14 deletions test/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
Invitation,
Item,
ItemCategory,
ItemLike,
ItemLoginSchemaType,
ItemMembership,
ItemTag,
Expand Down Expand Up @@ -578,20 +579,25 @@ export const ITEM_CATEGORIES: List<ItemCategoryRecord> = List([
ITEM_CATEGORY_1,
ITEM_CATEGORY_2,
]);
export const ITEM_LIKES: List<ItemLikeRecord> = convertJs([
{
id: 'id1',
item: MOCK_ITEM,
member: MOCK_MEMBER,
createdAt: new Date(),
},
{
id: 'id2',
item: MOCK_ITEM,
member: MOCK_MEMBER,
createdAt: new Date(),
},
]);

const buildItemLikes = (): List<ItemLikeRecord> => {
const data: ItemLike[] = [
{
id: 'id1',
item: MOCK_ITEM,
creator: MOCK_MEMBER,
createdAt: new Date(),
},
{
id: 'id2',
item: MOCK_ITEM,
creator: MOCK_MEMBER,
createdAt: new Date(),
},
];
return convertJs(data);
};
export const ITEM_LIKES: List<ItemLikeRecord> = buildItemLikes();

export const ITEM_VALIDATION_GROUP: ItemValidationGroupRecord = convertJs({
id: 'id-1',
Expand Down
Loading

0 comments on commit 2623486

Please sign in to comment.