mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-01-01 17:45:28 +08:00
### What problem does this PR solve? Feat: Refactoring the documentation page using shadcn. #10427 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1,11 +1,23 @@
|
||||
import CopyToClipboard from '@/components/copy-to-clipboard';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { IToken } from '@/interfaces/database/chat';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import type { TableProps } from 'antd';
|
||||
import { Button, Modal, Space, Table } from 'antd';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { useOperateApiKey } from '../hooks';
|
||||
|
||||
const ChatApiKeyModal = ({
|
||||
@ -17,57 +29,59 @@ const ChatApiKeyModal = ({
|
||||
useOperateApiKey(idKey, dialogId);
|
||||
const { t } = useTranslate('chat');
|
||||
|
||||
const columns: TableProps<IToken>['columns'] = [
|
||||
{
|
||||
title: 'Token',
|
||||
dataIndex: 'token',
|
||||
key: 'token',
|
||||
render: (text) => <a>{text}</a>,
|
||||
},
|
||||
{
|
||||
title: t('created'),
|
||||
dataIndex: 'create_date',
|
||||
key: 'create_date',
|
||||
render: (text) => formatDate(text),
|
||||
},
|
||||
{
|
||||
title: t('action'),
|
||||
key: 'action',
|
||||
render: (_, record) => (
|
||||
<Space size="middle">
|
||||
<CopyToClipboard text={record.token}></CopyToClipboard>
|
||||
<DeleteOutlined onClick={() => removeToken(record.token)} />
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title={t('apiKey')}
|
||||
open
|
||||
onCancel={hideModal}
|
||||
cancelButtonProps={{ style: { display: 'none' } }}
|
||||
style={{ top: 300 }}
|
||||
onOk={hideModal}
|
||||
width={'50vw'}
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={tokenList}
|
||||
rowKey={'token'}
|
||||
loading={listLoading}
|
||||
pagination={false}
|
||||
/>
|
||||
<Button
|
||||
onClick={createToken}
|
||||
loading={creatingLoading}
|
||||
disabled={tokenList?.length > 0}
|
||||
>
|
||||
{t('createNewKey')}
|
||||
</Button>
|
||||
</Modal>
|
||||
<Dialog open onOpenChange={hideModal}>
|
||||
<DialogContent className="max-w-[50vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('apiKey')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
{listLoading ? (
|
||||
<div className="flex justify-center py-8">Loading...</div>
|
||||
) : (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Token</TableHead>
|
||||
<TableHead>{t('created')}</TableHead>
|
||||
<TableHead>{t('action')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{tokenList?.map((tokenItem) => (
|
||||
<TableRow key={tokenItem.token}>
|
||||
<TableCell className="font-medium break-all">
|
||||
{tokenItem.token}
|
||||
</TableCell>
|
||||
<TableCell>{formatDate(tokenItem.create_date)}</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<CopyToClipboard text={tokenItem.token} />
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => removeToken(tokenItem.token)}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
<Button
|
||||
onClick={createToken}
|
||||
loading={creatingLoading}
|
||||
disabled={tokenList?.length > 0}
|
||||
>
|
||||
{t('createNewKey')}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
import React, { useSyncExternalStore } from 'react';
|
||||
|
||||
export interface AnchorItem {
|
||||
key: string;
|
||||
href: string;
|
||||
title: string;
|
||||
children?: AnchorItem[];
|
||||
}
|
||||
|
||||
interface SimpleAnchorProps {
|
||||
items: AnchorItem[];
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// Subscribe to URL hash changes
|
||||
const subscribeHash = (callback: () => void) => {
|
||||
window.addEventListener('hashchange', callback);
|
||||
return () => window.removeEventListener('hashchange', callback);
|
||||
};
|
||||
|
||||
const getHash = () => window.location.hash;
|
||||
|
||||
const Anchor: React.FC<SimpleAnchorProps> = ({
|
||||
items,
|
||||
className = '',
|
||||
style = {},
|
||||
}) => {
|
||||
// Sync with URL hash changes, to highlight the active item
|
||||
const hash = useSyncExternalStore(subscribeHash, getHash);
|
||||
|
||||
// Handle menu item click
|
||||
const handleClick = (
|
||||
e: React.MouseEvent<HTMLAnchorElement>,
|
||||
href: string,
|
||||
) => {
|
||||
e.preventDefault();
|
||||
const targetId = href.replace('#', '');
|
||||
const targetElement = document.getElementById(targetId);
|
||||
|
||||
if (targetElement) {
|
||||
// Update URL hash (triggers hashchange event)
|
||||
window.location.hash = href;
|
||||
// Smooth scroll to target
|
||||
targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
};
|
||||
|
||||
if (items.length === 0) return null;
|
||||
|
||||
return (
|
||||
<nav className={className} style={style}>
|
||||
<ul className="list-none p-0 m-0">
|
||||
{items.map((item) => (
|
||||
<li key={item.key} className="mb-2">
|
||||
<a
|
||||
href={item.href}
|
||||
onClick={(e) => handleClick(e, item.href)}
|
||||
className={`block px-3 py-1.5 no-underline rounded cursor-pointer transition-all duration-300 hover:text-accent-primary/70 ${
|
||||
hash === item.href
|
||||
? 'text-accent-primary bg-accent-primary-5'
|
||||
: 'text-text-secondary bg-transparent'
|
||||
}`}
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
{item.children && item.children.length > 0 && (
|
||||
<ul className="list-none p-0 ml-4 mt-1">
|
||||
{item.children.map((child) => (
|
||||
<li key={child.key} className="mb-1">
|
||||
<a
|
||||
href={child.href}
|
||||
onClick={(e) => handleClick(e, child.href)}
|
||||
className={`block px-3 py-1 text-sm no-underline rounded cursor-pointer transition-all duration-300 hover:text-accent-primary/70 ${
|
||||
hash === child.href
|
||||
? 'text-accent-primary bg-accent-primary-5'
|
||||
: 'text-text-secondary bg-transparent'
|
||||
}`}
|
||||
>
|
||||
{child.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Anchor;
|
||||
@ -1,52 +1,26 @@
|
||||
import { useIsDarkTheme } from '@/components/theme-provider';
|
||||
import { useSetModalState, useTranslate } from '@/hooks/common-hooks';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { LangfuseCard } from '@/pages/user-setting/setting-model/langfuse';
|
||||
import apiDoc from '@parent/docs/references/http_api_reference.md';
|
||||
import MarkdownPreview from '@uiw/react-markdown-preview';
|
||||
import { Button, Card, Flex, Space } from 'antd';
|
||||
import ChatApiKeyModal from '../chat-api-key-modal';
|
||||
import { usePreviewChat } from '../hooks';
|
||||
import BackendServiceApi from './backend-service-api';
|
||||
import MarkdownToc from './markdown-toc';
|
||||
|
||||
const ApiContent = ({
|
||||
id,
|
||||
idKey,
|
||||
hideChatPreviewCard = false,
|
||||
}: {
|
||||
id?: string;
|
||||
idKey: string;
|
||||
hideChatPreviewCard?: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslate('chat');
|
||||
const ApiContent = ({ id, idKey }: { id?: string; idKey: string }) => {
|
||||
const {
|
||||
visible: apiKeyVisible,
|
||||
hideModal: hideApiKeyModal,
|
||||
showModal: showApiKeyModal,
|
||||
} = useSetModalState();
|
||||
// const { embedVisible, hideEmbedModal, showEmbedModal, embedToken } =
|
||||
// useShowEmbedModal(idKey);
|
||||
|
||||
const { handlePreview } = usePreviewChat(idKey);
|
||||
|
||||
const isDarkTheme = useIsDarkTheme();
|
||||
|
||||
return (
|
||||
<div className="pb-2">
|
||||
<Flex vertical gap={'middle'}>
|
||||
<section className="flex flex-col gap-2 pb-5">
|
||||
<BackendServiceApi show={showApiKeyModal}></BackendServiceApi>
|
||||
{!hideChatPreviewCard && (
|
||||
<Card title={`${name} Web App`}>
|
||||
<Flex gap={8} vertical>
|
||||
<Space size={'middle'}>
|
||||
<Button onClick={handlePreview}>{t('preview')}</Button>
|
||||
{/* <Button onClick={() => showEmbedModal(id)}>
|
||||
{t('embedded')}
|
||||
</Button> */}
|
||||
</Space>
|
||||
</Flex>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<div style={{ position: 'relative' }}>
|
||||
<MarkdownToc content={apiDoc} />
|
||||
</div>
|
||||
@ -54,7 +28,8 @@ const ApiContent = ({
|
||||
source={apiDoc}
|
||||
wrapperElement={{ 'data-color-mode': isDarkTheme ? 'dark' : 'light' }}
|
||||
></MarkdownPreview>
|
||||
</Flex>
|
||||
</section>
|
||||
<LangfuseCard></LangfuseCard>
|
||||
{apiKeyVisible && (
|
||||
<ChatApiKeyModal
|
||||
hideModal={hideApiKeyModal}
|
||||
@ -62,14 +37,6 @@ const ApiContent = ({
|
||||
idKey={idKey}
|
||||
></ChatApiKeyModal>
|
||||
)}
|
||||
{/* {embedVisible && (
|
||||
<EmbedModal
|
||||
token={embedToken}
|
||||
visible={embedVisible}
|
||||
hideModal={hideEmbedModal}
|
||||
></EmbedModal>
|
||||
)} */}
|
||||
<LangfuseCard></LangfuseCard>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,33 +1,28 @@
|
||||
import { Button, Card, Flex, Space, Typography } from 'antd';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
|
||||
import { CopyToClipboardWithText } from '@/components/copy-to-clipboard';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
|
||||
const BackendServiceApi = ({ show }: { show(): void }) => {
|
||||
const { t } = useTranslate('chat');
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={
|
||||
<Space size={'large'}>
|
||||
<span>RAGFlow API</span>
|
||||
<Button onClick={show} type="primary">
|
||||
{t('apiKey')}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Flex gap={8} align="center">
|
||||
<b>{t('backendServiceApi')}</b>
|
||||
<Paragraph
|
||||
copyable={{ text: `${location.origin}` }}
|
||||
className={styles.apiLinkText}
|
||||
>
|
||||
{location.origin}
|
||||
</Paragraph>
|
||||
</Flex>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-4">
|
||||
<CardTitle>RAGFlow API</CardTitle>
|
||||
<Button onClick={show}>{t('apiKey')}</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center gap-2">
|
||||
<b className="font-semibold">{t('backendServiceApi')}</b>
|
||||
<CopyToClipboardWithText
|
||||
text={location.origin}
|
||||
></CopyToClipboardWithText>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { Modal } from 'antd';
|
||||
import ApiContent from './api-content';
|
||||
|
||||
const ChatOverviewModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
id,
|
||||
idKey,
|
||||
}: IModalProps<any> & { id: string; name?: string; idKey: string }) => {
|
||||
const { t } = useTranslate('chat');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title={t('overview')}
|
||||
open={visible}
|
||||
onCancel={hideModal}
|
||||
cancelButtonProps={{ style: { display: 'none' } }}
|
||||
onOk={hideModal}
|
||||
width={'100vw'}
|
||||
okText={t('close', { keyPrefix: 'common' })}
|
||||
>
|
||||
<ApiContent id={id} idKey={idKey}></ApiContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatOverviewModal;
|
||||
@ -1,21 +1,27 @@
|
||||
import { Anchor } from 'antd';
|
||||
import type { AnchorLinkItemProps } from 'antd/es/anchor/Anchor';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Anchor, { AnchorItem } from './anchor';
|
||||
|
||||
interface MarkdownTocProps {
|
||||
content: string;
|
||||
}
|
||||
|
||||
const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => {
|
||||
const [items, setItems] = useState<AnchorLinkItemProps[]>([]);
|
||||
const [items, setItems] = useState<AnchorItem[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const generateTocItems = () => {
|
||||
const headings = document.querySelectorAll(
|
||||
'.wmde-markdown h2, .wmde-markdown h3',
|
||||
);
|
||||
const tocItems: AnchorLinkItemProps[] = [];
|
||||
let currentH2Item: AnchorLinkItemProps | null = null;
|
||||
|
||||
// If headings haven't rendered yet, wait for next frame
|
||||
if (headings.length === 0) {
|
||||
requestAnimationFrame(generateTocItems);
|
||||
return;
|
||||
}
|
||||
|
||||
const tocItems: AnchorItem[] = [];
|
||||
let currentH2Item: AnchorItem | null = null;
|
||||
|
||||
headings.forEach((heading) => {
|
||||
const title = heading.textContent || '';
|
||||
@ -23,7 +29,7 @@ const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => {
|
||||
const isH2 = heading.tagName.toLowerCase() === 'h2';
|
||||
|
||||
if (id && title) {
|
||||
const item: AnchorLinkItemProps = {
|
||||
const item: AnchorItem = {
|
||||
key: id,
|
||||
href: `#${id}`,
|
||||
title,
|
||||
@ -48,7 +54,10 @@ const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => {
|
||||
setItems(tocItems.slice(1));
|
||||
};
|
||||
|
||||
setTimeout(generateTocItems, 100);
|
||||
// Use requestAnimationFrame to ensure execution after DOM rendering
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(generateTocItems);
|
||||
});
|
||||
}, [content]);
|
||||
|
||||
return (
|
||||
@ -56,7 +65,7 @@ const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => {
|
||||
className="markdown-toc bg-bg-base text-text-primary shadow shadow-text-secondary"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: 20,
|
||||
right: 30,
|
||||
top: 100,
|
||||
bottom: 150,
|
||||
width: 200,
|
||||
@ -66,7 +75,7 @@ const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => {
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
<Anchor items={items} affix={false} />
|
||||
<Anchor items={items} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
.codeCard {
|
||||
.clearCardBody();
|
||||
}
|
||||
|
||||
.codeText {
|
||||
padding: 10px;
|
||||
background-color: #ffffff09;
|
||||
}
|
||||
|
||||
.id {
|
||||
.linkText();
|
||||
}
|
||||
|
||||
.darkBg {
|
||||
background-color: rgb(69, 68, 68);
|
||||
}
|
||||
|
||||
.darkId {
|
||||
color: white;
|
||||
.darkBg();
|
||||
}
|
||||
@ -1,170 +0,0 @@
|
||||
import CopyToClipboard from '@/components/copy-to-clipboard';
|
||||
import HighLightMarkdown from '@/components/highlight-markdown';
|
||||
import { SharedFrom } from '@/constants/chat';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import {
|
||||
Card,
|
||||
Checkbox,
|
||||
Form,
|
||||
Modal,
|
||||
Select,
|
||||
Tabs,
|
||||
TabsProps,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { useIsDarkTheme } from '@/components/theme-provider';
|
||||
import {
|
||||
LanguageAbbreviation,
|
||||
LanguageAbbreviationMap,
|
||||
} from '@/constants/common';
|
||||
import { cn } from '@/lib/utils';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Paragraph, Link } = Typography;
|
||||
|
||||
const EmbedModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
token = '',
|
||||
form,
|
||||
beta = '',
|
||||
isAgent,
|
||||
}: IModalProps<any> & {
|
||||
token: string;
|
||||
form: SharedFrom;
|
||||
beta: string;
|
||||
isAgent: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslate('chat');
|
||||
const isDarkTheme = useIsDarkTheme();
|
||||
|
||||
const [visibleAvatar, setVisibleAvatar] = useState(false);
|
||||
const [locale, setLocale] = useState('');
|
||||
|
||||
const languageOptions = useMemo(() => {
|
||||
return Object.values(LanguageAbbreviation).map((x) => ({
|
||||
label: LanguageAbbreviationMap[x],
|
||||
value: x,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const generateIframeSrc = () => {
|
||||
let src = `${location.origin}/chat/share?shared_id=${token}&from=${form}&auth=${beta}`;
|
||||
if (visibleAvatar) {
|
||||
src += '&visible_avatar=1';
|
||||
}
|
||||
if (locale) {
|
||||
src += `&locale=${locale}`;
|
||||
}
|
||||
return src;
|
||||
};
|
||||
|
||||
const iframeSrc = generateIframeSrc();
|
||||
|
||||
const text = `
|
||||
~~~ html
|
||||
<iframe
|
||||
src="${iframeSrc}"
|
||||
style="width: 100%; height: 100%; min-height: 600px"
|
||||
frameborder="0"
|
||||
>
|
||||
</iframe>
|
||||
~~~
|
||||
`;
|
||||
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: t('fullScreenTitle'),
|
||||
children: (
|
||||
<Card
|
||||
title={t('fullScreenDescription')}
|
||||
extra={<CopyToClipboard text={text}></CopyToClipboard>}
|
||||
className={styles.codeCard}
|
||||
>
|
||||
<div className="p-2">
|
||||
<h2 className="mb-3">Option:</h2>
|
||||
|
||||
<Form.Item
|
||||
label={t('avatarHidden')}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<Checkbox
|
||||
checked={visibleAvatar}
|
||||
onChange={(e) => setVisibleAvatar(e.target.checked)}
|
||||
></Checkbox>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t('locale')}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="Select a locale"
|
||||
onChange={(value) => setLocale(value)}
|
||||
options={languageOptions}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<HighLightMarkdown>{text}</HighLightMarkdown>
|
||||
</Card>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: t('partialTitle'),
|
||||
children: t('comingSoon'),
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: t('extensionTitle'),
|
||||
children: t('comingSoon'),
|
||||
},
|
||||
];
|
||||
|
||||
const onChange = (key: string) => {
|
||||
console.log(key);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('embedIntoSite', { keyPrefix: 'common' })}
|
||||
open={visible}
|
||||
style={{ top: 300 }}
|
||||
width={'50vw'}
|
||||
onOk={hideModal}
|
||||
onCancel={hideModal}
|
||||
>
|
||||
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
|
||||
<div className="text-base font-medium mt-4 mb-1">
|
||||
{t(isAgent ? 'flow' : 'chat', { keyPrefix: 'header' })}
|
||||
<span className="ml-1 inline-block">ID</span>
|
||||
</div>
|
||||
<Paragraph
|
||||
copyable={{ text: token }}
|
||||
className={cn(styles.id, {
|
||||
[styles.darkId]: isDarkTheme,
|
||||
})}
|
||||
>
|
||||
{token}
|
||||
</Paragraph>
|
||||
<Link
|
||||
href={
|
||||
isAgent
|
||||
? 'https://ragflow.io/docs/dev/http_api_reference#create-session-with-agent'
|
||||
: 'https://ragflow.io/docs/dev/http_api_reference#create-session-with-chat-assistant'
|
||||
}
|
||||
target="_blank"
|
||||
>
|
||||
{t('howUseId', { keyPrefix: isAgent ? 'flow' : 'chat' })}
|
||||
</Link>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmbedModal;
|
||||
@ -1,4 +1,3 @@
|
||||
import { SharedFrom } from '@/constants/chat';
|
||||
import {
|
||||
useSetModalState,
|
||||
useShowDeleteConfirm,
|
||||
@ -80,11 +79,6 @@ export const useShowBetaEmptyError = () => {
|
||||
return { showBetaEmptyError };
|
||||
};
|
||||
|
||||
const getUrlWithToken = (token: string, from: string = 'chat') => {
|
||||
const { protocol, host } = window.location;
|
||||
return `${protocol}//${host}/chat/share?shared_id=${token}&from=${from}`;
|
||||
};
|
||||
|
||||
const useFetchTokenListBeforeOtherStep = () => {
|
||||
const { showTokenEmptyError } = useShowTokenEmptyError();
|
||||
const { showBetaEmptyError } = useShowBetaEmptyError();
|
||||
@ -149,31 +143,3 @@ export const useShowEmbedModal = () => {
|
||||
beta,
|
||||
};
|
||||
};
|
||||
|
||||
export const usePreviewChat = (idKey: string) => {
|
||||
const { handleOperate } = useFetchTokenListBeforeOtherStep();
|
||||
|
||||
const open = useCallback(
|
||||
(t: string) => {
|
||||
window.open(
|
||||
getUrlWithToken(
|
||||
t,
|
||||
idKey === 'canvasId' ? SharedFrom.Agent : SharedFrom.Chat,
|
||||
),
|
||||
'_blank',
|
||||
);
|
||||
},
|
||||
[idKey],
|
||||
);
|
||||
|
||||
const handlePreview = useCallback(async () => {
|
||||
const token = await handleOperate();
|
||||
if (token) {
|
||||
open(token);
|
||||
}
|
||||
}, [handleOperate, open]);
|
||||
|
||||
return {
|
||||
handlePreview,
|
||||
};
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@ import styles from './index.less';
|
||||
const ApiPage = () => {
|
||||
return (
|
||||
<div className={styles.apiWrapper}>
|
||||
<ApiContent idKey="dialogId" hideChatPreviewCard></ApiContent>
|
||||
<ApiContent idKey="dialogId"></ApiContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -45,11 +45,7 @@ export function LangfuseCard() {
|
||||
<Eye /> {t('setting.view')}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
size={'sm'}
|
||||
onClick={showSaveLangfuseConfigurationModal}
|
||||
className="bg-blue-500 hover:bg-blue-400"
|
||||
>
|
||||
<Button size={'sm'} onClick={showSaveLangfuseConfigurationModal}>
|
||||
<Settings2 />
|
||||
{t('setting.configuration')}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user