205 lines
5.9 KiB
TypeScript
205 lines
5.9 KiB
TypeScript
"use client"
|
||
|
||
import { usePathname } from "next/navigation"
|
||
|
||
import { Dashboard } from "@/components/ui/dashboard"
|
||
import { ChatbotUIContext } from "@/context/context"
|
||
import { getAssistantWorkspacesByWorkspaceId } from "@/db/assistants"
|
||
import { getChatsByWorkspaceId } from "@/db/chats"
|
||
import { getCollectionWorkspacesByWorkspaceId } from "@/db/collections"
|
||
import { getFileWorkspacesByWorkspaceId } from "@/db/files"
|
||
import { getFoldersByWorkspaceId } from "@/db/folders"
|
||
import { getModelWorkspacesByWorkspaceId } from "@/db/models"
|
||
import { getPresetWorkspacesByWorkspaceId } from "@/db/presets"
|
||
import { getPromptWorkspacesByWorkspaceId } from "@/db/prompts"
|
||
import { getAssistantImageFromStorage } from "@/db/storage/assistant-images"
|
||
import { getToolWorkspacesByWorkspaceId } from "@/db/tools"
|
||
import { getWorkspaceById } from "@/db/workspaces"
|
||
import { convertBlobToBase64 } from "@/lib/blob-to-b64"
|
||
import { supabase } from "@/lib/supabase/browser-client"
|
||
import { LLMID } from "@/types"
|
||
import { useParams, useRouter, useSearchParams } from "next/navigation"
|
||
import { ReactNode, useContext, useEffect, useState } from "react"
|
||
import Loading from "../loading"
|
||
import { useTranslation } from 'react-i18next'
|
||
|
||
interface WorkspaceLayoutProps {
|
||
children: ReactNode
|
||
}
|
||
|
||
export default function WorkspaceLayout({ children }: WorkspaceLayoutProps) {
|
||
const { t } = useTranslation()
|
||
|
||
const router = useRouter()
|
||
const pathname = usePathname() // 获取当前路径
|
||
|
||
// 提取当前路径中的 locale 部分
|
||
//const match = pathname.match(/^\/([a-z]{2})(\/|$)/)
|
||
const match = pathname ? pathname.match(/^\/([a-z]{2})(\/|$)/) : null;
|
||
const locale = match ? match[1] : "en"
|
||
|
||
|
||
const params = useParams()
|
||
const searchParams = useSearchParams()
|
||
const workspaceId = params.workspaceid as string
|
||
|
||
const {
|
||
setChatSettings,
|
||
setAssistants,
|
||
setAssistantImages,
|
||
setChats,
|
||
setCollections,
|
||
setFolders,
|
||
setFiles,
|
||
setPresets,
|
||
setPrompts,
|
||
setTools,
|
||
setModels,
|
||
selectedWorkspace,
|
||
setSelectedWorkspace,
|
||
setSelectedChat,
|
||
setChatMessages,
|
||
setUserInput,
|
||
setIsGenerating,
|
||
setFirstTokenReceived,
|
||
setChatFiles,
|
||
setChatImages,
|
||
setNewMessageFiles,
|
||
setNewMessageImages,
|
||
setShowFilesDisplay
|
||
} = useContext(ChatbotUIContext)
|
||
|
||
const [loading, setLoading] = useState(true)
|
||
|
||
|
||
useEffect(() => {
|
||
;(async () => {
|
||
const session = (await supabase.auth.getSession()).data.session
|
||
|
||
if (!session) {
|
||
// 跳转到带有 locale 的登录页面
|
||
return router.push(`/${locale}/login`)
|
||
} else {
|
||
await fetchWorkspaceData(workspaceId) // 如果有session,则加载工作区数据
|
||
}
|
||
})()
|
||
}, [])
|
||
|
||
|
||
useEffect(() => {
|
||
;(async () => await fetchWorkspaceData(workspaceId))()
|
||
|
||
setUserInput("")
|
||
setChatMessages([])
|
||
setSelectedChat(null)
|
||
|
||
setIsGenerating(false)
|
||
setFirstTokenReceived(false)
|
||
|
||
setChatFiles([])
|
||
setChatImages([])
|
||
setNewMessageFiles([])
|
||
setNewMessageImages([])
|
||
setShowFilesDisplay(false)
|
||
}, [workspaceId])
|
||
|
||
const fetchWorkspaceData = async (workspaceId: string) => {
|
||
setLoading(true)
|
||
|
||
const workspace = await getWorkspaceById(workspaceId)
|
||
setSelectedWorkspace(workspace)
|
||
|
||
const assistantData = await getAssistantWorkspacesByWorkspaceId(workspaceId)
|
||
setAssistants(assistantData.assistants)
|
||
|
||
for (const assistant of assistantData.assistants) {
|
||
let url = ""
|
||
|
||
if (assistant.image_path) {
|
||
url = (await getAssistantImageFromStorage(assistant.image_path)) || ""
|
||
}
|
||
|
||
if (url) {
|
||
const response = await fetch(url)
|
||
const blob = await response.blob()
|
||
const base64 = await convertBlobToBase64(blob)
|
||
|
||
setAssistantImages(prev => [
|
||
...prev,
|
||
{
|
||
assistantId: assistant.id,
|
||
path: assistant.image_path,
|
||
base64,
|
||
url
|
||
}
|
||
])
|
||
} else {
|
||
setAssistantImages(prev => [
|
||
...prev,
|
||
{
|
||
assistantId: assistant.id,
|
||
path: assistant.image_path,
|
||
base64: "",
|
||
url
|
||
}
|
||
])
|
||
}
|
||
}
|
||
|
||
const chats = await getChatsByWorkspaceId(workspaceId)
|
||
setChats(chats)
|
||
|
||
const collectionData =
|
||
await getCollectionWorkspacesByWorkspaceId(workspaceId)
|
||
setCollections(collectionData.collections)
|
||
|
||
const folders = await getFoldersByWorkspaceId(workspaceId)
|
||
setFolders(folders)
|
||
|
||
const fileData = await getFileWorkspacesByWorkspaceId(workspaceId)
|
||
setFiles(fileData.files)
|
||
|
||
const presetData = await getPresetWorkspacesByWorkspaceId(workspaceId)
|
||
setPresets(presetData.presets)
|
||
|
||
const promptData = await getPromptWorkspacesByWorkspaceId(workspaceId)
|
||
setPrompts(promptData.prompts)
|
||
|
||
const toolData = await getToolWorkspacesByWorkspaceId(workspaceId)
|
||
setTools(toolData.tools)
|
||
|
||
const modelData = await getModelWorkspacesByWorkspaceId(workspaceId)
|
||
setModels(modelData.models)
|
||
|
||
// setChatSettings({
|
||
// model: (searchParams.get("model") ||
|
||
// workspace?.default_model ||
|
||
// "gpt-4-1106-preview") as LLMID,
|
||
|
||
const firstModel = modelData.models[0]?.model_id || "GPT"; // 默认兜底
|
||
setChatSettings({
|
||
model: (searchParams.get("model") ||
|
||
workspace?.default_model ||
|
||
firstModel) as LLMID,
|
||
prompt:
|
||
workspace?.default_prompt ||
|
||
t("chat.promptPlaceholder"),
|
||
temperature: workspace?.default_temperature || 0.5,
|
||
contextLength: workspace?.default_context_length || 4096,
|
||
includeProfileContext: workspace?.include_profile_context || true,
|
||
includeWorkspaceInstructions:
|
||
workspace?.include_workspace_instructions || true,
|
||
embeddingsProvider:
|
||
(workspace?.embeddings_provider as "openai" | "local" | "bge-m3") || "bge-m3"
|
||
})
|
||
|
||
setLoading(false)
|
||
}
|
||
|
||
if (loading) {
|
||
return <Loading />
|
||
}
|
||
|
||
return <Dashboard>{children}</Dashboard>
|
||
}
|