diff options
| author | MohamedBassem <me@mbassem.com> | 2024-04-09 15:49:24 +0100 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-04-09 15:49:24 +0100 |
| commit | fe13408831dce4bdae4911098d6079a097cae9e8 (patch) | |
| tree | 228bbb192b3a0f3417a4526c382b0a3ddf7e04ff /apps/web/components/dashboard | |
| parent | 994691b02515dfb579a5c3618631065bd76b9e4b (diff) | |
| download | karakeep-fe13408831dce4bdae4911098d6079a097cae9e8.tar.zst | |
feature(web): Allow uploading directly into lists/tags. Fixes #69
Diffstat (limited to 'apps/web/components/dashboard')
7 files changed, 49 insertions, 72 deletions
diff --git a/apps/web/components/dashboard/UploadDropzone.tsx b/apps/web/components/dashboard/UploadDropzone.tsx index 70e6483a..bd08d2cf 100644 --- a/apps/web/components/dashboard/UploadDropzone.tsx +++ b/apps/web/components/dashboard/UploadDropzone.tsx @@ -1,12 +1,12 @@ "use client"; import React, { useState } from "react"; -import { api } from "@/lib/trpc"; import { cn } from "@/lib/utils"; import { useMutation } from "@tanstack/react-query"; import { TRPCClientError } from "@trpc/client"; import DropZone from "react-dropzone"; +import { useCreateBookmarkWithPostHook } from "@hoarder/shared-react/hooks/bookmarks"; import { zUploadErrorSchema, zUploadResponseSchema, @@ -16,20 +16,15 @@ import LoadingSpinner from "../ui/spinner"; import { toast } from "../ui/use-toast"; function useUploadAsset({ onComplete }: { onComplete: () => void }) { - const invalidateAllBookmarks = - api.useUtils().bookmarks.getBookmarks.invalidate; - - const { mutateAsync: createBookmark } = - api.bookmarks.createBookmark.useMutation({ - onSuccess: () => { - toast({ description: "Bookmark uploaded" }); - invalidateAllBookmarks(); - onComplete(); - }, - onError: () => { - toast({ description: "Something went wrong", variant: "destructive" }); - }, - }); + const { mutateAsync: createBookmark } = useCreateBookmarkWithPostHook({ + onSuccess: () => { + toast({ description: "Bookmark uploaded" }); + onComplete(); + }, + onError: () => { + toast({ description: "Something went wrong", variant: "destructive" }); + }, + }); const { mutateAsync: runUpload } = useMutation({ mutationFn: async (file: File) => { diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx index e3cfc796..a8ec1ab5 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx @@ -1,6 +1,6 @@ "use client"; -import { useContext, useState } from "react"; +import { useState } from "react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -10,7 +10,6 @@ import { } from "@/components/ui/dropdown-menu"; import { useToast } from "@/components/ui/use-toast"; import { useClientConfig } from "@/lib/clientConfig"; -import { BookmarkListContext } from "@/lib/hooks/list-context"; import { Link, List, @@ -29,6 +28,7 @@ import { useUpdateBookmark, } from "@hoarder/shared-react/hooks//bookmarks"; 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"; @@ -48,7 +48,7 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { const [isTextEditorOpen, setTextEditorOpen] = useState(false); - const { listId } = useContext(BookmarkListContext); + const { listId } = useBookmarkGridContext() ?? {}; const onError = () => { toast({ diff --git a/apps/web/components/dashboard/bookmarks/BookmarkedTextEditor.tsx b/apps/web/components/dashboard/bookmarks/BookmarkedTextEditor.tsx index eb618474..294f2b5a 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkedTextEditor.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkedTextEditor.tsx @@ -21,7 +21,7 @@ export function BookmarkedTextEditor({ open, setOpen, }: { - bookmark?: ZBookmark; + bookmark: ZBookmark; open: boolean; setOpen: (open: boolean) => void; }) { @@ -30,30 +30,14 @@ export function BookmarkedTextEditor({ bookmark && bookmark.content.type == "text" ? bookmark.content.text : "", ); - const invalidateAllBookmarksCache = - api.useUtils().bookmarks.getBookmarks.invalidate; const invalidateOneBookmarksCache = api.useUtils().bookmarks.getBookmark.invalidate; - const { mutate: createBookmarkMutator, isPending: isCreationPending } = - api.bookmarks.createBookmark.useMutation({ - onSuccess: () => { - invalidateAllBookmarksCache(); - toast({ - description: "Note created!", - }); - setOpen(false); - setNoteText(""); - }, - onError: () => { - toast({ description: "Something went wrong", variant: "destructive" }); - }, - }); - const { mutate: updateBookmarkMutator, isPending: isUpdatePending } = + const { mutate: updateBookmarkMutator, isPending } = api.bookmarks.updateBookmarkText.useMutation({ onSuccess: () => { invalidateOneBookmarksCache({ - bookmarkId: bookmark!.id, + bookmarkId: bookmark.id, }); toast({ description: "Note updated!", @@ -64,20 +48,12 @@ export function BookmarkedTextEditor({ toast({ description: "Something went wrong", variant: "destructive" }); }, }); - const isPending = isCreationPending || isUpdatePending; const onSave = () => { - if (isNewBookmark) { - createBookmarkMutator({ - type: "text", - text: noteText, - }); - } else { - updateBookmarkMutator({ - bookmarkId: bookmark.id, - text: noteText, - }); - } + updateBookmarkMutator({ + bookmarkId: bookmark.id, + text: noteText, + }); }; return ( diff --git a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx index 048dab85..bace3435 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx @@ -1,5 +1,3 @@ -"use client"; - import { useMemo } from "react"; import { ActionButton } from "@/components/ui/action-button"; import tailwindConfig from "@/tailwind.config"; @@ -78,15 +76,16 @@ export default function BookmarksGrid({ {bookmarks.map((b) => renderBookmark(b))} </Masonry> {hasNextPage && ( - <ActionButton - ignoreDemoMode={true} - loading={isFetchingNextPage} - onClick={() => fetchNextPage()} - className="mx-auto w-min" - variant="ghost" - > - Load More - </ActionButton> + <div className="flex justify-center"> + <ActionButton + ignoreDemoMode={true} + loading={isFetchingNextPage} + onClick={() => fetchNextPage()} + variant="ghost" + > + Load More + </ActionButton> + </div> )} </> ); diff --git a/apps/web/components/dashboard/bookmarks/EditorCard.tsx b/apps/web/components/dashboard/bookmarks/EditorCard.tsx index b9e46a30..10ad1f13 100644 --- a/apps/web/components/dashboard/bookmarks/EditorCard.tsx +++ b/apps/web/components/dashboard/bookmarks/EditorCard.tsx @@ -7,12 +7,13 @@ import { Separator } from "@/components/ui/separator"; import { Textarea } from "@/components/ui/textarea"; import { toast } from "@/components/ui/use-toast"; import { useClientConfig } from "@/lib/clientConfig"; -import { api } from "@/lib/trpc"; import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; +import { useCreateBookmarkWithPostHook } from "@hoarder/shared-react/hooks/bookmarks"; + function useFocusOnKeyPress(inputRef: React.RefObject<HTMLTextAreaElement>) { useEffect(() => { function handleKeyPress(e: KeyboardEvent) { @@ -47,10 +48,8 @@ export default function EditorCard({ className }: { className?: string }) { useImperativeHandle(ref, () => inputRef.current); useFocusOnKeyPress(inputRef); - const invalidateBookmarksCache = api.useUtils().bookmarks.invalidate; - const { mutate, isPending } = api.bookmarks.createBookmark.useMutation({ + const { mutate, isPending } = useCreateBookmarkWithPostHook({ onSuccess: () => { - invalidateBookmarksCache(); form.reset(); }, onError: () => { diff --git a/apps/web/components/dashboard/bookmarks/TagsEditor.tsx b/apps/web/components/dashboard/bookmarks/TagsEditor.tsx index 91294b2e..c1a4cc70 100644 --- a/apps/web/components/dashboard/bookmarks/TagsEditor.tsx +++ b/apps/web/components/dashboard/bookmarks/TagsEditor.tsx @@ -8,6 +8,7 @@ import CreateableSelect from "react-select/creatable"; import type { ZBookmark } from "@hoarder/trpc/types/bookmarks"; import type { ZAttachedByEnum } from "@hoarder/trpc/types/tags"; +import { useUpdateBookmarkTags } from "@hoarder/shared-react/hooks/bookmarks"; interface EditableTag { attachedBy: ZAttachedByEnum; @@ -17,16 +18,12 @@ interface EditableTag { export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) { const demoMode = !!useClientConfig().demoMode; - const apiUtils = api.useUtils(); - const { mutate } = api.bookmarks.updateTags.useMutation({ + const { mutate } = useUpdateBookmarkTags({ onSuccess: () => { toast({ description: "Tags has been updated!", }); - apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id }); - apiUtils.tags.list.invalidate(); - apiUtils.tags.get.invalidate(); }, onError: () => { toast({ @@ -58,7 +55,7 @@ export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) { case "create-option": { mutate({ bookmarkId: bookmark.id, - attach: [{ tag: actionMeta.option.label }], + attach: [{ tagName: actionMeta.option.label }], detach: [], }); break; @@ -68,7 +65,10 @@ export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) { mutate({ bookmarkId: bookmark.id, attach: [ - { tag: actionMeta.option.label, tagId: actionMeta.option?.value }, + { + tagName: actionMeta.option.label, + tagId: actionMeta.option?.value, + }, ], detach: [], }); diff --git a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx index a344320e..fe69201c 100644 --- a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx @@ -1,11 +1,13 @@ "use client"; +import UploadDropzone from "@/components/dashboard/UploadDropzone"; import { api } from "@/lib/trpc"; import type { ZGetBookmarksRequest, ZGetBookmarksResponse, } from "@hoarder/trpc/types/bookmarks"; +import { BookmarkGridContextProvider } from "@hoarder/shared-react/hooks/bookmark-grid-context"; import BookmarksGrid from "./BookmarksGrid"; @@ -29,7 +31,7 @@ export default function UpdatableBookmarksGrid({ getNextPageParam: (lastPage) => lastPage.nextCursor, }); - return ( + const grid = ( <BookmarksGrid bookmarks={data!.pages.flatMap((b) => b.bookmarks)} hasNextPage={hasNextPage} @@ -38,4 +40,10 @@ export default function UpdatableBookmarksGrid({ showEditorCard={showEditorCard} /> ); + + return ( + <BookmarkGridContextProvider query={query}> + {showEditorCard ? <UploadDropzone>{grid}</UploadDropzone> : grid} + </BookmarkGridContextProvider> + ); } |
