diff --git a/apps/web/src/components/calendar/flows/create-event/use-create-action.tsx b/apps/web/src/components/calendar/flows/create-event/use-create-action.tsx index f1259760..68a8bfb4 100644 --- a/apps/web/src/components/calendar/flows/create-event/use-create-action.tsx +++ b/apps/web/src/components/calendar/flows/create-event/use-create-action.tsx @@ -4,15 +4,15 @@ import { useSetAtom } from "jotai"; import { addOptimisticActionAtom, generateOptimisticId, - removeDraftOptimisticActionsByEventIdAtom, + removeOptimisticActionsByEventIdAtom, } from "../../hooks/optimistic-actions"; import type { CreateQueueItem, CreateQueueRequest } from "./create-queue"; import { CreateQueueContext } from "./create-queue-provider"; export function useCreateAction() { const addOptimisticAction = useSetAtom(addOptimisticActionAtom); - const removeDraftOptimisticActionsByEventId = useSetAtom( - removeDraftOptimisticActionsByEventIdAtom, + const removeOptimisticActionsByEventId = useSetAtom( + removeOptimisticActionsByEventIdAtom, ); const actorRef = CreateQueueContext.useActorRef(); @@ -22,10 +22,9 @@ export function useCreateAction() { const optimisticId = generateOptimisticId(); React.startTransition(() => { - // Remove any existing draft optimistic actions for this event - removeDraftOptimisticActionsByEventId(req.event.id); + // Removes all existing actions; relevant in the case of duplicate creates + removeOptimisticActionsByEventId(req.event.id); - // Add the create optimistic action addOptimisticAction({ id: optimisticId, type: "create", @@ -46,7 +45,7 @@ export function useCreateAction() { // Return optimistic id to allow callers to await completion externally return optimisticId; }, - [actorRef, addOptimisticAction, removeDraftOptimisticActionsByEventId], + [actorRef, addOptimisticAction, removeOptimisticActionsByEventId], ); return update; diff --git a/apps/web/src/components/calendar/flows/delete-event/delete-queue-provider.tsx b/apps/web/src/components/calendar/flows/delete-event/delete-queue-provider.tsx index fad003ed..cf72afd4 100644 --- a/apps/web/src/components/calendar/flows/delete-event/delete-queue-provider.tsx +++ b/apps/web/src/components/calendar/flows/delete-event/delete-queue-provider.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { createActorContext } from "@xstate/react"; import { useSetAtom } from "jotai"; -import { removeOptimisticActionAtom } from "@/components/calendar/hooks/optimistic-actions"; +import { removeOptimisticActionAtom, removeOptimisticActionsByEventIdAtom } from "@/components/calendar/hooks/optimistic-actions"; import { useDeleteEventMutation } from "@/components/calendar/hooks/use-event-mutations"; import { getEventById } from "@/lib/db"; import { createDeleteQueueMachine, type DeleteQueueItem } from "./delete-queue"; @@ -21,15 +21,15 @@ interface DeleteQueueProviderProps { export function DeleteQueueProvider({ children }: DeleteQueueProviderProps) { const deleteMutation = useDeleteEventMutation(); const removeOptimisticAction = useSetAtom(removeOptimisticActionAtom); + const removeOptimisticActionsByEventId = useSetAtom(removeOptimisticActionsByEventIdAtom); const deleteEvent = React.useCallback( async (item: DeleteQueueItem) => { const prevEvent = await getEventById(item.event.id); if (!prevEvent) { - if (item.event?.type === "draft") { - removeOptimisticAction(item.optimisticId); - } + // need to delete draft event + removeOptimisticActionsByEventId(item.event.id); return; } @@ -53,7 +53,7 @@ export function DeleteQueueProvider({ children }: DeleteQueueProviderProps) { }, ); }, - [deleteMutation, removeOptimisticAction], + [deleteMutation, removeOptimisticAction, removeOptimisticActionsByEventId], ); const logic = React.useMemo(() => { diff --git a/apps/web/src/components/calendar/flows/update-event/update-queue-provider.tsx b/apps/web/src/components/calendar/flows/update-event/update-queue-provider.tsx index a67008f5..34d572c5 100644 --- a/apps/web/src/components/calendar/flows/update-event/update-queue-provider.tsx +++ b/apps/web/src/components/calendar/flows/update-event/update-queue-provider.tsx @@ -45,7 +45,7 @@ export function UpdateQueueProvider({ children }: UpdateQueueProviderProps) { removeOptimisticAction(item.optimisticId); }, onSuccess: () => { - // removeOptimisticAction(item.optimisticId); + removeOptimisticAction(item.optimisticId); item.onSuccess?.(); }, }, @@ -61,7 +61,7 @@ export function UpdateQueueProvider({ children }: UpdateQueueProviderProps) { removeOptimisticAction(item.optimisticId); }, onSuccess: () => { - // removeOptimisticAction(item.optimisticId); + removeOptimisticAction(item.optimisticId); item.onSuccess?.(); }, }, diff --git a/apps/web/src/components/calendar/hooks/optimistic-actions.ts b/apps/web/src/components/calendar/hooks/optimistic-actions.ts index a8cec40c..c40a0e02 100644 --- a/apps/web/src/components/calendar/hooks/optimistic-actions.ts +++ b/apps/web/src/components/calendar/hooks/optimistic-actions.ts @@ -86,3 +86,17 @@ export const removeDraftOptimisticActionsByEventIdAtom = atom( set(optimisticActionsAtom, filtered); }, ); + +export const removeOptimisticActionsByEventIdAtom = atom( + null, + (get, set, eventId: string) => { + const currentActions = get(optimisticActionsAtom); + const filtered = Object.fromEntries( + Object.entries(currentActions).filter( + ([, action]) => action.eventId !== eventId, + ), + ); + + set(optimisticActionsAtom, filtered); + }, +); diff --git a/apps/web/src/components/calendar/hooks/use-optimistic-mutations.ts b/apps/web/src/components/calendar/hooks/use-optimistic-mutations.ts index 42c758c4..d783e86e 100644 --- a/apps/web/src/components/calendar/hooks/use-optimistic-mutations.ts +++ b/apps/web/src/components/calendar/hooks/use-optimistic-mutations.ts @@ -11,6 +11,7 @@ import { useTRPC } from "@/lib/trpc/client"; import { EventFormStateContext } from "../flows/event-form/event-form-state-provider"; import { addOptimisticActionAtom, + generateOptimisticId, removeDraftOptimisticActionsByEventIdAtom, } from "./optimistic-actions"; @@ -33,9 +34,12 @@ export function useCreateDraftAction() { unselectAllAction(); + const optimisticId = generateOptimisticId(); + addOptimisticAction({ type: "draft", eventId: event.id, + id: optimisticId, event: { ...event, type: "draft",