feat: optimisic card updates

This commit is contained in:
Henry
2025-02-02 10:33:32 +00:00
parent 14b4d73fb6
commit eba5d9335c
6 changed files with 122 additions and 19 deletions

View File

@@ -9,7 +9,7 @@ import {
HiOutlineUserPlus,
} from "react-icons/hi2";
import { type GetCardByIdOutput } from "@kan/api/types";
import type { GetCardByIdOutput } from "@kan/api/types";
import Avatar from "~/components/Avatar";
import Comment from "./Comment";
@@ -148,7 +148,7 @@ const ActivityList = ({
}) => {
return (
<div className="flex flex-col space-y-4 pt-4">
{activities?.map((activity, index) => {
{activities.map((activity, index) => {
const activityText = getActivityText({
type: activity.type,
toTitle: activity.toTitle,

View File

@@ -14,12 +14,14 @@ interface LabelSelectorProps {
selected: boolean;
leftIcon: React.ReactNode;
}[];
handleSelectLabel: (labelPublicId: string) => void;
isLoading: boolean;
}
export default function LabelSelector({
cardPublicId,
labels,
handleSelectLabel,
isLoading,
}: LabelSelectorProps) {
const { openModal } = useModal();
@@ -44,9 +46,10 @@ export default function LabelSelector({
) : (
<CheckboxDropdown
items={labels}
handleSelect={(_, label) =>
addOrRemoveLabel.mutate({ cardPublicId, labelPublicId: label.key })
}
handleSelect={(_, label) => {
handleSelectLabel(label.key);
addOrRemoveLabel.mutate({ cardPublicId, labelPublicId: label.key });
}}
handleEdit={(labelPublicId) => openModal("EDIT_LABEL", labelPublicId)}
handleCreate={() => openModal("NEW_LABEL")}
createNewItemLabel="Create new label"

View File

@@ -10,12 +10,14 @@ interface ListSelectorProps {
value: string;
selected: boolean;
}[];
handleChangeList: (newListPublicId: string, newListName: string) => void;
isLoading: boolean;
}
export default function ListSelector({
cardPublicId,
lists,
handleChangeList,
isLoading,
}: ListSelectorProps) {
const utils = api.useUtils();
@@ -39,12 +41,13 @@ export default function ListSelector({
) : (
<CheckboxDropdown
items={lists}
handleSelect={(_, member) =>
handleSelect={(_, member) => {
handleChangeList(member.key, member.value);
updateCardList.mutate({
cardPublicId,
newListPublicId: member.key,
})
}
});
}}
asChild
>
<Menu.Button className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-200 py-1 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-300 dark:border-dark-100 dark:text-dark-1000 dark:hover:border-dark-300 dark:hover:bg-dark-200">

View File

@@ -5,6 +5,7 @@ import { HiMiniPlus } from "react-icons/hi2";
import Avatar from "~/components/Avatar";
import CheckboxDropdown from "~/components/CheckboxDropdown";
import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup";
import { api } from "~/utils/api";
interface MemberSelectorProps {
@@ -16,16 +17,19 @@ interface MemberSelectorProps {
leftIcon: React.ReactNode;
imageUrl: string | undefined;
}[];
handleSelectMember: (memberPublicId: string) => void;
isLoading: boolean;
}
export default function MemberSelector({
cardPublicId,
members,
handleSelectMember,
isLoading,
}: MemberSelectorProps) {
const router = useRouter();
const { openModal } = useModal();
const { showPopup } = usePopup();
const utils = api.useUtils();
const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
@@ -34,6 +38,14 @@ export default function MemberSelector({
onSuccess: async () => {
await refetchCard();
},
onError: async () => {
await refetchCard();
showPopup({
header: "Unable to update members",
message: "Please try again later, or contact customer support.",
icon: "error",
});
},
});
const selectedMembers = members.filter((member) => member.selected);
@@ -52,12 +64,13 @@ export default function MemberSelector({
) : (
<CheckboxDropdown
items={members}
handleSelect={(_, member) =>
handleSelect={(_, member) => {
handleSelectMember(member.key);
addOrRemoveMember.mutate({
cardPublicId,
workspaceMemberPublicId: member.key,
})
}
});
}}
handleCreate={handleInviteMember}
createNewItemLabel="Invite member"
asChild