feat: implement sidebar resizing functionality and update localization for resize action

This commit is contained in:
mlogclub
2026-06-07 21:56:20 +08:00
parent 892e82afbe
commit 994bec1b3f
3 changed files with 70 additions and 3 deletions
+68 -3
View File
@@ -22,7 +22,7 @@ import {
RefreshCwIcon, RefreshCwIcon,
UploadIcon, UploadIcon,
} from "lucide-react" } from "lucide-react"
import { useState } from "react" import { useEffect, useState, type PointerEvent } from "react"
import { toast } from "sonner" import { toast } from "sonner"
import { DebugPanel } from "./_components/debug-panel" import { DebugPanel } from "./_components/debug-panel"
import { DocumentList, type DocumentListActionState } from "./_components/document-list" import { DocumentList, type DocumentListActionState } from "./_components/document-list"
@@ -30,10 +30,29 @@ import { FAQList, type FAQListActionState } from "./_components/faq-list"
import { KnowledgeBaseList } from "./_components/knowledge-base-list" import { KnowledgeBaseList } from "./_components/knowledge-base-list"
import { RetrieveLogList } from "./_components/retrieve-log-list" import { RetrieveLogList } from "./_components/retrieve-log-list"
const KNOWLEDGE_BASE_LIST_WIDTH_STORAGE_KEY = "knowledge-base-list-width"
const KNOWLEDGE_BASE_LIST_MIN_WIDTH = 240
const KNOWLEDGE_BASE_LIST_MAX_WIDTH = 520
const KNOWLEDGE_BASE_LIST_DEFAULT_WIDTH = 320
export default function DashboardKnowledgeDocumentsPage() { export default function DashboardKnowledgeDocumentsPage() {
const t = useI18n() const t = useI18n()
const [selectedKnowledgeBase, setSelectedKnowledgeBase] = useState<KnowledgeBase | null>(null) const [selectedKnowledgeBase, setSelectedKnowledgeBase] = useState<KnowledgeBase | null>(null)
const [sidebarCollapsed, setSidebarCollapsed] = useState(false) const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
const [sidebarResizing, setSidebarResizing] = useState(false)
const [sidebarWidth, setSidebarWidth] = useState(() => {
if (typeof window === "undefined") {
return KNOWLEDGE_BASE_LIST_DEFAULT_WIDTH
}
const saved = Number(localStorage.getItem(KNOWLEDGE_BASE_LIST_WIDTH_STORAGE_KEY))
if (!Number.isFinite(saved)) {
return KNOWLEDGE_BASE_LIST_DEFAULT_WIDTH
}
return Math.min(
KNOWLEDGE_BASE_LIST_MAX_WIDTH,
Math.max(KNOWLEDGE_BASE_LIST_MIN_WIDTH, saved),
)
})
const [debugPanelOpen, setDebugPanelOpen] = useState(false) const [debugPanelOpen, setDebugPanelOpen] = useState(false)
const [activeTab, setActiveTab] = useState("documents") const [activeTab, setActiveTab] = useState("documents")
const [documentActionState, setDocumentActionState] = useState<DocumentListActionState | null>(null) const [documentActionState, setDocumentActionState] = useState<DocumentListActionState | null>(null)
@@ -41,6 +60,42 @@ export default function DashboardKnowledgeDocumentsPage() {
const [exportingFAQ, setExportingFAQ] = useState(false) const [exportingFAQ, setExportingFAQ] = useState(false)
const isFAQKnowledgeBase = selectedKnowledgeBase?.knowledgeType === "faq" const isFAQKnowledgeBase = selectedKnowledgeBase?.knowledgeType === "faq"
useEffect(() => {
localStorage.setItem(KNOWLEDGE_BASE_LIST_WIDTH_STORAGE_KEY, String(sidebarWidth))
}, [sidebarWidth])
function handleSidebarResizePointerDown(event: PointerEvent<HTMLDivElement>) {
event.preventDefault()
const startX = event.clientX
const startWidth = sidebarWidth
function handlePointerMove(moveEvent: globalThis.PointerEvent) {
const nextWidth = startWidth + moveEvent.clientX - startX
setSidebarWidth(
Math.min(
KNOWLEDGE_BASE_LIST_MAX_WIDTH,
Math.max(KNOWLEDGE_BASE_LIST_MIN_WIDTH, nextWidth),
),
)
}
function handlePointerEnd() {
window.removeEventListener("pointermove", handlePointerMove)
window.removeEventListener("pointerup", handlePointerEnd)
window.removeEventListener("pointercancel", handlePointerEnd)
document.body.style.cursor = ""
document.body.style.userSelect = ""
setSidebarResizing(false)
}
setSidebarResizing(true)
document.body.style.cursor = "col-resize"
document.body.style.userSelect = "none"
window.addEventListener("pointermove", handlePointerMove)
window.addEventListener("pointerup", handlePointerEnd)
window.addEventListener("pointercancel", handlePointerEnd)
}
async function handleExportFAQ() { async function handleExportFAQ() {
if (!selectedKnowledgeBase || exportingFAQ) { if (!selectedKnowledgeBase || exportingFAQ) {
return return
@@ -59,14 +114,24 @@ export default function DashboardKnowledgeDocumentsPage() {
return ( return (
<div className="flex h-full min-h-0 overflow-hidden"> <div className="flex h-full min-h-0 overflow-hidden">
<div <div
className={`shrink-0 overflow-hidden transition-[width] duration-200 ${ className={`relative shrink-0 overflow-hidden ${
sidebarCollapsed ? "w-0" : "w-80" sidebarResizing ? "" : "transition-[width] duration-200"
}`} }`}
style={{ width: sidebarCollapsed ? 0 : sidebarWidth }}
> >
<KnowledgeBaseList <KnowledgeBaseList
selectedKnowledgeBaseId={selectedKnowledgeBase?.id ?? null} selectedKnowledgeBaseId={selectedKnowledgeBase?.id ?? null}
onSelectKnowledgeBase={setSelectedKnowledgeBase} onSelectKnowledgeBase={setSelectedKnowledgeBase}
/> />
{!sidebarCollapsed ? (
<div
className="absolute top-0 right-[-3px] z-20 h-full w-1.5 cursor-col-resize transition-colors hover:bg-primary/30"
onPointerDown={handleSidebarResizePointerDown}
role="separator"
aria-orientation="vertical"
aria-label={t("knowledge.resizeList")}
/>
) : null}
</div> </div>
<div className="relative shrink-0 bg-background"> <div className="relative shrink-0 bg-background">
<Button <Button
+1
View File
@@ -1768,6 +1768,7 @@
"retrieveLogs": "Retrieval Logs", "retrieveLogs": "Retrieval Logs",
"expandList": "Expand knowledge base list", "expandList": "Expand knowledge base list",
"collapseList": "Collapse knowledge base list", "collapseList": "Collapse knowledge base list",
"resizeList": "Resize knowledge base list",
"refreshDocuments": "Refresh documents", "refreshDocuments": "Refresh documents",
"listLayout": "List layout", "listLayout": "List layout",
"gridLayout": "Grid layout", "gridLayout": "Grid layout",
+1
View File
@@ -1769,6 +1769,7 @@
"retrieveLogs": "检索日志", "retrieveLogs": "检索日志",
"expandList": "展开知识库列表", "expandList": "展开知识库列表",
"collapseList": "折叠知识库列表", "collapseList": "折叠知识库列表",
"resizeList": "调整知识库列表宽度",
"refreshDocuments": "刷新文档", "refreshDocuments": "刷新文档",
"listLayout": "列表布局", "listLayout": "列表布局",
"gridLayout": "网格布局", "gridLayout": "网格布局",