fix: allow assigning cards to any member in a user's workspace

This commit is contained in:
Henry
2025-02-03 22:27:28 +00:00
parent eba5d9335c
commit 3ba600bc41
6 changed files with 49 additions and 16 deletions

View File

@@ -126,7 +126,6 @@ const getActivityIcon = (
fromIndex?: number | null, fromIndex?: number | null,
toIndex?: number | null, toIndex?: number | null,
): React.ReactNode | null => { ): React.ReactNode | null => {
console.log({ fromIndex, toIndex });
if (type === "card.updated.list" && fromIndex != null && toIndex != null) { if (type === "card.updated.list" && fromIndex != null && toIndex != null) {
return fromIndex > toIndex ? ( return fromIndex > toIndex ? (
<HiOutlineArrowLeft /> <HiOutlineArrowLeft />

View File

@@ -4,6 +4,7 @@ import { HiMiniPlus } from "react-icons/hi2";
import Badge from "~/components/Badge"; import Badge from "~/components/Badge";
import CheckboxDropdown from "~/components/CheckboxDropdown"; import CheckboxDropdown from "~/components/CheckboxDropdown";
import { useModal } from "~/providers/modal"; import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
interface LabelSelectorProps { interface LabelSelectorProps {
@@ -14,6 +15,7 @@ interface LabelSelectorProps {
selected: boolean; selected: boolean;
leftIcon: React.ReactNode; leftIcon: React.ReactNode;
}[]; }[];
refetchCard: () => Promise<void>;
handleSelectLabel: (labelPublicId: string) => void; handleSelectLabel: (labelPublicId: string) => void;
isLoading: boolean; isLoading: boolean;
} }
@@ -21,18 +23,25 @@ interface LabelSelectorProps {
export default function LabelSelector({ export default function LabelSelector({
cardPublicId, cardPublicId,
labels, labels,
refetchCard,
handleSelectLabel, handleSelectLabel,
isLoading, isLoading,
}: LabelSelectorProps) { }: LabelSelectorProps) {
const { openModal } = useModal(); const { openModal } = useModal();
const utils = api.useUtils(); const { showPopup } = usePopup();
const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const addOrRemoveLabel = api.card.addOrRemoveLabel.useMutation({ const addOrRemoveLabel = api.card.addOrRemoveLabel.useMutation({
onSuccess: async () => { onSuccess: async () => {
await refetchCard(); await refetchCard();
}, },
onError: async () => {
await refetchCard();
showPopup({
header: "Unable to update labels",
message: "Please try again later, or contact customer support.",
icon: "error",
});
},
}); });
const selectedLabels = labels.filter((label) => label.selected); const selectedLabels = labels.filter((label) => label.selected);

View File

@@ -1,6 +1,7 @@
import { Menu } from "@headlessui/react"; import { Menu } from "@headlessui/react";
import CheckboxDropdown from "~/components/CheckboxDropdown"; import CheckboxDropdown from "~/components/CheckboxDropdown";
import { usePopup } from "~/providers/popup";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
interface ListSelectorProps { interface ListSelectorProps {
@@ -10,6 +11,7 @@ interface ListSelectorProps {
value: string; value: string;
selected: boolean; selected: boolean;
}[]; }[];
refetchCard: () => Promise<void>;
handleChangeList: (newListPublicId: string, newListName: string) => void; handleChangeList: (newListPublicId: string, newListName: string) => void;
isLoading: boolean; isLoading: boolean;
} }
@@ -18,16 +20,23 @@ export default function ListSelector({
cardPublicId, cardPublicId,
lists, lists,
handleChangeList, handleChangeList,
refetchCard,
isLoading, isLoading,
}: ListSelectorProps) { }: ListSelectorProps) {
const utils = api.useUtils(); const { showPopup } = usePopup();
const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const updateCardList = api.card.reorder.useMutation({ const updateCardList = api.card.reorder.useMutation({
onSuccess: async () => { onSuccess: async () => {
await refetchCard(); await refetchCard();
}, },
onError: async () => {
await refetchCard();
showPopup({
header: "Unable to update list",
message: "Please try again later, or contact customer support.",
icon: "error",
});
},
}); });
const selectedList = lists.find((list) => list.selected); const selectedList = lists.find((list) => list.selected);

View File

@@ -18,6 +18,7 @@ interface MemberSelectorProps {
imageUrl: string | undefined; imageUrl: string | undefined;
}[]; }[];
handleSelectMember: (memberPublicId: string) => void; handleSelectMember: (memberPublicId: string) => void;
refetchCard: () => Promise<void>;
isLoading: boolean; isLoading: boolean;
} }
@@ -25,14 +26,12 @@ export default function MemberSelector({
cardPublicId, cardPublicId,
members, members,
handleSelectMember, handleSelectMember,
refetchCard,
isLoading, isLoading,
}: MemberSelectorProps) { }: MemberSelectorProps) {
const router = useRouter(); const router = useRouter();
const { openModal } = useModal(); const { openModal } = useModal();
const { showPopup } = usePopup(); const { showPopup } = usePopup();
const utils = api.useUtils();
const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const addOrRemoveMember = api.card.addOrRemoveMember.useMutation({ const addOrRemoveMember = api.card.addOrRemoveMember.useMutation({
onSuccess: async () => { onSuccess: async () => {

View File

@@ -44,10 +44,20 @@ export default function CardPage() {
? router.query.cardId[0] ? router.query.cardId[0]
: router.query.cardId; : router.query.cardId;
const { data, isLoading } = api.card.byId.useQuery({ const { data, isLoading, refetch } = api.card.byId.useQuery({
cardPublicId: cardId ?? "", cardPublicId: cardId ?? "",
}); });
const refetchCard = async () => {
try {
const { data: updatedCard } = await refetch();
if (updatedCard) setCard(updatedCard);
} catch (error) {
console.error({ error });
}
};
useEffect(() => { useEffect(() => {
setCard(data); setCard(data);
}, [data]); }, [data]);
@@ -180,9 +190,11 @@ export default function CardPage() {
const updateCard = api.card.update.useMutation({ const updateCard = api.card.update.useMutation({
onSuccess: async () => { onSuccess: async () => {
await utils.card.byId.refetch(); await refetchCard();
}, },
onError: () => { onError: async () => {
await refetchCard();
showPopup({ showPopup({
header: "Unable to update card", header: "Unable to update card",
message: "Please try again later, or contact customer support.", message: "Please try again later, or contact customer support.",
@@ -295,6 +307,7 @@ export default function CardPage() {
<ListSelector <ListSelector
cardPublicId={cardId} cardPublicId={cardId}
lists={formattedLists} lists={formattedLists}
refetchCard={refetchCard}
handleChangeList={handleChangeList} handleChangeList={handleChangeList}
isLoading={isLoading} isLoading={isLoading}
/> />
@@ -304,6 +317,7 @@ export default function CardPage() {
<LabelSelector <LabelSelector
cardPublicId={cardId} cardPublicId={cardId}
labels={formattedLabels} labels={formattedLabels}
refetchCard={refetchCard}
handleSelectLabel={handleSelectLabel} handleSelectLabel={handleSelectLabel}
isLoading={isLoading} isLoading={isLoading}
/> />
@@ -313,6 +327,7 @@ export default function CardPage() {
<MemberSelector <MemberSelector
cardPublicId={cardId} cardPublicId={cardId}
members={formattedMembers} members={formattedMembers}
refetchCard={refetchCard}
handleSelectMember={handleSelectMember} handleSelectMember={handleSelectMember}
isLoading={isLoading} isLoading={isLoading}
/> />

View File

@@ -582,9 +582,11 @@ USING (
"workspaceMemberId" IN ( "workspaceMemberId" IN (
SELECT wm.id SELECT wm.id
FROM workspace_members wm FROM workspace_members wm
JOIN workspace w ON wm."workspaceId" = w.id WHERE wm."workspaceId" IN (
JOIN board b ON w.id = b."workspaceId" SELECT "workspaceId"
WHERE wm."userId" = auth.uid() FROM workspace_members
WHERE "userId" = auth.uid()
)
) )
); );