diff options
Diffstat (limited to 'apps/web')
| -rw-r--r-- | apps/web/components/settings/AISettings.tsx | 108 | ||||
| -rw-r--r-- | apps/web/lib/clientConfig.tsx | 2 | ||||
| -rw-r--r-- | apps/web/lib/i18n/locales/en/translation.json | 5 | ||||
| -rw-r--r-- | apps/web/lib/userSettings.tsx | 2 |
4 files changed, 117 insertions, 0 deletions
diff --git a/apps/web/components/settings/AISettings.tsx b/apps/web/components/settings/AISettings.tsx index beaa93dc..d8adcb76 100644 --- a/apps/web/components/settings/AISettings.tsx +++ b/apps/web/components/settings/AISettings.tsx @@ -4,8 +4,10 @@ import { ActionButton } from "@/components/ui/action-button"; import { Form, FormControl, + FormDescription, FormField, FormItem, + FormLabel, FormMessage, } from "@/components/ui/form"; import { FullPageSpinner } from "@/components/ui/full-page-spinner"; @@ -18,15 +20,18 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { Switch } from "@/components/ui/switch"; import { toast } from "@/components/ui/use-toast"; import { useClientConfig } from "@/lib/clientConfig"; import { useTranslation } from "@/lib/i18n/client"; import { api } from "@/lib/trpc"; +import { useUserSettings } from "@/lib/userSettings"; import { zodResolver } from "@hookform/resolvers/zod"; import { Plus, Save, Trash2 } from "lucide-react"; import { useForm } from "react-hook-form"; import { z } from "zod"; +import { useUpdateUserSettings } from "@karakeep/shared-react/hooks/users"; import { buildImagePrompt, buildSummaryPromptUntruncated, @@ -37,6 +42,108 @@ import { ZPrompt, zUpdatePromptSchema, } from "@karakeep/shared/types/prompts"; +import { zUpdateUserSettingsSchema } from "@karakeep/shared/types/users"; + +export function AIPreferences() { + const { t } = useTranslation(); + const clientConfig = useClientConfig(); + const settings = useUserSettings(); + + const { mutate: updateSettings } = useUpdateUserSettings({ + onSuccess: () => { + toast({ + description: "Settings updated successfully!", + }); + }, + onError: () => { + toast({ + description: "Failed to update settings", + variant: "destructive", + }); + }, + }); + + const form = useForm<z.infer<typeof zUpdateUserSettingsSchema>>({ + resolver: zodResolver(zUpdateUserSettingsSchema), + values: settings + ? { + autoTaggingEnabled: settings.autoTaggingEnabled, + autoSummarizationEnabled: settings.autoSummarizationEnabled, + } + : undefined, + }); + + const showAutoTagging = clientConfig.inference.enableAutoTagging; + const showAutoSummarization = clientConfig.inference.enableAutoSummarization; + + // Don't show the section if neither feature is enabled on the server + if (!showAutoTagging && !showAutoSummarization) { + return null; + } + + return ( + <div className="mt-2 flex flex-col gap-2"> + <p className="mb-1 text-xs italic text-muted-foreground"> + {t("settings.ai.ai_preferences_description")} + </p> + <Form {...form}> + <form className="space-y-4"> + {showAutoTagging && ( + <FormField + control={form.control} + name="autoTaggingEnabled" + render={({ field }) => ( + <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3"> + <div className="space-y-0.5"> + <FormLabel>{t("settings.ai.auto_tagging")}</FormLabel> + <FormDescription> + {t("settings.ai.auto_tagging_description")} + </FormDescription> + </div> + <FormControl> + <Switch + checked={field.value ?? true} + onCheckedChange={(checked) => { + field.onChange(checked); + updateSettings({ autoTaggingEnabled: checked }); + }} + /> + </FormControl> + </FormItem> + )} + /> + )} + + {showAutoSummarization && ( + <FormField + control={form.control} + name="autoSummarizationEnabled" + render={({ field }) => ( + <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3"> + <div className="space-y-0.5"> + <FormLabel>{t("settings.ai.auto_summarization")}</FormLabel> + <FormDescription> + {t("settings.ai.auto_summarization_description")} + </FormDescription> + </div> + <FormControl> + <Switch + checked={field.value ?? true} + onCheckedChange={(checked) => { + field.onChange(checked); + updateSettings({ autoSummarizationEnabled: checked }); + }} + /> + </FormControl> + </FormItem> + )} + /> + )} + </form> + </Form> + </div> + ); +} export function PromptEditor() { const { t } = useTranslation(); @@ -353,6 +460,7 @@ export default function AISettings() { <div className="w-full text-2xl font-medium sm:w-1/3"> {t("settings.ai.ai_settings")} </div> + <AIPreferences /> <TaggingRules /> </div> </div> diff --git a/apps/web/lib/clientConfig.tsx b/apps/web/lib/clientConfig.tsx index 9331a7af..ab367be0 100644 --- a/apps/web/lib/clientConfig.tsx +++ b/apps/web/lib/clientConfig.tsx @@ -14,6 +14,8 @@ export const ClientConfigCtx = createContext<ClientConfig>({ inference: { isConfigured: false, inferredTagLang: "english", + enableAutoTagging: false, + enableAutoSummarization: false, }, serverVersion: undefined, disableNewReleaseCheck: true, diff --git a/apps/web/lib/i18n/locales/en/translation.json b/apps/web/lib/i18n/locales/en/translation.json index d05ca702..08dc33e4 100644 --- a/apps/web/lib/i18n/locales/en/translation.json +++ b/apps/web/lib/i18n/locales/en/translation.json @@ -222,6 +222,11 @@ }, "ai": { "ai_settings": "AI Settings", + "ai_preferences_description": "Control which AI features are enabled for your account.", + "auto_tagging": "Auto-tagging", + "auto_tagging_description": "Automatically generate tags for your bookmarks using AI.", + "auto_summarization": "Auto-summarization", + "auto_summarization_description": "Automatically generate summaries for your bookmarks using AI.", "tagging_rules": "Tagging Rules", "tagging_rule_description": "Prompts that you add here will be included as rules to the model during tag generation. You can view the final prompts in the prompt preview section.", "prompt_preview": "Prompt Preview", diff --git a/apps/web/lib/userSettings.tsx b/apps/web/lib/userSettings.tsx index 2bb7c8a5..d35c9e56 100644 --- a/apps/web/lib/userSettings.tsx +++ b/apps/web/lib/userSettings.tsx @@ -16,6 +16,8 @@ export const UserSettingsContext = createContext<ZUserSettings>({ readerFontSize: null, readerLineHeight: null, readerFontFamily: null, + autoTaggingEnabled: null, + autoSummarizationEnabled: null, }); export function UserSettingsContextProvider({ |
