Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update edit #951

Merged
merged 3 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/item/mutations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ describe('Items Mutations', () => {
const item = FolderItemFactory();
const mutation = mutations.useEditItem;
const itemKey = itemKeys.single(item.id).content;
const payload = { id: item.id, description: 'new description' };
const payload = {
id: item.id,
description: 'new description',
};

it('Edit item in root', async () => {
// set default data
Expand Down Expand Up @@ -85,6 +88,36 @@ describe('Items Mutations', () => {
).toBeTruthy();
});

it('Edit item in root without item in cache', async () => {
// set default data
queryClient.setQueryData(itemKeys.allAccessible(), [FolderItemFactory()]);

const route = `/${buildEditItemRoute(item.id)}`;
const response = item;
const endpoints = [
{
response,
method: HttpMethod.Patch,
route,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
mockedMutation.mutate(payload);
await waitForMutation();
});

expect(
queryClient.getQueryState(itemKeys.allAccessible())?.isInvalidated,
).toBeTruthy();
});

it('Edit item in item', async () => {
// set default data
const parentItem = FolderItemFactory();
Expand All @@ -99,7 +132,7 @@ describe('Items Mutations', () => {
queryClient.setQueryData(parentKey, [FolderItemFactory()]);

const route = `/${buildEditItemRoute(editedItem.id)}`;
const response = item;
const response = editedItem;
const endpoints = [
{
response,
Expand Down
72 changes: 4 additions & 68 deletions src/item/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,57 +122,6 @@ export default (queryConfig: QueryClientConfig) => {
>
>,
) => Api.editItem(item.id, item, queryConfig),
// newItem contains all updatable properties
onMutate: async (
newItem: Partial<DiscriminatedItem> &
Pick<DiscriminatedItem, 'id'> & {
extra?: DiscriminatedItem['extra'];
},
) => {
const itemKey = itemKeys.single(newItem.id).content;

// invalidate key
await queryClient.cancelQueries({ queryKey: itemKey });

// build full item with new values
const prevItem = queryClient.getQueryData<DiscriminatedItem>(itemKey);

// if the item is not in the cache, we don't need to continue with optimistic mutation
if (!prevItem) {
return {};
}

// trim manually names because it does it in the backend
const newFullItem = {
...prevItem,
name: prevItem.name.trim(),
displayName: prevItem.displayName.trim(),
};
queryClient.setQueryData(itemKey, newFullItem);

const previousItems = {
...(Boolean(prevItem) && {
parent: await mutateParentChildren(
{
childPath: prevItem?.path,
value: (old: DiscriminatedItem[]) => {
if (!old?.length) {
return old;
}
const idx = old.findIndex(({ id }) => id === newItem.id);
if (newFullItem && idx >= 0) {
old[idx] = newFullItem;
}
return old;
},
},
queryClient,
),
item: prevItem,
}),
};
return previousItems;
},
onSuccess: () => {
notifier?.(
{
Expand All @@ -182,30 +131,17 @@ export default (queryConfig: QueryClientConfig) => {
{ enableNotifications },
);
},
onError: (error: Error, newItem, context) => {
if (context?.parent && context?.item) {
const prevItem = context?.item;
const parentKey = getKeyForParentId(
getParentFromPath(prevItem?.path),
);
queryClient.setQueryData(parentKey, context.parent);
}

const itemKey = itemKeys.single(newItem.id).content;
queryClient.setQueryData(itemKey, context?.item);

onError: (error: Error) => {
notifier?.(
{ type: editItemRoutine.FAILURE, payload: { error } },
{ enableNotifications },
);
},
onSettled: (_newItem, _error, { id }, context) => {
const prevItem = context?.item;
if (prevItem) {
const parentKey = getKeyForParentId(getParentFromPath(prevItem.path));
onSettled: (newItem, _error, { id }) => {
if (newItem) {
const parentKey = getKeyForParentId(getParentFromPath(newItem.path));
queryClient.invalidateQueries({ queryKey: parentKey });
}

const itemKey = itemKeys.single(id).content;
queryClient.invalidateQueries({ queryKey: itemKey });
},
Expand Down