Spaces:
Sleeping
Sleeping
File size: 4,099 Bytes
c16e487 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | "use client";
import { useTranslation } from "react-i18next";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { toast } from "sonner";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Form, FormControl, FormField, FormItem } from "@/components/ui/form";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import useKnowledge from "@/hooks/useKnowledge";
import { useSettingStore } from "@/store/setting";
type Props = {
open: boolean;
onClose: () => void;
};
const BUILD_MODE = process.env.NEXT_PUBLIC_BUILD_MODE;
const URLRegExp = /^https?:\/\/.+/;
const formSchema = z.object({
url: z.string(),
crawler: z.string(),
});
function Crawler({ open, onClose }: Props) {
const { t } = useTranslation();
const { getKnowledgeFromUrl } = useKnowledge();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: async () => {
const { crawler } = useSettingStore.getState();
return { url: "", crawler };
},
});
async function onSubmit(values: z.infer<typeof formSchema>) {
const settingStore = useSettingStore.getState();
const { url, crawler } = values;
if (URLRegExp.test(url)) {
onClose();
settingStore.update({ crawler });
await getKnowledgeFromUrl(url, crawler);
form.reset();
} else {
toast.error(t("knowledge.urlError"));
}
}
function handleClose(open: boolean) {
if (!open) onClose();
}
return (
<Dialog open={open} onOpenChange={handleClose}>
<DialogContent>
<DialogHeader>
<DialogTitle>{t("knowledge.webCrawler")}</DialogTitle>
<DialogDescription>{t("knowledge.webCrawlerTip")}</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="url"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
className="text-sm"
placeholder={t("knowledge.urlPlaceholder")}
{...field}
/>
</FormControl>
</FormItem>
)}
/>
<DialogFooter className="flex justify-between sm:justify-between flex-row">
<FormField
control={form.control}
name="crawler"
render={({ field }) => (
<FormItem>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<SelectTrigger className="w-36">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem
className={BUILD_MODE === "export" ? "hidden" : ""}
value="local"
>
{t("knowledge.localCrawler")}
</SelectItem>
<SelectItem value="jina">Jina Reader</SelectItem>
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
<div className="inline-flex gap-2">
<Button type="reset" variant="secondary">
{t("knowledge.clear")}
</Button>
<Button type="submit">{t("knowledge.fetch")}</Button>
</div>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}
export default Crawler;
|