space-card.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import { apiInterceptors, delSpace, newDialogue } from '@/client/api';
  2. import { ISpace } from '@/types/knowledge';
  3. import { ClockCircleOutlined, DeleteFilled, MessageFilled, UserOutlined, WarningOutlined } from '@ant-design/icons';
  4. import { Badge, ConfigProvider, Modal, Popover } from 'antd';
  5. import moment from 'moment';
  6. import { useRouter } from 'next/router';
  7. import { useTranslation } from 'react-i18next';
  8. import GptCard from '../common/gpt-card';
  9. import DocPanel from './doc-panel';
  10. interface IProps {
  11. space: ISpace;
  12. onAddDoc: (spaceName: string) => void;
  13. getSpaces: () => void;
  14. }
  15. const { confirm } = Modal;
  16. export default function SpaceCard(props: IProps) {
  17. const router = useRouter();
  18. const { t } = useTranslation();
  19. const { space, getSpaces } = props;
  20. const showDeleteConfirm = () => {
  21. confirm({
  22. title: t('Tips'),
  23. icon: <WarningOutlined />,
  24. content: `${t('Del_Knowledge_Tips')}?`,
  25. okText: 'Yes',
  26. okType: 'danger',
  27. cancelText: 'No',
  28. async onOk() {
  29. await apiInterceptors(delSpace({ name: space?.name }));
  30. getSpaces();
  31. },
  32. });
  33. };
  34. function onDeleteDoc() {
  35. getSpaces();
  36. }
  37. const handleChat = async () => {
  38. const [_, data] = await apiInterceptors(
  39. newDialogue({
  40. chat_mode: 'chat_knowledge',
  41. }),
  42. );
  43. if (data?.conv_uid) {
  44. router.push(`/chat?scene=chat_knowledge&id=${data?.conv_uid}&db_param=${space.name}`);
  45. }
  46. };
  47. return (
  48. <ConfigProvider
  49. theme={{
  50. components: {
  51. Popover: {
  52. zIndexPopup: 90,
  53. },
  54. },
  55. }}
  56. >
  57. <Popover
  58. className='cursor-pointer'
  59. placement='bottom'
  60. trigger='click'
  61. content={<DocPanel space={space} onAddDoc={props.onAddDoc} onDeleteDoc={onDeleteDoc} />}
  62. >
  63. <Badge className='mb-4 min-w-[200px] sm:w-60 lg:w-72' count={space.docs || 0}>
  64. <GptCard
  65. title={space.name}
  66. desc={space.desc}
  67. icon={
  68. space.domain_type === 'FinancialReport'
  69. ? '/models/fin_report.jpg'
  70. : space.vector_type === 'KnowledgeGraph'
  71. ? '/models/knowledge-graph.png'
  72. : space.vector_type === 'FullText'
  73. ? '/models/knowledge-full-text.jpg'
  74. : '/models/knowledge-default.jpg'
  75. }
  76. iconBorder={false}
  77. tags={[
  78. {
  79. text: (
  80. <>
  81. <UserOutlined className='mr-1' />
  82. {space?.owner}
  83. </>
  84. ),
  85. },
  86. {
  87. text: (
  88. <>
  89. <ClockCircleOutlined className='mr-1' />
  90. {moment(space.gmt_modified).format('YYYY-MM-DD')}
  91. </>
  92. ),
  93. },
  94. ]}
  95. operations={[
  96. {
  97. label: t('Chat'),
  98. children: <MessageFilled />,
  99. onClick: handleChat,
  100. },
  101. {
  102. label: t('Delete'),
  103. children: <DeleteFilled />,
  104. onClick: () => {
  105. showDeleteConfirm();
  106. },
  107. },
  108. ]}
  109. />
  110. </Badge>
  111. </Popover>
  112. </ConfigProvider>
  113. );
  114. }