perf: improve board optimistic updates

This commit is contained in:
Henry
2025-02-06 22:45:55 +00:00
parent b1fa8a529d
commit fe45c31795
4 changed files with 181 additions and 161 deletions

View File

@@ -1,13 +1,7 @@
import type { ReactNode } from "react";
import React, { createContext, useContext, useState } from "react";
import type {
GetBoardByIdOutput,
NewCardInput,
NewListInput,
ReorderCardInput,
ReorderListInput,
} from "@kan/api/types";
import type { GetBoardByIdOutput, NewListInput } from "@kan/api/types";
import { generateUID } from "@kan/shared/utils";
import { usePopup } from "~/providers/popup";
@@ -16,9 +10,6 @@ import { api } from "~/utils/api";
interface BoardContextProps {
boardData: GetBoardByIdOutput;
setBoardData: React.Dispatch<React.SetStateAction<GetBoardByIdOutput>>;
updateList: (params: ReorderListInput) => void;
updateCard: (params: ReorderCardInput) => void;
addCard: (params: NewCardInput) => void;
addList: (params: NewListInput) => void;
removeCard: (params: { cardPublicId: string }) => void;
refetchBoard: () => Promise<void>;
@@ -60,78 +51,6 @@ export const BoardProvider: React.FC<{ children: ReactNode }> = ({
}
};
const updateCardMutation = api.card.reorder.useMutation({
onSuccess: async () => {
await refetchBoard();
},
onError: async () => {
await refetchBoard();
showPopup({
header: "Unable to update card",
message: "Please try again later, or contact customer support.",
icon: "error",
});
},
});
const updateListMutation = api.list.reorder.useMutation({
onSuccess: async () => {
await refetchBoard();
},
onError: async () => {
await refetchBoard();
showPopup({
header: "Unable to update list",
message: "Please try again later, or contact customer support.",
icon: "error",
});
},
});
const addCard = ({
title,
listPublicId,
labelPublicIds,
memberPublicIds,
position,
}: {
title: string;
listPublicId: string;
labelPublicIds: string[];
memberPublicIds: string[];
position: "start" | "end";
}) => {
if (!boardData) return;
const updatedLists = boardData.lists.map((list) => {
if (list.publicId === listPublicId) {
const newCard = {
publicId: `PLACEHOLDER_${generateUID()}`,
title,
listId: 2,
description: "",
labels: boardData.labels.filter((label) =>
labelPublicIds.includes(label.publicId),
),
members:
boardData.workspace?.members.filter((member) =>
memberPublicIds.includes(member.publicId),
) ?? [],
index: position === "start" ? 0 : list.cards.length,
};
const updatedCards =
position === "start"
? [newCard, ...list.cards]
: [...list.cards, newCard];
return { ...list, cards: updatedCards };
}
return list;
});
setBoardData({ ...boardData, lists: updatedLists });
};
const addList = ({ name, boardPublicId }: NewListInput) => {
if (!boardData) return;
@@ -162,38 +81,11 @@ export const BoardProvider: React.FC<{ children: ReactNode }> = ({
setBoardData({ ...boardData, lists: updatedLists });
};
const updateList = ({
listPublicId,
currentIndex,
newIndex,
}: ReorderListInput) => {
updateListMutation.mutate({
listPublicId,
currentIndex,
newIndex,
});
};
const updateCard = ({
cardPublicId,
newListPublicId,
newIndex,
}: ReorderCardInput) => {
updateCardMutation.mutate({
cardPublicId,
newListPublicId,
newIndex,
});
};
return (
<BoardContext.Provider
value={{
boardData,
setBoardData,
updateList,
updateCard,
addCard,
addList,
removeCard,
refetchBoard,