feat: add optimistic updates for deleting and changing hidden status of event types. (#4721)
* fix: remove loading state * feat: use optimistic update for deleting * feat: use optimistic update for hiding * Moved PR changes Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com>pull/4971/head
parent
3e201c9fe8
commit
7f2560e1e3
|
@ -98,13 +98,34 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||||
});
|
});
|
||||||
|
|
||||||
const setHiddenMutation = trpc.useMutation("viewer.eventTypes.update", {
|
const setHiddenMutation = trpc.useMutation("viewer.eventTypes.update", {
|
||||||
onError: async (err) => {
|
onMutate: async ({ id }) => {
|
||||||
console.error(err.message);
|
|
||||||
await utils.cancelQuery(["viewer.eventTypes"]);
|
await utils.cancelQuery(["viewer.eventTypes"]);
|
||||||
await utils.invalidateQueries(["viewer.eventTypes"]);
|
const previousValue = utils.getQueryData(["viewer.eventTypes"]);
|
||||||
|
if (previousValue) {
|
||||||
|
const newList = [...types];
|
||||||
|
const itemIndex = newList.findIndex((item) => item.id === id);
|
||||||
|
if (itemIndex !== -1 && newList[itemIndex]) {
|
||||||
|
newList[itemIndex].hidden = !newList[itemIndex].hidden;
|
||||||
|
}
|
||||||
|
utils.setQueryData(["viewer.eventTypes"], {
|
||||||
|
...previousValue,
|
||||||
|
eventTypeGroups: [
|
||||||
|
...previousValue.eventTypeGroups.slice(0, groupIndex),
|
||||||
|
{ ...group, eventTypes: newList },
|
||||||
|
...previousValue.eventTypeGroups.slice(groupIndex + 1),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { previousValue };
|
||||||
},
|
},
|
||||||
onSettled: async () => {
|
onError: async (err, _, context) => {
|
||||||
await utils.invalidateQueries(["viewer.eventTypes"]);
|
if (context?.previousValue) {
|
||||||
|
utils.setQueryData(["viewer.eventTypes"], context.previousValue);
|
||||||
|
}
|
||||||
|
console.error(err.message);
|
||||||
|
},
|
||||||
|
onSettled: () => {
|
||||||
|
utils.invalidateQueries(["viewer.eventTypes"]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -169,12 +190,31 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteMutation = trpc.useMutation("viewer.eventTypes.delete", {
|
const deleteMutation = trpc.useMutation("viewer.eventTypes.delete", {
|
||||||
onSuccess: async () => {
|
onSuccess: () => {
|
||||||
await utils.invalidateQueries(["viewer.eventTypes"]);
|
|
||||||
showToast(t("event_type_deleted_successfully"), "success");
|
showToast(t("event_type_deleted_successfully"), "success");
|
||||||
setDeleteDialogOpen(false);
|
setDeleteDialogOpen(false);
|
||||||
},
|
},
|
||||||
onError: (err) => {
|
onMutate: async ({ id }) => {
|
||||||
|
await utils.cancelQuery(["viewer.eventTypes"]);
|
||||||
|
const previousValue = utils.getQueryData(["viewer.eventTypes"]);
|
||||||
|
if (previousValue) {
|
||||||
|
const newList = types.filter((item) => item.id !== id);
|
||||||
|
|
||||||
|
utils.setQueryData(["viewer.eventTypes"], {
|
||||||
|
...previousValue,
|
||||||
|
eventTypeGroups: [
|
||||||
|
...previousValue.eventTypeGroups.slice(0, groupIndex),
|
||||||
|
{ ...group, eventTypes: newList },
|
||||||
|
...previousValue.eventTypeGroups.slice(groupIndex + 1),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { previousValue };
|
||||||
|
},
|
||||||
|
onError: (err, _, context) => {
|
||||||
|
if (context?.previousValue) {
|
||||||
|
utils.setQueryData(["viewer.eventTypes"], context.previousValue);
|
||||||
|
}
|
||||||
if (err instanceof HttpError) {
|
if (err instanceof HttpError) {
|
||||||
const message = `${err.statusCode}: ${err.message}`;
|
const message = `${err.statusCode}: ${err.message}`;
|
||||||
showToast(message, "error");
|
showToast(message, "error");
|
||||||
|
@ -183,6 +223,9 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||||
showToast(err.message, "error");
|
showToast(err.message, "error");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onSettled: () => {
|
||||||
|
utils.invalidateQueries(["viewer.eventTypes"]);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [isNativeShare, setNativeShare] = useState(true);
|
const [isNativeShare, setNativeShare] = useState(true);
|
||||||
|
@ -439,7 +482,6 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||||
</ul>
|
</ul>
|
||||||
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
||||||
<ConfirmationDialogContent
|
<ConfirmationDialogContent
|
||||||
isLoading={deleteMutation.isLoading}
|
|
||||||
variety="danger"
|
variety="danger"
|
||||||
title={t("delete_event_type")}
|
title={t("delete_event_type")}
|
||||||
confirmBtnText={t("confirm_delete_event_type")}
|
confirmBtnText={t("confirm_delete_event_type")}
|
||||||
|
|
Loading…
Reference in New Issue