From 5ecdc36b7d60aa66b49e01e9fec8ba61ad537376 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Thu, 2 Jan 2025 13:00:58 +0200 Subject: feat: Add support for smart lists (#802) * feat: Add support for smart lists * i18n * Fix update list endpoint * Add a test for smart lists * Add header to the query explainer * Hide remove from lists in the smart context list * Add proper validation to list form --------- Co-authored-by: Deepak Kapoor <41769111+orthdron@users.noreply.github.com> --- .../components/dashboard/lists/EditListModal.tsx | 119 +++++++++++++++++---- 1 file changed, 96 insertions(+), 23 deletions(-) (limited to 'apps/web/components/dashboard/lists/EditListModal.tsx') diff --git a/apps/web/components/dashboard/lists/EditListModal.tsx b/apps/web/components/dashboard/lists/EditListModal.tsx index d66d7096..98bb19be 100644 --- a/apps/web/components/dashboard/lists/EditListModal.tsx +++ b/apps/web/components/dashboard/lists/EditListModal.tsx @@ -25,6 +25,13 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { toast } from "@/components/ui/use-toast"; import { useTranslation } from "@/lib/i18n/client"; import data from "@emoji-mart/data"; @@ -38,7 +45,10 @@ import { useCreateBookmarkList, useEditBookmarkList, } from "@hoarder/shared-react/hooks/lists"; -import { ZBookmarkList } from "@hoarder/shared/types/lists"; +import { + ZBookmarkList, + zNewBookmarkListSchema, +} from "@hoarder/shared/types/lists"; import { BookmarkListSelector } from "./BookmarkListSelector"; @@ -46,13 +56,13 @@ export function EditListModal({ open: userOpen, setOpen: userSetOpen, list, - parent, + prefill, children, }: { open?: boolean; setOpen?: (v: boolean) => void; list?: ZBookmarkList; - parent?: ZBookmarkList; + prefill?: Partial>; children?: React.ReactNode; }) { const { t } = useTranslation(); @@ -64,17 +74,14 @@ export function EditListModal({ throw new Error("You must provide both open and setOpen or neither"); } const [customOpen, customSetOpen] = useState(false); - const formSchema = z.object({ - name: z.string(), - icon: z.string(), - parentId: z.string().nullish(), - }); - const form = useForm>({ - resolver: zodResolver(formSchema), + const form = useForm>({ + resolver: zodResolver(zNewBookmarkListSchema), defaultValues: { - name: list?.name ?? "", - icon: list?.icon ?? "🚀", - parentId: list?.parentId ?? parent?.id, + name: list?.name ?? prefill?.name ?? "", + icon: list?.icon ?? prefill?.icon ?? "🚀", + parentId: list?.parentId ?? prefill?.parentId, + type: list?.type ?? prefill?.type ?? "manual", + query: list?.query ?? prefill?.query ?? undefined, }, }); const [open, setOpen] = [ @@ -84,9 +91,11 @@ export function EditListModal({ useEffect(() => { form.reset({ - name: list?.name ?? "", - icon: list?.icon ?? "🚀", - parentId: list?.parentId ?? parent?.id, + name: list?.name ?? prefill?.name ?? "", + icon: list?.icon ?? prefill?.icon ?? "🚀", + parentId: list?.parentId ?? prefill?.parentId, + type: list?.type ?? prefill?.type ?? "manual", + query: list?.query ?? prefill?.query ?? undefined, }); }, [open]); @@ -154,14 +163,24 @@ export function EditListModal({ } }, }); + const listType = form.watch("type"); + + useEffect(() => { + if (listType !== "smart") { + form.resetField("query"); + } + }, [listType]); const isEdit = !!list; const isPending = isCreating || isEditing; - const onSubmit = form.handleSubmit((value: z.infer) => { - value.parentId = value.parentId === "" ? null : value.parentId; - isEdit ? editList({ ...value, listId: list.id }) : createList(value); - }); + const onSubmit = form.handleSubmit( + (value: z.infer) => { + value.parentId = value.parentId === "" ? null : value.parentId; + value.query = value.type === "smart" ? value.query : undefined; + isEdit ? editList({ ...value, listId: list.id }) : createList(value); + }, + ); return (
- {isEdit ? "Edit" : "New"} List + + {isEdit ? t("lists.edit_list") : t("lists.new_list")} +
{ return ( - Parent + {t("lists.parent_list")}