Pass the entire link to the store & fix bulk update function
This commit is contained in:
parent
da0533ac36
commit
582607e726
|
@ -35,10 +35,16 @@ export default function LinkCard({
|
|||
|
||||
const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore();
|
||||
|
||||
const handleCheckboxClick = (checkboxId: number) => {
|
||||
setSelectedLinks((selectedLinks.includes(checkboxId) ? selectedLinks.filter((id) => id !== checkboxId) : [...selectedLinks, checkboxId]));
|
||||
const handleCheckboxClick = (link: LinkIncludingShortenedCollectionAndTags) => {
|
||||
if (selectedLinks.includes(link)) {
|
||||
setSelectedLinks(selectedLinks.filter((e) => e !== link));
|
||||
} else {
|
||||
setSelectedLinks([...selectedLinks, link]);
|
||||
}
|
||||
};
|
||||
|
||||
console.log(selectedLinks)
|
||||
|
||||
let shortendURL;
|
||||
|
||||
try {
|
||||
|
@ -96,8 +102,8 @@ export default function LinkCard({
|
|||
<input
|
||||
type="checkbox"
|
||||
className="checkbox checkbox-primary my-auto ml-3 mt-3 absolute z-20 bg-white dark:bg-base-200"
|
||||
checked={selectedLinks.includes(link.id)}
|
||||
onChange={() => handleCheckboxClick(link.id)}
|
||||
checked={selectedLinks.includes(link)}
|
||||
onChange={() => handleCheckboxClick(link)}
|
||||
/>
|
||||
}
|
||||
<Link
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function BulkDeleteLinksModal({ onClose }: Props) {
|
|||
const deleteLink = async () => {
|
||||
const load = toast.loading(`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : ""}...`);
|
||||
|
||||
const response = await deleteLinksById(selectedLinks);
|
||||
const response = await deleteLinksById(selectedLinks.map(link => link.id));
|
||||
|
||||
toast.dismiss(load);
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
|
||||
import updateLinkById from "../linkId/updateLinkById";
|
||||
|
||||
// Need to fix this
|
||||
export default async function updateLinks(userId: number, links: LinkIncludingShortenedCollectionAndTags[], newData: Pick<LinkIncludingShortenedCollectionAndTags, "tags" | "collectionId">) {
|
||||
let allUpdatesSuccessful = true;
|
||||
|
||||
for (const link of links) {
|
||||
const updatedData: LinkIncludingShortenedCollectionAndTags = {
|
||||
...link,
|
||||
tags: [...link.tags, ...(newData.tags ?? [])],
|
||||
collectionId: newData.collectionId ?? link.collectionId,
|
||||
}
|
||||
|
||||
const updatedLink = await updateLinkById(userId, link.id, updatedData);
|
||||
|
||||
if (updatedLink.status !== 200) {
|
||||
allUpdatesSuccessful = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allUpdatesSuccessful) {
|
||||
return { response: "All links updated successfully", status: 200 };
|
||||
} else {
|
||||
return { response: "Some links failed to update", status: 400 };
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import getPermission from "@/lib/api/getPermission";
|
||||
import { UsersAndCollections } from "@prisma/client";
|
||||
|
||||
// Need to fix this
|
||||
export default async function updateLinksById(userId: number, linkIds: number[], data: LinkIncludingShortenedCollectionAndTags) {
|
||||
if (!linkIds || linkIds.length === 0) {
|
||||
return { response: "Please choose valid links.", status: 401 };
|
||||
}
|
||||
|
||||
// Check if the user has access to the collection of each link
|
||||
// if any of the links are not accessible, return an error
|
||||
for (const linkId of linkIds) {
|
||||
const linkIsAccessible = await getPermission({ userId, linkId });
|
||||
|
||||
const memberHasAccess = linkIsAccessible?.members.some(
|
||||
(e: UsersAndCollections) => e.userId === userId && e.canUpdate
|
||||
);
|
||||
|
||||
if (!(linkIsAccessible?.ownerId === userId || memberHasAccess)) {
|
||||
return { response: "Link is not accessible.", status: 401 };
|
||||
}
|
||||
}
|
||||
|
||||
const updateData = {
|
||||
collection: {
|
||||
connect: {
|
||||
id: data.collection.id,
|
||||
},
|
||||
},
|
||||
tags: {
|
||||
set: [],
|
||||
connectOrCreate: data.tags.map((tag) => ({
|
||||
where: {
|
||||
name_ownerId: {
|
||||
name: tag.name,
|
||||
ownerId: data.collection.ownerId,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
name: tag.name,
|
||||
owner: {
|
||||
connect: {
|
||||
id: data.collection.ownerId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
},
|
||||
include: {
|
||||
tags: true,
|
||||
collection: true,
|
||||
}
|
||||
};
|
||||
|
||||
const updatedLinks = await prisma.link.updateMany({
|
||||
where: {
|
||||
id: { in: linkIds },
|
||||
},
|
||||
data: updateData,
|
||||
});
|
||||
|
||||
return { response: updatedLinks, status: 200 };
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { prisma } from "@/lib/api/db";
|
||||
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
|
||||
import { Collection, Link, UsersAndCollections } from "@prisma/client";
|
||||
import { UsersAndCollections } from "@prisma/client";
|
||||
import getPermission from "@/lib/api/getPermission";
|
||||
import moveFile from "@/lib/api/storage/moveFile";
|
||||
|
||||
|
@ -48,9 +48,9 @@ export default async function updateLinkById(
|
|||
collection: true,
|
||||
pinnedBy: isCollectionOwner
|
||||
? {
|
||||
where: { id: userId },
|
||||
select: { id: true },
|
||||
}
|
||||
where: { id: userId },
|
||||
select: { id: true },
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
});
|
||||
|
@ -111,9 +111,9 @@ export default async function updateLinkById(
|
|||
collection: true,
|
||||
pinnedBy: isCollectionOwner
|
||||
? {
|
||||
where: { id: userId },
|
||||
select: { id: true },
|
||||
}
|
||||
where: { id: userId },
|
||||
select: { id: true },
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import deleteLinksById from "@/lib/api/controllers/links/bulk/deleteLinksById";
|
||||
import updateLinksById from "@/lib/api/controllers/links/bulk/updateLinksById";
|
||||
import updateLinksById from "@/lib/api/controllers/links/bulk/updateLinks";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
|
|
|
@ -4,7 +4,7 @@ import postLink from "@/lib/api/controllers/links/postLink";
|
|||
import { LinkRequestQuery } from "@/types/global";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import deleteLinksById from "@/lib/api/controllers/links/bulk/deleteLinksById";
|
||||
import updateLinksById from "@/lib/api/controllers/links/bulk/updateLinksById";
|
||||
import updateLinksById from "@/lib/api/controllers/links/bulk/updateLinks";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const user = await verifyUser({ req, res });
|
||||
|
|
|
@ -111,14 +111,14 @@ export default function Index() {
|
|||
if (selectedLinks.length === links.length) {
|
||||
setSelectedLinks([]);
|
||||
} else {
|
||||
setSelectedLinks(links.map((e) => e.id));
|
||||
setSelectedLinks(links.map((link) => link));
|
||||
}
|
||||
};
|
||||
|
||||
const bulkDeleteLinks = async () => {
|
||||
const load = toast.loading(`Deleting ${selectedLinks.length} Link${selectedLinks.length > 1 ? "s" : ""}...`);
|
||||
|
||||
const response = await deleteLinksById(selectedLinks);
|
||||
const response = await deleteLinksById(selectedLinks.map((link) => link.id));
|
||||
|
||||
toast.dismiss(load);
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@ type ResponseObject = {
|
|||
|
||||
type LinkStore = {
|
||||
links: LinkIncludingShortenedCollectionAndTags[];
|
||||
selectedLinks: number[];
|
||||
selectedLinks: LinkIncludingShortenedCollectionAndTags[];
|
||||
setLinks: (
|
||||
data: LinkIncludingShortenedCollectionAndTags[],
|
||||
isInitialCall: boolean
|
||||
) => void;
|
||||
setSelectedLinks: (linkIds: number[]) => void;
|
||||
setSelectedLinks: (links: LinkIncludingShortenedCollectionAndTags[]) => void;
|
||||
addLink: (
|
||||
body: LinkIncludingShortenedCollectionAndTags
|
||||
) => Promise<ResponseObject>;
|
||||
|
@ -23,7 +23,6 @@ type LinkStore = {
|
|||
updateLink: (
|
||||
link: LinkIncludingShortenedCollectionAndTags
|
||||
) => Promise<ResponseObject>;
|
||||
updateLinksById: (linkIds: number[], data: Partial<LinkIncludingShortenedCollectionAndTags>) => Promise<ResponseObject>;
|
||||
removeLink: (linkId: number) => Promise<ResponseObject>;
|
||||
deleteLinksById: (linkIds: number[]) => Promise<ResponseObject>;
|
||||
resetLinks: () => void;
|
||||
|
@ -50,7 +49,7 @@ const useLinkStore = create<LinkStore>()((set) => ({
|
|||
),
|
||||
}));
|
||||
},
|
||||
setSelectedLinks: (linkIds) => set({ selectedLinks: linkIds }),
|
||||
setSelectedLinks: (links) => set({ selectedLinks: links }),
|
||||
addLink: async (body) => {
|
||||
const response = await fetch("/api/v1/links", {
|
||||
body: JSON.stringify(body),
|
||||
|
@ -128,29 +127,7 @@ const useLinkStore = create<LinkStore>()((set) => ({
|
|||
|
||||
return { ok: response.ok, data: data.response };
|
||||
},
|
||||
updateLinksById: async (linkIds, data) => {
|
||||
const response = await fetch("/api/v1/links", {
|
||||
body: JSON.stringify({ linkIds, data }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "PUT",
|
||||
});
|
||||
|
||||
const responseData = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
set((state) => ({
|
||||
links: state.links.map((link) =>
|
||||
linkIds.includes(link.id) ? { ...link, ...data } : link
|
||||
),
|
||||
}));
|
||||
useTagStore.getState().setTags();
|
||||
useCollectionStore.getState().setCollections();
|
||||
}
|
||||
|
||||
return { ok: response.ok, data: responseData.response };
|
||||
},
|
||||
removeLink: async (linkId) => {
|
||||
const response = await fetch(`/api/v1/links/${linkId}`, {
|
||||
headers: {
|
||||
|
|
Ŝarĝante…
Reference in New Issue