aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components/dashboard/lists/AllListsView.tsx
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-04-19 00:09:27 +0100
committerGitHub <noreply@github.com>2024-04-19 00:09:27 +0100
commite0999f701cd1834c3d940113cd8dd5247c5fe95f (patch)
treec4169a564ecd3f933e711bcc8ef7db20532174ea /apps/web/components/dashboard/lists/AllListsView.tsx
parentdeba31ee010f785a9739fd4df8a64a3056c9593d (diff)
downloadkarakeep-e0999f701cd1834c3d940113cd8dd5247c5fe95f.tar.zst
feature: Nested lists (#110). Fixes #62
* feature: Add support for nested lists * prevent moving the parent to a subtree
Diffstat (limited to 'apps/web/components/dashboard/lists/AllListsView.tsx')
-rw-r--r--apps/web/components/dashboard/lists/AllListsView.tsx113
1 files changed, 74 insertions, 39 deletions
diff --git a/apps/web/components/dashboard/lists/AllListsView.tsx b/apps/web/components/dashboard/lists/AllListsView.tsx
index 00e76a23..308af5db 100644
--- a/apps/web/components/dashboard/lists/AllListsView.tsx
+++ b/apps/web/components/dashboard/lists/AllListsView.tsx
@@ -1,31 +1,59 @@
"use client";
import Link from "next/link";
-import { useNewListModal } from "@/components/dashboard/sidebar/NewListModal";
+import { EditListModal } from "@/components/dashboard/lists/EditListModal";
import { Button } from "@/components/ui/button";
-import { api } from "@/lib/trpc";
-import { keepPreviousData } from "@tanstack/react-query";
-import { Plus } from "lucide-react";
+import { CollapsibleTriggerChevron } from "@/components/ui/collapsible";
+import { MoreHorizontal, Plus } from "lucide-react";
import type { ZBookmarkList } from "@hoarder/shared/types/lists";
+import { CollapsibleBookmarkLists } from "./CollapsibleBookmarkLists";
+import { ListOptions } from "./ListOptions";
+
function ListItem({
name,
icon,
path,
+ style,
+ list,
+ open,
+ collapsible,
}: {
name: string;
icon: string;
path: string;
+ style?: React.CSSProperties;
+ list?: ZBookmarkList;
+ open?: boolean;
+ collapsible: boolean;
}) {
return (
- <Link href={path}>
- <div className="rounded-md border border-border bg-background px-4 py-2 text-lg">
- <p className="text-nowrap">
- {icon} {name}
- </p>
- </div>
- </Link>
+ <li
+ className="my-2 flex items-center justify-between rounded-md border border-border p-2 hover:bg-accent/50"
+ style={style}
+ >
+ <span className="flex flex-1 items-center gap-1">
+ {collapsible && (
+ <CollapsibleTriggerChevron className="size-5" open={open ?? false} />
+ )}
+ <Link href={path} className="flex flex-1 gap-1">
+ <p className="text-nowrap text-lg">
+ {icon} {name}
+ </p>
+ </Link>
+ </span>
+ {list && (
+ <ListOptions list={list}>
+ <Button
+ className="flex h-full items-center justify-end"
+ variant="ghost"
+ >
+ <MoreHorizontal />
+ </Button>
+ </ListOptions>
+ )}
+ </li>
);
}
@@ -34,34 +62,41 @@ export default function AllListsView({
}: {
initialData: ZBookmarkList[];
}) {
- const { setOpen: setIsNewListModalOpen } = useNewListModal();
- let { data: lists } = api.lists.list.useQuery(undefined, {
- initialData: { lists: initialData },
- placeholderData: keepPreviousData,
- });
-
- // TODO: This seems to be a bug in react query
- lists ||= { lists: initialData };
-
return (
- <div className="flex flex-col flex-wrap gap-2 md:flex-row">
- <Button
- className="my-auto flex h-full"
- onClick={() => setIsNewListModalOpen(true)}
- >
- <Plus />
- <span className="my-auto">New List</span>
- </Button>
- <ListItem name="Favourites" icon="⭐️" path={`/dashboard/favourites`} />
- <ListItem name="Archive" icon="🗄️" path={`/dashboard/archive`} />
- {lists.lists.map((l) => (
- <ListItem
- key={l.id}
- name={l.name}
- icon={l.icon}
- path={`/dashboard/lists/${l.id}`}
- />
- ))}
- </div>
+ <ul>
+ <EditListModal>
+ <Button className="mb-2 flex h-full w-full items-center">
+ <Plus />
+ <span>New List</span>
+ </Button>
+ </EditListModal>
+ <ListItem
+ collapsible={false}
+ name="Favourites"
+ icon="⭐️"
+ path={`/dashboard/favourites`}
+ />
+ <ListItem
+ collapsible={false}
+ name="Archive"
+ icon="🗄️"
+ path={`/dashboard/archive`}
+ />
+ <CollapsibleBookmarkLists
+ initialData={initialData}
+ render={({ item, level, open }) => (
+ <ListItem
+ key={item.item.id}
+ name={item.item.name}
+ icon={item.item.icon}
+ list={item.item}
+ path={`/dashboard/lists/${item.item.id}`}
+ collapsible={item.children.length > 0}
+ open={open}
+ style={{ marginLeft: `${level * 1}rem` }}
+ />
+ )}
+ />
+ </ul>
);
}