252 lines
12 KiB
TypeScript
252 lines
12 KiB
TypeScript
import { useContext, useEffect, useRef, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { userContext } from "../../contexts/userContext";
|
|
import { deleteFileLib, readFileLibDatabase } from "../../controllers/API";
|
|
import { captureAndAlertRequestErrorHoc } from "../../controllers/request";
|
|
import { useTable } from "../../util/hook";
|
|
import {DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem} from "../../components/ui/dropdown-menu";
|
|
import CreateModal from "./components/createModel"
|
|
import RenameModal from "./components/renameModel"
|
|
import MoveModal from "./components/moveModel";
|
|
import addIcon from "../../assets/knowledge/add-icon.png";
|
|
import folderIcon from "../../assets/knowledge/folder-icon.png";
|
|
import knowledgeIcon from "../../assets/knowledge/knowledge-icon.png";
|
|
import duihuaGengduo from "../../assets/chat/duihua-gengduo.png";
|
|
import writeIcon from "../../assets/knowledge/write-icon.png";
|
|
import moveIcon from "../../assets/knowledge/move-icon.png";
|
|
import exportIcon from "../../assets/knowledge/export-icon.png";
|
|
import deleteIcon from "../../assets/knowledge/delete-icon.png";
|
|
import noFolderIcon from "../../assets/knowledge/no-folder-icon.png";
|
|
import { useNavigate } from "react-router-dom";
|
|
export default function FileLibPage() {
|
|
const [open, setOpen] = useState(false);
|
|
const [renameOpen, setRenameOpen] = useState(false);
|
|
const [moveOpen, setMoveOpen] = useState(false);
|
|
const { user } = useContext(userContext);
|
|
const [parentId, setParentId] = useState('0')
|
|
const [titleArray, setTitleArray] = useState([]);
|
|
const [folderShow, setFolderShow] = useState(false)
|
|
const [type, setType] = useState(1)
|
|
const [data, setData] = useState({})
|
|
const navigate = useNavigate()
|
|
|
|
const { page, pageSize, data: datalist, total, loading, setPage, search, reload } = useTable({},(param) =>
|
|
readFileLibDatabase(param.page, 10000, param.keyword, parentId)
|
|
)
|
|
|
|
useEffect(() => {
|
|
reload()
|
|
}, [])
|
|
|
|
// Delete
|
|
const { delShow, idRef, close, delConfirm } = useDelete();
|
|
|
|
const handleDelete = () => {
|
|
captureAndAlertRequestErrorHoc(deleteFileLib(idRef.current.id).then(res => {
|
|
reload();
|
|
close();
|
|
}));
|
|
}
|
|
|
|
const handleDetail = (el) => {
|
|
if(el.type == 1){
|
|
reload();
|
|
titleArray.push(el)
|
|
setTitleArray(titleArray)
|
|
setParentId(el.id)
|
|
}else if(el.type == 2){
|
|
// @ts-ignore
|
|
window.libname = el.name
|
|
navigate("/filelib/" + el.id);
|
|
}else if(el.type == 3){
|
|
|
|
}
|
|
}
|
|
|
|
const backFolder = (parentId, index) => {
|
|
setParentId(parentId)
|
|
reload();
|
|
if(index == -1){
|
|
setTitleArray([])
|
|
}else if(index == (titleArray.length - 1)){
|
|
return;
|
|
}else{
|
|
titleArray.splice(index+1)
|
|
}
|
|
}
|
|
|
|
// 进详情页前缓存 page, 临时方案
|
|
const handleCachePage = () => {
|
|
// @ts-ignore
|
|
window.LibPage = page
|
|
}
|
|
useEffect(() => {
|
|
// @ts-ignore
|
|
const _page = window.LibPage
|
|
if (_page) {
|
|
setPage(_page);
|
|
// @ts-ignore
|
|
delete window.LibPage
|
|
} else {
|
|
setPage(1);
|
|
}
|
|
}, [])
|
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<div className="w-full h-screen p-6 overflow-y-auto">
|
|
{loading && <div className="absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-[rgba(255,255,255,0.6)] dark:bg-blur-shared">
|
|
<span className="loading loading-infinity loading-lg"></span>
|
|
</div>}
|
|
|
|
<div className="w-full">
|
|
<div className={'knowledge-header'}>
|
|
<div className={'knowledge-title'}>
|
|
{titleArray.length > 0?
|
|
<div className={"title-list"}>
|
|
<div className={"title-item"}>
|
|
<label onClick={()=>backFolder('0', -1)}>{t("lib.rootDirectory")}</label>
|
|
</div>
|
|
{
|
|
titleArray.map((title, index) => (
|
|
<div className={"title-item"} key={title}>
|
|
<span>{index <= (titleArray.length - 1)? ">" : ""}</span>
|
|
<label onClick={()=>backFolder(title.id, index)}>{title.name}</label>
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
:
|
|
t('lib.myKnowledge')
|
|
}
|
|
</div>
|
|
<div className={'knowledge-create-box'}>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger>
|
|
<div className={'knowledge-create'} onClick={() => setOpen(true)}>
|
|
<img src={addIcon} className={'create-icon'}/>
|
|
<label>{t('lib.createNew')}</label>
|
|
</div>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuItem onClick={()=>{
|
|
setType(1)
|
|
setOpen(true)
|
|
}}><img src={folderIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>文件夹</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={()=>{
|
|
setType(2)
|
|
setOpen(true)
|
|
}}><img src={knowledgeIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>知识库</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
</div>
|
|
{
|
|
datalist.length > 0 ?
|
|
<div className={"folder-list"}>
|
|
{datalist.map((el) => (
|
|
<div className={"folder-item"} key={el.id}>
|
|
<div className={"folder-content-item"} onClick={() =>handleDetail(el)}>
|
|
<div className={"folder-header"}>
|
|
{
|
|
el.type == 1?
|
|
<span className={"knowledge-img-bg"}>
|
|
<img src={el.type == 1? folderIcon :(el.img_url?el.img_url: knowledgeIcon )}/>
|
|
</span>
|
|
: (
|
|
el.img_url?
|
|
<img src={knowledgeIcon} className={"knowledge-img"}/>
|
|
:
|
|
<span className={"knowledge-img-bg"}>
|
|
<img src={knowledgeIcon}/>
|
|
</span>
|
|
)
|
|
}
|
|
<label>{el.name}</label>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger>
|
|
<img src={duihuaGengduo} className={'more-button'}/>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuItem onClick={(event)=>{
|
|
event.stopPropagation();
|
|
setData(el)
|
|
setRenameOpen(true)
|
|
}}><img src={writeIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>{t("lib.rename")}</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={(event)=>{
|
|
event.stopPropagation();
|
|
setData(el)
|
|
setMoveOpen(true)
|
|
}}><img src={moveIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>{t("lib.move")}</DropdownMenuItem>
|
|
<DropdownMenuItem><img src={exportIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>{t("code.export")}</DropdownMenuItem>
|
|
|
|
{user.role === 'admin' || user.user_id === el.user_id ?
|
|
<DropdownMenuItem onClick={(event) => {
|
|
event.stopPropagation();
|
|
delConfirm(el)
|
|
}}>
|
|
<img src={deleteIcon} style={{width:'13px',height:'13px',marginRight:'8px'}}/>{t('delete')}
|
|
</DropdownMenuItem> :
|
|
''
|
|
}
|
|
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
<div className={"folder-description"}>
|
|
{el.type == 1 ? t("lib.foldDesc") :el.description}
|
|
</div>
|
|
<div className={"folder-type"}>{el.type == 1?t('lib.folder'):el.type == 2?t('lib.universalKnowledgeBase'):t('lib.webSite')}</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
:
|
|
<div className={"no-folder"}>
|
|
<img src={noFolderIcon}/>
|
|
<p>{t('lib.noKnowledgeBase')}</p>
|
|
</div>
|
|
}
|
|
|
|
</div>
|
|
|
|
<CreateModal reload={reload} createType={type} parentId={parentId} datalist={datalist} open={open} setOpen={setOpen}></CreateModal>
|
|
<RenameModal reload={reload} data={data} open={renameOpen} setOpen={setRenameOpen}></RenameModal>
|
|
<MoveModal reload={reload} data={data} open={moveOpen} setOpen={setMoveOpen} ></MoveModal>
|
|
|
|
<dialog className={`modal ${delShow && 'modal-open'}`}>
|
|
<form method="dialog" className="modal-box w-[360px] bg-[#fff] shadow-lg dialog-box">
|
|
<h3 className="tip-title">{t('prompt')}</h3>
|
|
<p className="tip-message">{t('lib.confirmDeleteLibrary')}</p>
|
|
<div className={"button-box"}>
|
|
<button className={"cancel-button tip-button"} onClick={close}>{t("cancel")}</button>
|
|
<button className={"confirm-button delete-button tip-button-margin"} onClick={handleDelete}>{t("lib.confirmDelete")}</button>
|
|
</div>
|
|
</form>
|
|
</dialog>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|
|
|
|
const useDelete = () => {
|
|
const [delShow, setDelShow] = useState(false)
|
|
const idRef = useRef<any>(null)
|
|
|
|
return {
|
|
delShow,
|
|
idRef,
|
|
close: () => {
|
|
setDelShow(false)
|
|
},
|
|
delConfirm: (id) => {
|
|
idRef.current = id
|
|
setDelShow(true)
|
|
}
|
|
}
|
|
}
|
|
|