From 4791a534b2561071a01708775b23408f78d56dc8 Mon Sep 17 00:00:00 2001 From: kamtschatka Date: Sun, 13 Oct 2024 14:01:19 +0200 Subject: [PATCH] fix(web): Fix slowness in loading the all tags UI. Fixes #382 (#390) * long delay when selecting tags in UI #382 improved performance by not handling hover in css also rendering the draggable div only if draggable mode is active * updated the code to reuse the DeleteTagConfirmationDialog to improve performance and fix the tag deletion * some fixes --------- Co-authored-by: MohamedBassem --- .../components/dashboard/tags/AllTagsView.tsx | 27 ++++++++ .../tags/DeleteTagConfirmationDialog.tsx | 6 +- .../web/components/dashboard/tags/TagPill.tsx | 66 ++++++++++++------- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/apps/web/components/dashboard/tags/AllTagsView.tsx b/apps/web/components/dashboard/tags/AllTagsView.tsx index 7b81ed72..f6a42ef2 100644 --- a/apps/web/components/dashboard/tags/AllTagsView.tsx +++ b/apps/web/components/dashboard/tags/AllTagsView.tsx @@ -19,6 +19,7 @@ import { ArrowDownAZ, Combine } from "lucide-react"; import type { ZGetTagResponse } from "@hoarder/shared/types/tags"; import { useDeleteUnusedTags } from "@hoarder/shared-react/hooks/tags"; +import DeleteTagConfirmationDialog from "./DeleteTagConfirmationDialog"; import { TagPill } from "./TagPill"; function DeleteAllUnusedTags({ numUnusedTags }: { numUnusedTags: number }) { @@ -71,9 +72,22 @@ export default function AllTagsView({ }: { initialData: ZGetTagResponse[]; }) { + interface Tag { + id: string; + name: string; + } + const [draggingEnabled, setDraggingEnabled] = React.useState(false); const [sortByName, setSortByName] = React.useState(false); + const [isDialogOpen, setIsDialogOpen] = React.useState(false); + const [selectedTag, setSelectedTag] = React.useState(null); + + const handleOpenDialog = (tag: Tag) => { + setSelectedTag(tag); + setIsDialogOpen(true); + }; + function toggleSortByName(): void { setSortByName(!sortByName); } @@ -104,6 +118,7 @@ export default function AllTagsView({ name={t.name} count={t.count} isDraggable={draggingEnabled} + onOpenDialog={handleOpenDialog} /> ))} @@ -115,6 +130,18 @@ export default function AllTagsView({ }; return ( <> + {selectedTag && ( + { + if (!o) { + setSelectedTag(null); + } + setIsDialogOpen(o); + }} + /> + )}
void; }) { @@ -55,8 +53,6 @@ export default function DeleteTagConfirmationDialog({ Delete )} - > - {children} - + /> ); } diff --git a/apps/web/components/dashboard/tags/TagPill.tsx b/apps/web/components/dashboard/tags/TagPill.tsx index 88b88b52..ff17f224 100644 --- a/apps/web/components/dashboard/tags/TagPill.tsx +++ b/apps/web/components/dashboard/tags/TagPill.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; @@ -9,19 +9,24 @@ import Draggable from "react-draggable"; import { useMergeTag } from "@hoarder/shared-react/hooks/tags"; -import DeleteTagConfirmationDialog from "./DeleteTagConfirmationDialog"; - export function TagPill({ id, name, count, isDraggable, + onOpenDialog, }: { id: string; name: string; count: number; isDraggable: boolean; + onOpenDialog: (tag: { id: string; name: string }) => void; }) { + const [isHovered, setIsHovered] = useState(false); + + const handleMouseOver = () => setIsHovered(true); + const handleMouseOut = () => setIsHovered(false); + const { mutate: mergeTag } = useMergeTag({ onSuccess: () => { toast({ @@ -62,6 +67,39 @@ export function TagPill({ }, ); + const pill = ( +
+ + {name} {count} + + + {isHovered && !isDraggable && ( + + )} +
+ ); + if (!isDraggable) { + return pill; + } return ( -
- - {name} {count} - - - - - -
+ {pill}
); }