diff options
| author | MohamedBassem <me@mbassem.com> | 2024-04-26 11:59:20 +0100 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-04-26 11:59:20 +0100 |
| commit | 5aabbec42afcabce826fff14a667a2ca3b0b701f (patch) | |
| tree | d4191e153c977a244f0223baa15d5640e1df06a6 | |
| parent | 4efcac7e32b1471078142ece8c7d8db3ebffa443 (diff) | |
| download | karakeep-5aabbec42afcabce826fff14a667a2ca3b0b701f.tar.zst | |
fix: Change tag listing API to return unused tags
| -rw-r--r-- | apps/web/components/dashboard/tags/AllTagsView.tsx | 25 | ||||
| -rw-r--r-- | packages/trpc/routers/tags.ts | 59 |
2 files changed, 52 insertions, 32 deletions
diff --git a/apps/web/components/dashboard/tags/AllTagsView.tsx b/apps/web/components/dashboard/tags/AllTagsView.tsx index 1f9f2dba..ce780a2f 100644 --- a/apps/web/components/dashboard/tags/AllTagsView.tsx +++ b/apps/web/components/dashboard/tags/AllTagsView.tsx @@ -2,6 +2,11 @@ import Link from "next/link"; import { Button } from "@/components/ui/button"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; import InfoTooltip from "@/components/ui/info-tooltip"; import { Separator } from "@/components/ui/separator"; import { api } from "@/lib/trpc"; @@ -54,7 +59,8 @@ export default function AllTagsView({ const allTags = data.tags.sort((a, b) => b.count - a.count); const humanTags = allTags.filter((t) => (t.countAttachedBy.human ?? 0) > 0); - const aiTags = allTags.filter((t) => (t.countAttachedBy.human ?? 0) == 0); + const aiTags = allTags.filter((t) => (t.countAttachedBy.ai ?? 0) > 0); + const emptyTags = allTags.filter((t) => t.count === 0); const tagsToPill = (tags: typeof allTags) => { let tagPill; @@ -86,6 +92,23 @@ export default function AllTagsView({ </InfoTooltip> </span> <div className="flex flex-wrap gap-3">{tagsToPill(aiTags)}</div> + + <Separator /> + + <span className="flex items-center gap-2"> + <p className="text-lg">Unused Tags</p> + <InfoTooltip size={15} className="my-auto" variant="explain"> + <p>Tags that are not attached to any bookmarks</p> + </InfoTooltip> + </span> + <Collapsible> + <CollapsibleTrigger className="pb-2"> + <Button variant="link">Show {emptyTags.length} unused tags</Button> + </CollapsibleTrigger> + <CollapsibleContent> + <div className="flex flex-wrap gap-3">{tagsToPill(emptyTags)}</div> + </CollapsibleContent> + </Collapsible> </> ); } diff --git a/packages/trpc/routers/tags.ts b/packages/trpc/routers/tags.ts index 2e6efa8e..4806079a 100644 --- a/packages/trpc/routers/tags.ts +++ b/packages/trpc/routers/tags.ts @@ -1,5 +1,5 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server"; -import { and, count, eq, inArray } from "drizzle-orm"; +import { and, eq, inArray } from "drizzle-orm"; import { z } from "zod"; import type { ZAttachedByEnum } from "@hoarder/shared/types/tags"; @@ -306,36 +306,33 @@ export const tagsAppRouter = router({ }), ) .query(async ({ ctx }) => { - const res = await ctx.db - .select({ - id: tagsOnBookmarks.tagId, - name: bookmarkTags.name, - attachedBy: tagsOnBookmarks.attachedBy, - count: count(), - }) - .from(tagsOnBookmarks) - .groupBy(tagsOnBookmarks.tagId, tagsOnBookmarks.attachedBy) - .innerJoin(bookmarkTags, eq(bookmarkTags.id, tagsOnBookmarks.tagId)) - .where(eq(bookmarkTags.userId, ctx.user.id)); - - const tags = res.reduce< - Record<string, z.infer<typeof zGetTagResponseSchema>> - >((acc, row) => { - if (!(row.id in acc)) { - acc[row.id] = { - id: row.id, - name: row.name, - count: 0, - countAttachedBy: { - ai: 0, - human: 0, + const tags = await ctx.db.query.bookmarkTags.findMany({ + where: eq(bookmarkTags.userId, ctx.user.id), + with: { + tagsOnBookmarks: { + columns: { + attachedBy: true, }, - }; - } - acc[row.id].count += row.count; - acc[row.id].countAttachedBy[row.attachedBy]! += row.count; - return acc; - }, {}); - return { tags: Object.values(tags) }; + }, + }, + }); + + const resp = tags.map(({ tagsOnBookmarks, ...rest }) => ({ + ...rest, + count: tagsOnBookmarks.length, + countAttachedBy: tagsOnBookmarks.reduce< + Record<ZAttachedByEnum, number> + >( + (acc, curr) => { + if (curr.attachedBy) { + acc[curr.attachedBy]++; + } + return acc; + }, + { ai: 0, human: 0 }, + ), + })); + + return { tags: resp }; }), }); |
