mirror of
https://github.com/Funkoala14/KnowledgeBase_OOIN.git
synced 2025-06-08 05:09:44 +08:00
[dev]add request
This commit is contained in:
parent
ee5d1bcaa8
commit
6d0ebf169c
@ -78,4 +78,25 @@ export const icons = {
|
|||||||
></path>
|
></path>
|
||||||
</svg>`,
|
</svg>`,
|
||||||
edit: `<svg t="1741043785681" class="icon" viewBox="0 0 1061 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14021" width="16" height="16" fill='currentColor'><path d="M877.714 475.429v402.286c0 40.396-32.747 73.143-73.143 73.143H146.285c-40.396 0-73.143-32.747-73.143-73.143V219.429c0-40.396 32.747-73.143 73.143-73.143h438.857V73.143H146.285C65.494 73.143-0.001 138.637-0.001 219.429v658.286c0 80.791 65.494 146.286 146.286 146.286h658.286c80.791 0 146.286-65.494 146.286-146.286V475.429h-73.143z" p-id="14022"></path><path d="M397.897 774.217c-5.145 0.812-11.079 1.275-17.121 1.275-27.052 0-51.934-9.295-71.624-24.866-24.26-24.318-23.529-59.427-22.798-117.209 2.851-45.25 21.396-85.691 50.197-116.398L830.903 22.674c40.96-40.96 100.206-20.48 138.24 16.091 10.971 10.971 40.594 40.96 51.566 51.566 36.571 36.571 58.88 96.914 17.189 138.971L543.087 724.113c-30.205 29.593-71.086 48.391-116.341 50.093l-28.848 0.01z m-36.571-75.337c13.39 1.737 28.876 2.729 44.595 2.729 6.955 0 13.864-0.194 20.723-0.577 24.676-1.644 47.559-12.193 64.931-28.534l495.854-494.76c0.004-0.236 0.007-0.514 0.007-0.793 0-14.36-6.517-27.198-16.754-35.717-11.047-10.667-41.401-41.021-52.007-51.992-8.83-10.109-21.744-16.459-36.141-16.459l-0.454 0.002-494.423 494.446a115.687 115.687 0 0 0-28.495 66.486c-0.399 6.509-0.609 13.605-0.609 20.75 0 15.659 1.007 31.082 2.961 46.209z" p-id="14023"></path></svg>`,
|
edit: `<svg t="1741043785681" class="icon" viewBox="0 0 1061 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14021" width="16" height="16" fill='currentColor'><path d="M877.714 475.429v402.286c0 40.396-32.747 73.143-73.143 73.143H146.285c-40.396 0-73.143-32.747-73.143-73.143V219.429c0-40.396 32.747-73.143 73.143-73.143h438.857V73.143H146.285C65.494 73.143-0.001 138.637-0.001 219.429v658.286c0 80.791 65.494 146.286 146.286 146.286h658.286c80.791 0 146.286-65.494 146.286-146.286V475.429h-73.143z" p-id="14022"></path><path d="M397.897 774.217c-5.145 0.812-11.079 1.275-17.121 1.275-27.052 0-51.934-9.295-71.624-24.866-24.26-24.318-23.529-59.427-22.798-117.209 2.851-45.25 21.396-85.691 50.197-116.398L830.903 22.674c40.96-40.96 100.206-20.48 138.24 16.091 10.971 10.971 40.594 40.96 51.566 51.566 36.571 36.571 58.88 96.914 17.189 138.971L543.087 724.113c-30.205 29.593-71.086 48.391-116.341 50.093l-28.848 0.01z m-36.571-75.337c13.39 1.737 28.876 2.729 44.595 2.729 6.955 0 13.864-0.194 20.723-0.577 24.676-1.644 47.559-12.193 64.931-28.534l495.854-494.76c0.004-0.236 0.007-0.514 0.007-0.793 0-14.36-6.517-27.198-16.754-35.717-11.047-10.667-41.401-41.021-52.007-51.992-8.83-10.109-21.744-16.459-36.141-16.459l-0.454 0.002-494.423 494.446a115.687 115.687 0 0 0-28.495 66.486c-0.399 6.509-0.609 13.605-0.609 20.75 0 15.659 1.007 31.082 2.961 46.209z" p-id="14023"></path></svg>`,
|
||||||
|
list: `<svg
|
||||||
|
t='1741046309233'
|
||||||
|
class='icon'
|
||||||
|
viewBox='0 0 1024 1024'
|
||||||
|
version='1.1'
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
p-id='21340'
|
||||||
|
width='16'
|
||||||
|
height='16'
|
||||||
|
fill='currentColor'
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d='M896 256l-288 0c-17.696 0-32-14.336-32-32s14.304-32 32-32l288 0c17.696 0 32 14.336 32 32S913.696 256 896 256zM896 416l-288 0c-17.696 0-32-14.336-32-32s14.304-32 32-32l288 0c17.696 0 32 14.336 32 32S913.696 416 896 416zM896 672l-288 0c-17.696 0-32-14.304-32-32s14.304-32 32-32l288 0c17.696 0 32 14.304 32 32S913.696 672 896 672zM896 832l-288 0c-17.696 0-32-14.304-32-32s14.304-32 32-32l288 0c17.696 0 32 14.304 32 32S913.696 832 896 832zM384 480 192 480c-52.928 0-96-43.072-96-96L96 192c0-52.928 43.072-96 96-96l192 0c52.928 0 96 43.072 96 96l0 192C480 436.928 436.928 480 384 480zM192 160C174.368 160 160 174.368 160 192l0 192c0 17.632 14.368 32 32 32l192 0c17.632 0 32-14.368 32-32L416 192c0-17.632-14.368-32-32-32L192 160zM384 928 192 928c-52.928 0-96-43.072-96-96l0-192c0-52.928 43.072-96 96-96l192 0c52.928 0 96 43.072 96 96l0 192C480 884.928 436.928 928 384 928zM192 608c-17.632 0-32 14.336-32 32l0 192c0 17.664 14.368 32 32 32l192 0c17.632 0 32-14.336 32-32l0-192c0-17.664-14.368-32-32-32L192 608z'
|
||||||
|
p-id='21341'
|
||||||
|
></path>
|
||||||
|
</svg>`,
|
||||||
|
'setting-fill': `<svg t="1741046883752" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34037" width="24" height="24" fill='currentColor'><path d="M809.188 550.978c1.6-12.8 2.799-25.799 2.799-38.998s-1.2-26.198-2.799-38.998l84.596-66.197c7.6-6 9.8-16.799 4.8-25.599l-79.996-138.594c-5-8.6-15.399-12.199-24.399-8.6l-99.596 40.199c-20.599-15.8-43.198-29.198-67.597-39.398l-14.999-105.996c-1.8-9.399-9.999-16.799-20-16.799l-159.994 0c-9.999 0-18.199 7.4-19.799 16.799l-14.999 105.996c-24.399 10.2-46.999 23.399-67.597 39.398l-99.596-40.199c-9-3.4-19.399 0-24.399 8.6l-79.996 138.594c-5 8.6-2.8 19.399 4.8 25.599l84.397 66.197c-1.6 12.8-2.8 25.799-2.8 38.998 0 13.2 1.2 26.198 2.8 38.998l-84.397 66.197c-7.6 6-9.8 16.799-4.8 25.599l79.996 138.594c5 8.6 15.399 12.199 24.399 8.6l99.596-40.199c20.599 15.8 43.198 29.198 67.597 39.398l14.999 105.996c1.6 9.399 9.8 16.799 19.799 16.799l159.994 0c9.999 0 18.199-7.4 19.799-16.799l14.999-105.996c24.399-10.2 46.999-23.399 67.597-39.398l99.596 40.199c9 3.4 19.399 0 24.399-8.6l79.996-138.594c5-8.6 2.8-19.399-4.8-25.599l-84.396-66.197zM512 651.973c-77.396 0-139.994-62.598-139.994-139.994s62.598-139.994 139.994-139.994 139.994 62.598 139.994 139.994-62.598 139.994-139.994 139.994z" p-id="34038"></path></svg>`,
|
||||||
|
dataset: `<svg t="1741046791101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="32858" width="24" height="24" fill='currentColor'><path d="M170.666667 798.464V262.101333C170.666667 235.178667 192.512 213.333333 219.434667 213.333333h585.130666C831.488 213.333333 853.333333 235.178667 853.333333 262.101333v536.362667c0 26.922667-21.845333 48.768-48.768 48.768H219.434667A48.768 48.768 0 0 1 170.666667 798.464z m48.768-146.261333v146.261333h585.130666v-146.261333H219.434667z m0-48.768h585.130666v-146.304H219.434667v146.304z m0-195.072h585.130666V262.101333H219.434667V408.32z m73.130666-97.493334h97.536a24.362667 24.362667 0 1 1 0 48.768H292.565333a24.362667 24.362667 0 1 1 0-48.768z m0 195.029334h97.536a24.362667 24.362667 0 1 1 0 48.768H292.565333a24.362667 24.362667 0 0 1 0-48.768z m0 195.072h97.536a24.362667 24.362667 0 0 1 0 48.725333H292.565333a24.362667 24.362667 0 0 1 0-48.725333z p-id="32859"></path></svg>`,
|
||||||
|
calendar: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16" fill='currentColor'><path d="M152 24c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40L64 64C28.7 64 0 92.7 0 128l0 16 0 48L0 448c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-256 0-48 0-16c0-35.3-28.7-64-64-64l-40 0 0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40L152 64l0-40zM48 192l352 0 0 256c0 8.8-7.2 16-16 16L64 464c-8.8 0-16-7.2-16-16l0-256z"/></svg>`,
|
||||||
|
clipboard: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="16" height="16" fill='currentColor'><path d="M280 64l40 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 128C0 92.7 28.7 64 64 64l40 0 9.6 0C121 27.5 153.3 0 192 0s71 27.5 78.4 64l9.6 0zM64 112c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l256 0c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16l-16 0 0 24c0 13.3-10.7 24-24 24l-88 0-88 0c-13.3 0-24-10.7-24-24l0-24-16 0zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z"/></svg>`,
|
||||||
|
chat: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16" fill='currentColor'><path d="M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9l.3-.5z"/></svg>`,
|
||||||
};
|
};
|
||||||
|
@ -91,7 +91,12 @@ export default function DatasetTab({ knowledgeBase }) {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className='breadcrumb-item'>
|
<li className='breadcrumb-item'>
|
||||||
<Link className='text-secondary text-decoration-none' to={`/knowledge-base/${knowledgeBase.id}`}>{knowledgeBase.title}</Link>
|
<Link
|
||||||
|
className='text-secondary text-decoration-none'
|
||||||
|
to={`/knowledge-base/${knowledgeBase.id}`}
|
||||||
|
>
|
||||||
|
{knowledgeBase.title}
|
||||||
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className='breadcrumb-item active text-dark' aria-current='page'>
|
<li className='breadcrumb-item active text-dark' aria-current='page'>
|
||||||
数据集
|
数据集
|
||||||
@ -194,14 +199,14 @@ export default function DatasetTab({ knowledgeBase }) {
|
|||||||
<td>{doc.size}</td>
|
<td>{doc.size}</td>
|
||||||
<td>{doc.updatedAt}</td>
|
<td>{doc.updatedAt}</td>
|
||||||
<td>
|
<td>
|
||||||
<div className='d-flex gap-2'>
|
<div className='d-flex gap-1'>
|
||||||
<button className='btn btn-sm btn-outline-primary' title='查看'>
|
<button className='btn btn-sm text-primary' title='查看'>
|
||||||
<SvgIcon className='eye' />
|
<SvgIcon className='eye' />
|
||||||
</button>
|
</button>
|
||||||
<button className='btn btn-sm btn-outline-success' title='编辑'>
|
<button className='btn btn-sm text-success' title='编辑'>
|
||||||
<SvgIcon className='edit' />
|
<SvgIcon className='edit' />
|
||||||
</button>
|
</button>
|
||||||
<button className='btn btn-sm btn-outline-danger' title='删除'>
|
<button className='btn btn-sm text-danger' title='删除'>
|
||||||
<SvgIcon className='trash' />
|
<SvgIcon className='trash' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,21 +2,6 @@ import React from 'react';
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import SvgIcon from '../../../components/SvgIcon';
|
import SvgIcon from '../../../components/SvgIcon';
|
||||||
|
|
||||||
// Custom styled Link component with hover effect
|
|
||||||
const StyledLink = ({ to, children }) => {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
to={to}
|
|
||||||
className='text-secondary text-decoration-none'
|
|
||||||
style={{ transition: 'all 0.2s ease' }}
|
|
||||||
onMouseOver={(e) => (e.currentTarget.style.color = '#212529')}
|
|
||||||
onMouseOut={(e) => (e.currentTarget.style.color = '')}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function SettingsTab({ knowledgeBase }) {
|
export default function SettingsTab({ knowledgeBase }) {
|
||||||
// Handle form submission
|
// Handle form submission
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
@ -38,12 +23,12 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
<nav aria-label='breadcrumb'>
|
<nav aria-label='breadcrumb'>
|
||||||
<ol className='breadcrumb mb-0'>
|
<ol className='breadcrumb mb-0'>
|
||||||
<li className='breadcrumb-item'>
|
<li className='breadcrumb-item'>
|
||||||
<StyledLink to='/'>知识库</StyledLink>
|
<Link className='text-secondary text-decoration-none' to='/'>知识库</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className='breadcrumb-item'>
|
<li className='breadcrumb-item'>
|
||||||
<StyledLink to={`/knowledge-base/${knowledgeBase.id}`}>{knowledgeBase.title}</StyledLink>
|
<Link className='text-secondary text-decoration-none' to={`/knowledge-base/${knowledgeBase.id}`}>{knowledgeBase.title}</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className='breadcrumb-item active text-secondary' aria-current='page'>
|
<li className='breadcrumb-item active text-dark' aria-current='page'>
|
||||||
设置
|
设置
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -132,12 +117,12 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className='d-flex gap-2'>
|
<div className='d-flex gap-2'>
|
||||||
<button
|
<button
|
||||||
className='btn btn-sm btn-outline-secondary'
|
className='btn btn-sm text-primary'
|
||||||
title='编辑'
|
title='编辑'
|
||||||
>
|
>
|
||||||
<SvgIcon className='edit' />
|
<SvgIcon className='edit' />
|
||||||
</button>
|
</button>
|
||||||
<button className='btn btn-sm btn-outline-danger' title='删除'>
|
<button className='btn btn-sm text-danger' title='删除'>
|
||||||
<SvgIcon className='trash' />
|
<SvgIcon className='trash' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -152,12 +137,12 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
<td>
|
<td>
|
||||||
<div className='d-flex gap-2'>
|
<div className='d-flex gap-2'>
|
||||||
<button
|
<button
|
||||||
className='btn btn-sm btn-outline-secondary'
|
className='btn btn-sm text-primary'
|
||||||
title='编辑'
|
title='编辑'
|
||||||
>
|
>
|
||||||
<SvgIcon className='edit' />
|
<SvgIcon className='edit' />
|
||||||
</button>
|
</button>
|
||||||
<button className='btn btn-sm btn-outline-danger' title='删除'>
|
<button className='btn btn-sm text-danger' title='删除'>
|
||||||
<SvgIcon className='trash' />
|
<SvgIcon className='trash' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -167,7 +152,7 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type='button' className='btn btn-outline-primary mt-2'>
|
<button type='button' className='btn btn-outline-dark mt-2'>
|
||||||
<SvgIcon className='plus me-1' />
|
<SvgIcon className='plus me-1' />
|
||||||
添加用户
|
添加用户
|
||||||
</button>
|
</button>
|
||||||
@ -177,7 +162,7 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
<button type='button' className='btn btn-outline-danger' onClick={handleDelete}>
|
<button type='button' className='btn btn-outline-danger' onClick={handleDelete}>
|
||||||
删除知识库
|
删除知识库
|
||||||
</button>
|
</button>
|
||||||
<button type='submit' className='btn btn-primary'>
|
<button type='submit' className='btn btn-dark'>
|
||||||
保存设置
|
保存设置
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,17 @@ export default function KnowledgeBase() {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [showCreateModal, setShowCreateModal] = useState(false);
|
const [showCreateModal, setShowCreateModal] = useState(false);
|
||||||
|
const [showAccessRequestModal, setShowAccessRequestModal] = useState(false);
|
||||||
|
const [formErrors, setFormErrors] = useState({});
|
||||||
|
const [accessRequestErrors, setAccessRequestErrors] = useState({});
|
||||||
|
const [accessRequestData, setAccessRequestData] = useState({
|
||||||
|
id: '',
|
||||||
|
title: '',
|
||||||
|
accessType: '只读访问',
|
||||||
|
duration: '一周',
|
||||||
|
projectInfo: '',
|
||||||
|
reason: '',
|
||||||
|
});
|
||||||
const [newKnowledgeBase, setNewKnowledgeBase] = useState({
|
const [newKnowledgeBase, setNewKnowledgeBase] = useState({
|
||||||
title: '',
|
title: '',
|
||||||
description: '',
|
description: '',
|
||||||
@ -47,17 +58,65 @@ export default function KnowledgeBase() {
|
|||||||
...prev,
|
...prev,
|
||||||
[name]: value,
|
[name]: value,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Clear error when user types
|
||||||
|
if (formErrors[name]) {
|
||||||
|
setFormErrors((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: '',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAccessRequestInputChange = (e) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setAccessRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Clear error when user types
|
||||||
|
if (accessRequestErrors[name]) {
|
||||||
|
setAccessRequestErrors((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: '',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateCreateForm = () => {
|
||||||
|
const errors = {};
|
||||||
|
|
||||||
|
if (!newKnowledgeBase.title.trim()) {
|
||||||
|
errors.title = '请输入知识库名称';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newKnowledgeBase.description.trim()) {
|
||||||
|
errors.description = '请输入知识库描述';
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormErrors(errors);
|
||||||
|
return Object.keys(errors).length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateAccessRequestForm = () => {
|
||||||
|
const errors = {};
|
||||||
|
|
||||||
|
if (!accessRequestData.projectInfo.trim()) {
|
||||||
|
errors.projectInfo = '请输入项目信息';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accessRequestData.reason.trim()) {
|
||||||
|
errors.reason = '请输入申请原因';
|
||||||
|
}
|
||||||
|
|
||||||
|
setAccessRequestErrors(errors);
|
||||||
|
return Object.keys(errors).length === 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateKnowledgeBase = () => {
|
const handleCreateKnowledgeBase = () => {
|
||||||
// Here you would typically call an API to create the knowledge base
|
// Validate form
|
||||||
if (!newKnowledgeBase.title.trim()) {
|
if (!validateCreateForm()) {
|
||||||
dispatch(
|
|
||||||
showNotification({
|
|
||||||
message: '请输入知识库名称',
|
|
||||||
type: 'error',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +134,7 @@ export default function KnowledgeBase() {
|
|||||||
|
|
||||||
// Reset form and close modal
|
// Reset form and close modal
|
||||||
setNewKnowledgeBase({ title: '', description: '' });
|
setNewKnowledgeBase({ title: '', description: '' });
|
||||||
|
setFormErrors({});
|
||||||
setShowCreateModal(false);
|
setShowCreateModal(false);
|
||||||
|
|
||||||
// Navigate to the newly created knowledge base with datasets tab
|
// Navigate to the newly created knowledge base with datasets tab
|
||||||
@ -85,6 +145,40 @@ export default function KnowledgeBase() {
|
|||||||
navigate(`/knowledge-base/${id}/datasets`);
|
navigate(`/knowledge-base/${id}/datasets`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRequestAccess = (id, title) => {
|
||||||
|
setAccessRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
}));
|
||||||
|
setAccessRequestErrors({});
|
||||||
|
setShowAccessRequestModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmitAccessRequest = () => {
|
||||||
|
// Validate form
|
||||||
|
if (!validateAccessRequestForm()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here you would typically call an API to submit the access request
|
||||||
|
dispatch(
|
||||||
|
showNotification({
|
||||||
|
message: '权限申请已提交',
|
||||||
|
type: 'success',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reset form and close modal
|
||||||
|
setAccessRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
projectInfo: '',
|
||||||
|
reason: '',
|
||||||
|
}));
|
||||||
|
setAccessRequestErrors({});
|
||||||
|
setShowAccessRequestModal(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<div className='d-flex justify-content-between align-items-center mb-3'>
|
<div className='d-flex justify-content-between align-items-center mb-3'>
|
||||||
@ -101,7 +195,11 @@ export default function KnowledgeBase() {
|
|||||||
<div className='row gap-3 m-0'>
|
<div className='row gap-3 m-0'>
|
||||||
{knowledgeList.map((item) => (
|
{knowledgeList.map((item) => (
|
||||||
<React.Fragment key={item.id}>
|
<React.Fragment key={item.id}>
|
||||||
<KnowledgeCard {...item} onClick={() => handleCardClick(item.id)} />
|
<KnowledgeCard
|
||||||
|
{...item}
|
||||||
|
onClick={() => handleCardClick(item.id)}
|
||||||
|
onRequestAccess={handleRequestAccess}
|
||||||
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -143,11 +241,11 @@ export default function KnowledgeBase() {
|
|||||||
<div className='modal-body'>
|
<div className='modal-body'>
|
||||||
<div className='mb-3'>
|
<div className='mb-3'>
|
||||||
<label htmlFor='knowledgeTitle' className='form-label'>
|
<label htmlFor='knowledgeTitle' className='form-label'>
|
||||||
知识库名称
|
知识库名称 <span className='text-danger'>*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
className='form-control'
|
className={`form-control ${formErrors.title ? 'is-invalid' : ''}`}
|
||||||
id='knowledgeTitle'
|
id='knowledgeTitle'
|
||||||
name='title'
|
name='title'
|
||||||
value={newKnowledgeBase.title}
|
value={newKnowledgeBase.title}
|
||||||
@ -155,20 +253,25 @@ export default function KnowledgeBase() {
|
|||||||
placeholder='请输入知识库名称'
|
placeholder='请输入知识库名称'
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
{formErrors.title && <div className='invalid-feedback'>{formErrors.title}</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className='mb-3'>
|
<div className='mb-3'>
|
||||||
<label htmlFor='knowledgeDescription' className='form-label'>
|
<label htmlFor='knowledgeDescription' className='form-label'>
|
||||||
知识库描述
|
知识库描述 <span className='text-danger'>*</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
className='form-control'
|
className={`form-control ${formErrors.description ? 'is-invalid' : ''}`}
|
||||||
id='knowledgeDescription'
|
id='knowledgeDescription'
|
||||||
name='description'
|
name='description'
|
||||||
value={newKnowledgeBase.description}
|
value={newKnowledgeBase.description}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
placeholder='请输入知识库描述'
|
placeholder='请输入知识库描述'
|
||||||
rows='3'
|
rows='3'
|
||||||
|
required
|
||||||
></textarea>
|
></textarea>
|
||||||
|
{formErrors.description && (
|
||||||
|
<div className='invalid-feedback'>{formErrors.description}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='modal-footer d-flex justify-content-end gap-2'>
|
<div className='modal-footer d-flex justify-content-end gap-2'>
|
||||||
@ -186,6 +289,152 @@ export default function KnowledgeBase() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 申请访问权限弹窗 */}
|
||||||
|
{showAccessRequestModal && (
|
||||||
|
<div
|
||||||
|
className='modal-backdrop'
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
zIndex: 1050,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className='modal-content bg-white rounded shadow'
|
||||||
|
style={{
|
||||||
|
width: '500px',
|
||||||
|
maxWidth: '90%',
|
||||||
|
padding: '20px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='modal-header d-flex justify-content-between align-items-center mb-3'>
|
||||||
|
<h5 className='modal-title m-0'>申请访问权限</h5>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn-close'
|
||||||
|
onClick={() => setShowAccessRequestModal(false)}
|
||||||
|
aria-label='Close'
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className='modal-body'>
|
||||||
|
<div className='mb-4'>
|
||||||
|
<label className='form-label d-flex align-items-center gap-1'>
|
||||||
|
<SvgIcon className='key' />
|
||||||
|
访问级别 <span className='text-danger'>*</span>
|
||||||
|
</label>
|
||||||
|
<div className='d-flex gap-2'>
|
||||||
|
<div
|
||||||
|
className={`p-3 rounded border bg-warning-subtle ${
|
||||||
|
accessRequestData.accessType === '只读访问'
|
||||||
|
? 'border-warning bg-warning-subtle'
|
||||||
|
: 'border-warning-subtle opacity-50'
|
||||||
|
}`}
|
||||||
|
style={{ flex: 1, cursor: 'pointer' }}
|
||||||
|
onClick={() =>
|
||||||
|
setAccessRequestData((prev) => ({ ...prev, accessType: '只读访问' }))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className='text-center text-warning fw-bold mb-1'>只读访问</div>
|
||||||
|
<div className='text-center text-muted small'>仅查看数据集内容</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`p-3 rounded border bg-success-subtle ${
|
||||||
|
accessRequestData.accessType === '完全访问'
|
||||||
|
? 'border-success'
|
||||||
|
: 'border-success-subtle opacity-50'
|
||||||
|
}`}
|
||||||
|
style={{ flex: 1, cursor: 'pointer' }}
|
||||||
|
onClick={() =>
|
||||||
|
setAccessRequestData((prev) => ({ ...prev, accessType: '完全访问' }))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className='text-center text-success fw-bold mb-1'>完全访问</div>
|
||||||
|
<div className='text-center text-muted small'>查看、编辑和管理数据</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mb-3'>
|
||||||
|
<label className='form-label d-flex align-items-center gap-1'>
|
||||||
|
<SvgIcon className='calendar' />
|
||||||
|
访问时长 <span className='text-danger'>*</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
className='form-select'
|
||||||
|
name='duration'
|
||||||
|
value={accessRequestData.duration}
|
||||||
|
onChange={handleAccessRequestInputChange}
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<option value='一周'>一周</option>
|
||||||
|
<option value='一个月'>一个月</option>
|
||||||
|
<option value='三个月'>三个月</option>
|
||||||
|
<option value='六个月'>六个月</option>
|
||||||
|
<option value='永久'>永久</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mb-3'>
|
||||||
|
<label className='form-label d-flex align-items-center gap-1'>
|
||||||
|
<SvgIcon className='clipboard' />
|
||||||
|
项目信息 <span className='text-danger'>*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
className={`form-control ${accessRequestErrors.projectInfo ? 'is-invalid' : ''}`}
|
||||||
|
name='projectInfo'
|
||||||
|
value={accessRequestData.projectInfo}
|
||||||
|
onChange={handleAccessRequestInputChange}
|
||||||
|
placeholder='请输入项目信息'
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{accessRequestErrors.projectInfo && (
|
||||||
|
<div className='invalid-feedback'>{accessRequestErrors.projectInfo}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mb-3'>
|
||||||
|
<label className='form-label d-flex align-items-center gap-1'>
|
||||||
|
<SvgIcon className='chat' />
|
||||||
|
申请原因 <span className='text-danger'>*</span>
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
className={`form-control ${accessRequestErrors.reason ? 'is-invalid' : ''}`}
|
||||||
|
name='reason'
|
||||||
|
value={accessRequestData.reason}
|
||||||
|
onChange={handleAccessRequestInputChange}
|
||||||
|
placeholder='请输入申请原因'
|
||||||
|
rows='4'
|
||||||
|
required
|
||||||
|
></textarea>
|
||||||
|
{accessRequestErrors.reason && (
|
||||||
|
<div className='invalid-feedback'>{accessRequestErrors.reason}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='modal-footer d-flex justify-content-end gap-2'>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn btn-outline-secondary'
|
||||||
|
onClick={() => setShowAccessRequestModal(false)}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</button>
|
||||||
|
<button type='button' className='btn btn-dark' onClick={handleSubmitAccessRequest}>
|
||||||
|
提交申请
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export default function KnowledgeBaseDetail() {
|
|||||||
|
|
||||||
<nav className='nav flex-column'>
|
<nav className='nav flex-column'>
|
||||||
<a
|
<a
|
||||||
className={`nav-link link-dark link-underline-light d-flex align-items-center ${
|
className={`nav-link link-dark link-underline-light d-flex align-items-center gap-2 ${
|
||||||
activeTab === 'datasets' ? 'active bg-light rounded fw-bold' : ''
|
activeTab === 'datasets' ? 'active bg-light rounded fw-bold' : ''
|
||||||
}`}
|
}`}
|
||||||
href='#'
|
href='#'
|
||||||
@ -54,11 +54,11 @@ export default function KnowledgeBaseDetail() {
|
|||||||
handleTabChange('datasets');
|
handleTabChange('datasets');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SvgIcon className='database me-2' />
|
<SvgIcon className='dataset' />
|
||||||
数据集
|
数据集
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className={`nav-link link-dark link-underline-light d-flex align-items-center ${
|
className={`nav-link link-dark link-underline-light d-flex align-items-center gap-1 ${
|
||||||
activeTab === 'settings' ? 'active bg-light rounded fw-bold' : ''
|
activeTab === 'settings' ? 'active bg-light rounded fw-bold' : ''
|
||||||
}`}
|
}`}
|
||||||
href='#'
|
href='#'
|
||||||
@ -67,7 +67,7 @@ export default function KnowledgeBaseDetail() {
|
|||||||
handleTabChange('settings');
|
handleTabChange('settings');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SvgIcon className='gear me-2' />
|
<SvgIcon className='setting-fill' />
|
||||||
设置
|
设置
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import SvgIcon from '../../components/SvgIcon';
|
import SvgIcon from '../../components/SvgIcon';
|
||||||
|
|
||||||
export default function KnowledgeCard({ id, title, description, documents, date, access, onClick }) {
|
export default function KnowledgeCard({ id, title, description, documents, date, access, onClick, onRequestAccess }) {
|
||||||
|
const handleNewChat = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRequestAccess = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
onRequestAccess(id, title);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='knowledge-card card shadow border-0 p-0 col' onClick={onClick}>
|
<div className='knowledge-card card shadow border-0 p-0 col' onClick={onClick}>
|
||||||
<div className='card-body'>
|
<div className='card-body'>
|
||||||
@ -44,12 +55,18 @@ export default function KnowledgeCard({ id, title, description, documents, date,
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{access === 'full' || access === 'read' ? (
|
{access === 'full' || access === 'read' ? (
|
||||||
<button className='btn btn-outline-dark btn-sm d-flex align-items-center gap-1'>
|
<button
|
||||||
|
className='btn btn-outline-dark btn-sm d-flex align-items-center gap-1'
|
||||||
|
onClick={handleNewChat}
|
||||||
|
>
|
||||||
<SvgIcon className={'chat-dot'} />
|
<SvgIcon className={'chat-dot'} />
|
||||||
新聊天
|
新聊天
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button className='btn btn-outline-dark btn-sm d-flex align-items-center gap-1'>
|
<button
|
||||||
|
className='btn btn-outline-dark btn-sm d-flex align-items-center gap-1'
|
||||||
|
onClick={handleRequestAccess}
|
||||||
|
>
|
||||||
<SvgIcon className={'key'} />
|
<SvgIcon className={'key'} />
|
||||||
申请权限
|
申请权限
|
||||||
</button>
|
</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user