diff options
Diffstat (limited to 'apps/web')
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx | 12 | ||||
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/ManageListsModal.tsx (renamed from apps/web/components/dashboard/bookmarks/AddToListModal.tsx) | 91 | ||||
| -rw-r--r-- | apps/web/components/dashboard/lists/BookmarkListSelector.tsx | 7 |
3 files changed, 95 insertions, 15 deletions
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx index 6f07107b..e5f38eae 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx @@ -33,9 +33,9 @@ import { import { useRemoveBookmarkFromList } from "@hoarder/shared-react/hooks//lists"; import { useBookmarkGridContext } from "@hoarder/shared-react/hooks/bookmark-grid-context"; -import { useAddToListModal } from "./AddToListModal"; import { BookmarkedTextEditor } from "./BookmarkedTextEditor"; import { ArchivedActionIcon, FavouritedActionIcon } from "./icons"; +import { useManageListsModal } from "./ManageListsModal"; import { useTagModel } from "./TagModal"; export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { @@ -46,8 +46,8 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { const { setOpen: setTagModalIsOpen, content: tagModal } = useTagModel(bookmark); - const { setOpen: setAddToListModalOpen, content: addToListModal } = - useAddToListModal(bookmark.id); + const { setOpen: setManageListsModalOpen, content: manageListsModal } = + useManageListsModal(bookmark.id); const [isTextEditorOpen, setTextEditorOpen] = useState(false); @@ -99,7 +99,7 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { return ( <> {tagModal} - {addToListModal} + {manageListsModal} <BookmarkedTextEditor bookmark={bookmark} open={isTextEditorOpen} @@ -171,9 +171,9 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { <span>Edit Tags</span> </DropdownMenuItem> - <DropdownMenuItem onClick={() => setAddToListModalOpen(true)}> + <DropdownMenuItem onClick={() => setManageListsModalOpen(true)}> <List className="mr-2 size-4" /> - <span>Add to List</span> + <span>Manage Lists</span> </DropdownMenuItem> {listId && ( diff --git a/apps/web/components/dashboard/bookmarks/AddToListModal.tsx b/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx index 3b8a6700..a906aee8 100644 --- a/apps/web/components/dashboard/bookmarks/AddToListModal.tsx +++ b/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx @@ -17,15 +17,21 @@ import { FormMessage, } from "@/components/ui/form"; import { toast } from "@/components/ui/use-toast"; +import { api } from "@/lib/trpc"; import { zodResolver } from "@hookform/resolvers/zod"; +import { X } from "lucide-react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { useAddBookmarkToList } from "@hoarder/shared-react/hooks/lists"; +import { + useAddBookmarkToList, + useBookmarkLists, + useRemoveBookmarkFromList, +} from "@hoarder/shared-react/hooks/lists"; import { BookmarkListSelector } from "../lists/BookmarkListSelector"; -export default function AddToListModal({ +export default function ManageListsModal({ bookmarkId, open, setOpen, @@ -41,15 +47,50 @@ export default function AddToListModal({ }); const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), + defaultValues: { + listId: undefined, + }, }); + const { data: allLists } = useBookmarkLists(undefined, { enabled: open }); + + const { data: alreadyInList } = api.lists.getListsOfBookmark.useQuery( + { + bookmarkId, + }, + { enabled: open }, + ); + const { mutate: addToList, isPending: isAddingToListPending } = useAddBookmarkToList({ onSuccess: () => { toast({ description: "List has been updated!", }); - setOpen(false); + form.resetField("listId"); + }, + onError: (e) => { + if (e.data?.code == "BAD_REQUEST") { + toast({ + variant: "destructive", + description: e.message, + }); + } else { + toast({ + variant: "destructive", + title: "Something went wrong", + }); + } + }, + }); + + const { mutate: deleteFromList, isPending: isDeleteFromListPending } = + useRemoveBookmarkFromList({ + onSuccess: () => { + toast({ + description: "List has been updated!", + }); + form.resetField("listId"); }, onError: (e) => { if (e.data?.code == "BAD_REQUEST") { @@ -79,10 +120,38 @@ export default function AddToListModal({ })} > <DialogHeader> - <DialogTitle>Add to List</DialogTitle> + <DialogTitle>Manage Lists</DialogTitle> </DialogHeader> + {allLists && ( + <ul className="flex flex-col gap-2 pb-2 pt-4"> + {alreadyInList?.lists.map((list) => ( + <li + key={list.id} + className="flex items-center justify-between rounded-lg border border-border bg-background px-2 py-1 text-foreground" + > + <p> + {allLists + .getPathById(list.id)! + .map((l) => `${l.icon} ${l.name}`) + .join(" / ")} + </p> + <ActionButton + type="button" + variant="ghost" + size="sm" + loading={isDeleteFromListPending} + onClick={() => + deleteFromList({ bookmarkId, listId: list.id }) + } + > + <X className="size-4" /> + </ActionButton> + </li> + ))} + </ul> + )} - <div className="py-4"> + <div className="pb-4"> <FormField control={form.control} name="listId" @@ -90,7 +159,13 @@ export default function AddToListModal({ return ( <FormItem> <FormControl> - <BookmarkListSelector onChange={field.onChange} /> + <BookmarkListSelector + value={field.value} + hideBookmarkIds={alreadyInList?.lists.map( + (l) => l.id, + )} + onChange={field.onChange} + /> </FormControl> <FormMessage /> </FormItem> @@ -119,14 +194,14 @@ export default function AddToListModal({ ); } -export function useAddToListModal(bookmarkId: string) { +export function useManageListsModal(bookmarkId: string) { const [open, setOpen] = useState(false); return { open, setOpen, content: ( - <AddToListModal bookmarkId={bookmarkId} open={open} setOpen={setOpen} /> + <ManageListsModal bookmarkId={bookmarkId} open={open} setOpen={setOpen} /> ), }; } diff --git a/apps/web/components/dashboard/lists/BookmarkListSelector.tsx b/apps/web/components/dashboard/lists/BookmarkListSelector.tsx index fdae1c17..144297cf 100644 --- a/apps/web/components/dashboard/lists/BookmarkListSelector.tsx +++ b/apps/web/components/dashboard/lists/BookmarkListSelector.tsx @@ -14,12 +14,14 @@ export function BookmarkListSelector({ value, onChange, hideSubtreeOf, + hideBookmarkIds = [], placeholder = "Select a list", }: { value?: string | null; onChange: (value: string) => void; placeholder?: string; hideSubtreeOf?: string; + hideBookmarkIds?: string[]; }) { const { data, isPending: isFetchingListsPending } = useBookmarkLists(); let { allPaths } = data ?? {}; @@ -29,6 +31,9 @@ export function BookmarkListSelector({ } allPaths = allPaths?.filter((path) => { + if (hideBookmarkIds.includes(path[path.length - 1].id)) { + return false; + } if (!hideSubtreeOf) { return true; } @@ -36,7 +41,7 @@ export function BookmarkListSelector({ }); return ( - <Select onValueChange={onChange} value={value ?? undefined}> + <Select onValueChange={onChange} value={value ?? ""}> <SelectTrigger className="w-full"> <SelectValue placeholder={placeholder} /> </SelectTrigger> |
