feat: optimistically update when deleting an availability (#4648)
* feat: use optimistic updates for deleting * feat: remove loading props * feat: remove loading props from v1 component Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Alex van Andel <me@alexvanandel.com>pull/4656/head^2
parent
ca859c871c
commit
f14b13a1ba
|
@ -51,7 +51,6 @@ export function AvailabilityList({ schedules }: inferQueryOutput<"viewer.availab
|
|||
key={schedule.id}
|
||||
schedule={schedule}
|
||||
deleteFunction={deleteMutation.mutate}
|
||||
isDeleting={deleteMutation.isLoading}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -21,16 +21,32 @@ export function AvailabilityList({ schedules }: inferQueryOutput<"viewer.availab
|
|||
const meQuery = trpc.useQuery(["viewer.me"]);
|
||||
|
||||
const deleteMutation = trpc.useMutation("viewer.availability.schedule.delete", {
|
||||
onSuccess: async () => {
|
||||
await utils.invalidateQueries(["viewer.availability.list"]);
|
||||
showToast(t("schedule_deleted_successfully"), "success");
|
||||
onMutate: async ({ scheduleId }) => {
|
||||
await utils.cancelQuery(["viewer.availability.list"]);
|
||||
const previousValue = utils.getQueryData(["viewer.availability.list"]);
|
||||
if (previousValue) {
|
||||
const filteredValue = previousValue.schedules.filter(({ id }) => id !== scheduleId);
|
||||
utils.setQueryData(["viewer.availability.list"], { ...previousValue, schedules: filteredValue });
|
||||
}
|
||||
|
||||
return { previousValue };
|
||||
},
|
||||
onError: (err) => {
|
||||
|
||||
onError: (err, variables, context) => {
|
||||
if (context?.previousValue) {
|
||||
utils.setQueryData(["viewer.availability.list"], context.previousValue);
|
||||
}
|
||||
if (err instanceof HttpError) {
|
||||
const message = `${err.statusCode}: ${err.message}`;
|
||||
showToast(message, "error");
|
||||
}
|
||||
},
|
||||
onSettled: () => {
|
||||
utils.invalidateQueries(["viewer.availability.list"]);
|
||||
},
|
||||
onSuccess: () => {
|
||||
showToast(t("schedule_deleted_successfully"), "success");
|
||||
},
|
||||
});
|
||||
|
||||
// Adds smooth delete button - item fades and old item slides into place
|
||||
|
@ -61,7 +77,6 @@ export function AvailabilityList({ schedules }: inferQueryOutput<"viewer.availab
|
|||
key={schedule.id}
|
||||
schedule={schedule}
|
||||
deleteFunction={deleteMutation.mutate}
|
||||
isDeleting={deleteMutation.isLoading}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -13,12 +13,10 @@ import Button from "@calcom/ui/v2/core/Button";
|
|||
export function ScheduleListItem({
|
||||
schedule,
|
||||
deleteFunction,
|
||||
isDeleting = false,
|
||||
displayOptions,
|
||||
}: {
|
||||
schedule: inferQueryOutput<"viewer.availability.list">["schedules"][number];
|
||||
deleteFunction: ({ scheduleId }: { scheduleId: number }) => void;
|
||||
isDeleting: boolean;
|
||||
displayOptions?: {
|
||||
timeZone?: string;
|
||||
hour12?: boolean;
|
||||
|
@ -67,7 +65,6 @@ export function ScheduleListItem({
|
|||
<DropdownMenuContent>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
disabled={isDeleting}
|
||||
onClick={() => {
|
||||
deleteFunction({
|
||||
scheduleId: schedule.id,
|
||||
|
@ -76,9 +73,8 @@ export function ScheduleListItem({
|
|||
type="button"
|
||||
color="destructive"
|
||||
className="w-full font-normal"
|
||||
StartIcon={isDeleting ? undefined : Icon.FiTrash}
|
||||
loading={isDeleting}>
|
||||
{isDeleting ? t("deleting") : t("delete_schedule")}
|
||||
StartIcon={Icon.FiTrash}>
|
||||
{t("delete_schedule")}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
|
Loading…
Reference in New Issue