aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-04-06 02:13:47 +0100
committerMohamedBassem <me@mbassem.com>2024-04-06 02:13:47 +0100
commit044659fd1ba2082491eed713dc72bafd696f0439 (patch)
treed597da0ae1165e6a2dc50387121ea079a607b8a3 /apps
parent4cf990816817c009a512356373fdb1c4baa5e63b (diff)
downloadkarakeep-044659fd1ba2082491eed713dc72bafd696f0439.tar.zst
fix: Refresh the all tags page automatically when a tag is modified
Diffstat (limited to 'apps')
-rw-r--r--apps/web/app/dashboard/tags/page.tsx53
-rw-r--r--apps/web/components/dashboard/bookmarks/TagsEditor.tsx8
-rw-r--r--apps/web/components/dashboard/tags/AllTagsView.tsx67
3 files changed, 74 insertions, 54 deletions
diff --git a/apps/web/app/dashboard/tags/page.tsx b/apps/web/app/dashboard/tags/page.tsx
index 9f5038e7..6caea513 100644
--- a/apps/web/app/dashboard/tags/page.tsx
+++ b/apps/web/app/dashboard/tags/page.tsx
@@ -1,62 +1,15 @@
-import Link from "next/link";
-import InfoTooltip from "@/components/ui/info-tooltip";
+import AllTagsView from "@/components/dashboard/tags/AllTagsView";
import { Separator } from "@/components/ui/separator";
import { api } from "@/server/api/client";
-function TagPill({ name, count }: { name: string; count: number }) {
- return (
- <Link
- className="flex gap-2 rounded-md border border-border bg-background px-2 py-1 text-foreground hover:bg-foreground hover:text-background"
- href={`/dashboard/tags/${name}`}
- >
- {name} <Separator orientation="vertical" /> {count}
- </Link>
- );
-}
-
export default async function TagsPage() {
- let allTags = (await api.tags.list()).tags;
-
- // Sort tags by usage desc
- allTags = allTags.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 tagsToPill = (tags: typeof allTags) => {
- let tagPill;
- if (tags.length) {
- tagPill = tags.map((t) => (
- <TagPill key={t.id} name={t.name} count={t.count} />
- ));
- } else {
- tagPill = "No Tags";
- }
- return tagPill;
- };
+ const allTags = (await api.tags.list()).tags;
return (
<div className="space-y-4 rounded-md border bg-background p-4">
<span className="text-2xl">All Tags</span>
<Separator />
-
- <span className="flex items-center gap-2">
- <p className="text-lg">Your Tags</p>
- <InfoTooltip size={15} className="my-auto" variant="explain">
- <p>Tags that were attached at least once by you</p>
- </InfoTooltip>
- </span>
- <div className="flex flex-wrap gap-3">{tagsToPill(humanTags)}</div>
-
- <Separator />
-
- <span className="flex items-center gap-2">
- <p className="text-lg">AI Tags</p>
- <InfoTooltip size={15} className="my-auto" variant="explain">
- <p>Tags that were only attached automatically (by AI)</p>
- </InfoTooltip>
- </span>
- <div className="flex flex-wrap gap-3">{tagsToPill(aiTags)}</div>
+ <AllTagsView initialData={allTags} />
</div>
);
}
diff --git a/apps/web/components/dashboard/bookmarks/TagsEditor.tsx b/apps/web/components/dashboard/bookmarks/TagsEditor.tsx
index ecd6d29c..91294b2e 100644
--- a/apps/web/components/dashboard/bookmarks/TagsEditor.tsx
+++ b/apps/web/components/dashboard/bookmarks/TagsEditor.tsx
@@ -17,16 +17,16 @@ interface EditableTag {
export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) {
const demoMode = !!useClientConfig().demoMode;
- const bookmarkInvalidationFunction =
- api.useUtils().bookmarks.getBookmark.invalidate;
+ const apiUtils = api.useUtils();
const { mutate } = api.bookmarks.updateTags.useMutation({
onSuccess: () => {
toast({
description: "Tags has been updated!",
});
- bookmarkInvalidationFunction({ bookmarkId: bookmark.id });
- // TODO(bug) Invalidate the tag views as well
+ apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id });
+ apiUtils.tags.list.invalidate();
+ apiUtils.tags.get.invalidate();
},
onError: () => {
toast({
diff --git a/apps/web/components/dashboard/tags/AllTagsView.tsx b/apps/web/components/dashboard/tags/AllTagsView.tsx
new file mode 100644
index 00000000..0f9ee823
--- /dev/null
+++ b/apps/web/components/dashboard/tags/AllTagsView.tsx
@@ -0,0 +1,67 @@
+"use client";
+
+import Link from "next/link";
+import InfoTooltip from "@/components/ui/info-tooltip";
+import { Separator } from "@/components/ui/separator";
+import { api } from "@/lib/trpc";
+
+import type { ZGetTagResponse } from "@hoarder/trpc/types/tags";
+
+function TagPill({ name, count }: { name: string; count: number }) {
+ return (
+ <Link
+ className="flex gap-2 rounded-md border border-border bg-background px-2 py-1 text-foreground hover:bg-foreground hover:text-background"
+ href={`/dashboard/tags/${name}`}
+ >
+ {name} <Separator orientation="vertical" /> {count}
+ </Link>
+ );
+}
+
+export default function AllTagsView({
+ initialData,
+}: {
+ initialData: ZGetTagResponse[];
+}) {
+ const { data } = api.tags.list.useQuery(undefined, {
+ initialData: { tags: initialData },
+ });
+ // Sort tags by usage desc
+ 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 tagsToPill = (tags: typeof allTags) => {
+ let tagPill;
+ if (tags.length) {
+ tagPill = tags.map((t) => (
+ <TagPill key={t.id} name={t.name} count={t.count} />
+ ));
+ } else {
+ tagPill = "No Tags";
+ }
+ return tagPill;
+ };
+ return (
+ <>
+ <span className="flex items-center gap-2">
+ <p className="text-lg">Your Tags</p>
+ <InfoTooltip size={15} className="my-auto" variant="explain">
+ <p>Tags that were attached at least once by you</p>
+ </InfoTooltip>
+ </span>
+ <div className="flex flex-wrap gap-3">{tagsToPill(humanTags)}</div>
+
+ <Separator />
+
+ <span className="flex items-center gap-2">
+ <p className="text-lg">AI Tags</p>
+ <InfoTooltip size={15} className="my-auto" variant="explain">
+ <p>Tags that were only attached automatically (by AI)</p>
+ </InfoTooltip>
+ </span>
+ <div className="flex flex-wrap gap-3">{tagsToPill(aiTags)}</div>
+ </>
+ );
+}