diff --git a/src/app/(outerbase)/local-setting/page.tsx b/src/app/(outerbase)/local-setting-dialog.tsx similarity index 52% rename from src/app/(outerbase)/local-setting/page.tsx rename to src/app/(outerbase)/local-setting-dialog.tsx index 16602022..8d896681 100644 --- a/src/app/(outerbase)/local-setting/page.tsx +++ b/src/app/(outerbase)/local-setting-dialog.tsx @@ -1,15 +1,19 @@ -"use client"; +import { createDialog } from "@/components/create-dialog"; import LabelInput from "@/components/label-input"; import { Button } from "@/components/orbit/button"; +import { + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; import { getAgentFromLocalStorage, updateAgentFromLocalStorage, } from "@/lib/ai-agent-storage"; import { useCallback, useEffect, useState } from "react"; -import { toast } from "sonner"; -import NavigationLayout from "../nav-layout"; -export default function LocalSettingPage() { +export const localSettingDialog = createDialog(({ close }) => { const [token, setToken] = useState(""); useEffect(() => { @@ -30,34 +34,34 @@ export default function LocalSettingPage() { token, }); - toast("Setting saved!"); - }, [token]); + close(undefined); + }, [token, close]); return ( - -
-

Local Setting

+ <> + + Local Setting -

+ Bring your OpenAI token to enable the AI assistant. Your token is stored in localStorage. We do not store your token on our server. -

- - - -
- -
-
-
+ + + + + + + + + ); -} +}); diff --git a/src/app/(outerbase)/nav-profile.tsx b/src/app/(outerbase)/nav-profile.tsx index 8768e305..1ef1787f 100644 --- a/src/app/(outerbase)/nav-profile.tsx +++ b/src/app/(outerbase)/nav-profile.tsx @@ -17,6 +17,7 @@ import { import { useTheme } from "next-themes"; import { useRouter } from "next/navigation"; import { useCallback } from "react"; +import { localSettingDialog } from "./local-setting-dialog"; import { useSession } from "./session-provider"; export default function NavigationProfile() { @@ -88,7 +89,7 @@ export default function NavigationProfile() { { - router.push(`/local-setting`); + localSettingDialog.show({}).then().catch(); }} > Local Setting diff --git a/src/app/(theme)/embed/[driver]/page-client.tsx b/src/app/(theme)/embed/[driver]/page-client.tsx index 02244520..cfbe9832 100644 --- a/src/app/(theme)/embed/[driver]/page-client.tsx +++ b/src/app/(theme)/embed/[driver]/page-client.tsx @@ -13,6 +13,7 @@ import { } from "@/drivers/iframe-driver"; import ElectronSavedDocs from "@/drivers/saved-doc/electron-saved-doc"; import DoltExtension from "@/extensions/dolt"; +import LocalSettingSidebar from "@/extensions/local-setting-sidebar"; import { useAgentFromLocalStorage } from "@/lib/ai-agent-storage"; import { useSearchParams } from "next/navigation"; import { useEffect, useMemo } from "react"; @@ -79,9 +80,9 @@ function createDatabaseDriver(driverName: string) { function createEmbedExtensions(driverName: string) { if (driverName === "turso") { - return createSQLiteExtensions(); + return [...createSQLiteExtensions(), new LocalSettingSidebar()]; } else if (driverName === "sqlite" || driverName === "starbase") { - return createSQLiteExtensions(); + return [...createSQLiteExtensions(), new LocalSettingSidebar()]; } else if (driverName === "mysql") { return createMySQLExtensions(); } else if (driverName === "dolt") { diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index f8e397b9..9d56bc8a 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -1,8 +1,8 @@ "use client"; -import * as React from "react"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { Cross2Icon } from "@radix-ui/react-icons"; +import * as React from "react"; import { cn } from "@/lib/utils"; @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef< {children} - + Close @@ -88,7 +88,7 @@ const DialogTitle = React.forwardRef< (({ className, ...props }, ref) => ( )); @@ -110,13 +110,13 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, - DialogPortal, - DialogOverlay, - DialogTrigger, DialogClose, DialogContent, - DialogHeader, + DialogDescription, DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, DialogTitle, - DialogDescription, + DialogTrigger, }; diff --git a/src/extensions/local-setting-sidebar/index.tsx b/src/extensions/local-setting-sidebar/index.tsx new file mode 100644 index 00000000..2a842de8 --- /dev/null +++ b/src/extensions/local-setting-sidebar/index.tsx @@ -0,0 +1,19 @@ +import { localSettingDialog } from "@/app/(outerbase)/local-setting-dialog"; +import { StudioExtension } from "@/core/extension-base"; +import { StudioExtensionContext } from "@/core/extension-manager"; +import { MagicWand } from "@phosphor-icons/react"; + +export default class LocalSettingSidebar extends StudioExtension { + extensionName = "local-setting-sidebar"; + + init(studio: StudioExtensionContext): void { + studio.registerSidebar({ + key: "local-setting-sidebar", + name: "Local Settings", + icon: , + onClick: () => { + localSettingDialog.show({}).then().catch(); + }, + }); + } +} diff --git a/src/lib/ai-agent-storage.ts b/src/lib/ai-agent-storage.ts index 28fd34d0..cc3f391a 100644 --- a/src/lib/ai-agent-storage.ts +++ b/src/lib/ai-agent-storage.ts @@ -1,6 +1,7 @@ import { ChatGPTDriver } from "@/drivers/agent/chatgpt"; import { BaseDriver } from "@/drivers/base-driver"; import { useMemo } from "react"; +import useSWR, { mutate } from "swr"; export interface LocalAgentType { provider: "openai"; @@ -28,15 +29,19 @@ export function getAgentFromLocalStorage(): LocalAgentType | undefined { export function updateAgentFromLocalStorage(data: LocalAgentType) { localStorage.setItem("agent", JSON.stringify(data)); + mutate("/local-agent-setting", data); } export function useAgentFromLocalStorage(databaseDriver?: BaseDriver | null) { + const { data: agentConfig } = useSWR( + "/local-agent-setting", + getAgentFromLocalStorage + ); + return useMemo(() => { if (!databaseDriver) return undefined; - - const agentConfig = getAgentFromLocalStorage(); if (!agentConfig) return undefined; return new ChatGPTDriver(databaseDriver, agentConfig.token); - }, [databaseDriver]); + }, [databaseDriver, agentConfig]); }