mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Fix: Switch the default theme from light mode to dark mode and improve some styles #9869 -Update UI component styles such as input boxes, tables, and prompt boxes -Optimize login page layout and style details -Revise some of the wording, such as uniformly changing "data flow" to "pipeline" -Adjust the parser to support the markdown type ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -104,7 +104,7 @@ const RootProvider = ({ children }: React.PropsWithChildren) => {
|
|||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
defaultTheme={ThemeEnum.Light}
|
defaultTheme={ThemeEnum.Dark}
|
||||||
storageKey="ragflow-ui-theme"
|
storageKey="ragflow-ui-theme"
|
||||||
>
|
>
|
||||||
<Root>{children}</Root>
|
<Root>{children}</Root>
|
||||||
|
|||||||
@ -108,6 +108,7 @@ export function DataFlowSelect(props: IProps) {
|
|||||||
{...field}
|
{...field}
|
||||||
placeholder={t('dataFlowPlaceholder')}
|
placeholder={t('dataFlowPlaceholder')}
|
||||||
options={options}
|
options={options}
|
||||||
|
triggerClassName="!bg-bg-base"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isMult && (
|
{isMult && (
|
||||||
|
|||||||
@ -54,7 +54,10 @@ function MarkdownContent({
|
|||||||
const { setDocumentIds, data: fileThumbnails } =
|
const { setDocumentIds, data: fileThumbnails } =
|
||||||
useFetchDocumentThumbnailsByIds();
|
useFetchDocumentThumbnailsByIds();
|
||||||
const contentWithCursor = useMemo(() => {
|
const contentWithCursor = useMemo(() => {
|
||||||
let text = DOMPurify.sanitize(content);
|
let text = DOMPurify.sanitize(content, {
|
||||||
|
ADD_TAGS: ['think', 'section'],
|
||||||
|
ADD_ATTR: ['class'],
|
||||||
|
});
|
||||||
// let text = content;
|
// let text = content;
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
text = t('chat.searching');
|
text = t('chat.searching');
|
||||||
|
|||||||
@ -21,7 +21,7 @@ const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
|
|||||||
|
|
||||||
export function ThemeProvider({
|
export function ThemeProvider({
|
||||||
children,
|
children,
|
||||||
defaultTheme = ThemeEnum.Light,
|
defaultTheme = ThemeEnum.Dark,
|
||||||
storageKey = 'vite-ui-theme',
|
storageKey = 'vite-ui-theme',
|
||||||
...props
|
...props
|
||||||
}: ThemeProviderProps) {
|
}: ThemeProviderProps) {
|
||||||
|
|||||||
@ -31,7 +31,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex h-8 w-full rounded-md border border-input bg-bg-base px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
'flex h-8 w-full rounded-md border border-input bg-bg-base px-2 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-text-disabled focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const Table = React.forwardRef<
|
|||||||
>(({ className, rootClassName, ...props }, ref) => (
|
>(({ className, rootClassName, ...props }, ref) => (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative w-full overflow-auto rounded-2xl bg-bg-card scrollbar-none',
|
'relative w-full overflow-auto rounded-2xl bg-bg-card scrollbar-auto',
|
||||||
rootClassName,
|
rootClassName,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const TooltipContent = React.forwardRef<
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(
|
className={cn(
|
||||||
'z-50 overflow-auto scrollbar-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-w-[20vw]',
|
'z-50 overflow-auto scrollbar-auto rounded-md whitespace-pre-wrap border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-w-[30vw]',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@ -41,9 +41,7 @@ export const FormTooltip = ({ tooltip }: { tooltip: React.ReactNode }) => {
|
|||||||
>
|
>
|
||||||
<Info className="size-3 ml-2" />
|
<Info className="size-3 ml-2" />
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>{tooltip}</TooltipContent>
|
||||||
<p>{tooltip}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -300,8 +300,8 @@ export default {
|
|||||||
dataFlowPlaceholder: 'Please select a pipeline.',
|
dataFlowPlaceholder: 'Please select a pipeline.',
|
||||||
buildItFromScratch: 'Build it from scratch',
|
buildItFromScratch: 'Build it from scratch',
|
||||||
dataFlow: 'Pipeline',
|
dataFlow: 'Pipeline',
|
||||||
parseType: 'Parse Type',
|
parseType: 'Ingestion pipeline',
|
||||||
manualSetup: 'Manual Setup',
|
manualSetup: 'Choose pipeline',
|
||||||
builtIn: 'Built-in',
|
builtIn: 'Built-in',
|
||||||
titleDescription:
|
titleDescription:
|
||||||
'Update your knowledge base configuration here, particularly the chunking method.',
|
'Update your knowledge base configuration here, particularly the chunking method.',
|
||||||
@ -477,7 +477,8 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
|||||||
useGraphRagTip:
|
useGraphRagTip:
|
||||||
'Construct a knowledge graph over file chunks of the current knowledge base to enhance multi-hop question-answering involving nested logic. See https://ragflow.io/docs/dev/construct_knowledge_graph for details.',
|
'Construct a knowledge graph over file chunks of the current knowledge base to enhance multi-hop question-answering involving nested logic. See https://ragflow.io/docs/dev/construct_knowledge_graph for details.',
|
||||||
graphRagMethod: 'Method',
|
graphRagMethod: 'Method',
|
||||||
graphRagMethodTip: `Light: (Default) Use prompts provided by github.com/HKUDS/LightRAG to extract entities and relationships. This option consumes fewer tokens, less memory, and fewer computational resources.</br>
|
graphRagMethodTip: `
|
||||||
|
Light: (Default) Use prompts provided by github.com/HKUDS/LightRAG to extract entities and relationships. This option consumes fewer tokens, less memory, and fewer computational resources.</br>
|
||||||
General: Use prompts provided by github.com/microsoft/graphrag to extract entities and relationships`,
|
General: Use prompts provided by github.com/microsoft/graphrag to extract entities and relationships`,
|
||||||
resolution: 'Entity resolution',
|
resolution: 'Entity resolution',
|
||||||
resolutionTip: `An entity deduplication switch. When enabled, the LLM will combine similar entities - e.g., '2025' and 'the year of 2025', or 'IT' and 'Information Technology' - to construct a more accurate graph`,
|
resolutionTip: `An entity deduplication switch. When enabled, the LLM will combine similar entities - e.g., '2025' and 'the year of 2025', or 'IT' and 'Information Technology' - to construct a more accurate graph`,
|
||||||
@ -1740,7 +1741,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
overlappedPercent: 'Overlapped percent (%)',
|
overlappedPercent: 'Overlapped percent (%)',
|
||||||
searchMethod: 'Search method',
|
searchMethod: 'Search method',
|
||||||
searchMethodTip: `Defines how the content can be searched — by full-text, embedding, or both.
|
searchMethodTip: `Defines how the content can be searched — by full-text, embedding, or both.
|
||||||
The Tokenizer will store the content in the corresponding data structures for the selected methods.`,
|
The Indexer will store the content in the corresponding data structures for the selected methods.`,
|
||||||
begin: 'File',
|
begin: 'File',
|
||||||
parserMethod: 'Parsing method',
|
parserMethod: 'Parsing method',
|
||||||
systemPrompt: 'System Prompt',
|
systemPrompt: 'System Prompt',
|
||||||
|
|||||||
@ -268,25 +268,25 @@ export default {
|
|||||||
<br/>
|
<br/>
|
||||||
是否要继续?
|
是否要继续?
|
||||||
`,
|
`,
|
||||||
extractRaptor: '从文档中提取Raptor',
|
extractRaptor: '从文档中提取RAPTOR',
|
||||||
extractKnowledgeGraph: '从文档中提取知识图谱',
|
extractKnowledgeGraph: '从文档中提取知识图谱',
|
||||||
filterPlaceholder: '请输入',
|
filterPlaceholder: '请输入',
|
||||||
fileFilterTip: '',
|
fileFilterTip: '',
|
||||||
fileFilter: '正则匹配表达式',
|
fileFilter: '正则匹配表达式',
|
||||||
setDefaultTip: '',
|
setDefaultTip: '',
|
||||||
setDefault: '设置默认',
|
setDefault: '设置默认',
|
||||||
eidtLinkDataPipeline: '编辑数据流',
|
eidtLinkDataPipeline: '编辑pipeline',
|
||||||
linkPipelineSetTip: '管理与此数据集的数据管道链接',
|
linkPipelineSetTip: '管理与此数据集的数据管道链接',
|
||||||
default: '默认',
|
default: '默认',
|
||||||
dataPipeline: '数据流',
|
dataPipeline: 'pipeline',
|
||||||
linkDataPipeline: '关联数据流',
|
linkDataPipeline: '关联pipeline',
|
||||||
enableAutoGenerate: '是否启用自动生成',
|
enableAutoGenerate: '是否启用自动生成',
|
||||||
teamPlaceholder: '请选择团队',
|
teamPlaceholder: '请选择团队',
|
||||||
dataFlowPlaceholder: '请选择数据流',
|
dataFlowPlaceholder: '请选择pipeline',
|
||||||
buildItFromScratch: '去Scratch构建',
|
buildItFromScratch: '去Scratch构建',
|
||||||
dataFlow: '数据流',
|
dataFlow: 'pipeline',
|
||||||
parseType: '切片方法',
|
parseType: 'Ingestion pipeline',
|
||||||
manualSetup: '手动设置',
|
manualSetup: '选择pipeline',
|
||||||
builtIn: '内置',
|
builtIn: '内置',
|
||||||
titleDescription: '在这里更新您的知识库详细信息,尤其是切片方法。',
|
titleDescription: '在这里更新您的知识库详细信息,尤其是切片方法。',
|
||||||
name: '知识库名称',
|
name: '知识库名称',
|
||||||
@ -1611,7 +1611,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
<p>要保留这些更改,请点击“重新运行”以重新运行当前阶段。</p> `,
|
<p>要保留这些更改,请点击“重新运行”以重新运行当前阶段。</p> `,
|
||||||
changeStepModalConfirmText: '继续切换',
|
changeStepModalConfirmText: '继续切换',
|
||||||
changeStepModalCancelText: '取消',
|
changeStepModalCancelText: '取消',
|
||||||
unlinkPipelineModalTitle: '解绑数据流',
|
unlinkPipelineModalTitle: '解绑pipeline',
|
||||||
unlinkPipelineModalContent: `
|
unlinkPipelineModalContent: `
|
||||||
<p>一旦取消链接,该数据集将不再连接到当前数据管道。</p>
|
<p>一旦取消链接,该数据集将不再连接到当前数据管道。</p>
|
||||||
<p>正在解析的文件将继续解析,直到完成。</p>
|
<p>正在解析的文件将继续解析,直到完成。</p>
|
||||||
|
|||||||
@ -48,7 +48,11 @@ const MarkdownContent = ({
|
|||||||
const { setDocumentIds, data: fileThumbnails } =
|
const { setDocumentIds, data: fileThumbnails } =
|
||||||
useFetchDocumentThumbnailsByIds();
|
useFetchDocumentThumbnailsByIds();
|
||||||
const contentWithCursor = useMemo(() => {
|
const contentWithCursor = useMemo(() => {
|
||||||
let text = DOMPurify.sanitize(content);
|
let text = DOMPurify.sanitize(content, {
|
||||||
|
ADD_TAGS: ['think', 'section'],
|
||||||
|
ADD_ATTR: ['class'],
|
||||||
|
});
|
||||||
|
|
||||||
// let text = content;
|
// let text = content;
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
text = t('chat.searching');
|
text = t('chat.searching');
|
||||||
|
|||||||
@ -44,7 +44,7 @@ const FormatPreserveEditor = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{['text', 'html'].includes(initialValue.key) && (
|
{['text', 'html', 'markdown'].includes(initialValue.key) && (
|
||||||
<ObjectContainer
|
<ObjectContainer
|
||||||
isReadonly={isReadonly}
|
isReadonly={isReadonly}
|
||||||
className={className}
|
className={className}
|
||||||
|
|||||||
@ -194,7 +194,7 @@ const ParserContainer = (props: IProps) => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
' border rounded-lg p-[20px] box-border w-[calc(100%-20px)] overflow-auto scrollbar-none',
|
' border rounded-lg p-[20px] box-border w-[calc(100%-20px)] overflow-auto scrollbar-auto',
|
||||||
{
|
{
|
||||||
'h-[calc(100vh-240px)]': isChunck,
|
'h-[calc(100vh-240px)]': isChunck,
|
||||||
'h-[calc(100vh-180px)]': !isChunck,
|
'h-[calc(100vh-180px)]': !isChunck,
|
||||||
|
|||||||
@ -10,5 +10,5 @@ export enum ProcessingType {
|
|||||||
|
|
||||||
export const ProcessingTypeMap = {
|
export const ProcessingTypeMap = {
|
||||||
[ProcessingType.knowledgeGraph]: 'Knowledge Graph',
|
[ProcessingType.knowledgeGraph]: 'Knowledge Graph',
|
||||||
[ProcessingType.raptor]: 'Raptor',
|
[ProcessingType.raptor]: 'RAPTOR',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -109,7 +109,9 @@ export const getFileLogsTableColumns = (
|
|||||||
name={row.original.pipeline_title}
|
name={row.original.pipeline_title}
|
||||||
className="size-4"
|
className="size-4"
|
||||||
/>
|
/>
|
||||||
{row.original.pipeline_title}
|
{row.original.pipeline_title === 'naive'
|
||||||
|
? 'general'
|
||||||
|
: row.original.pipeline_title}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -396,7 +398,7 @@ const FileLogsTable: FC<FileLogsTableProps> = ({
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody className="relative">
|
<TableBody className="relative min-w-[1280px] overflow-auto">
|
||||||
{table.getRowModel().rows?.length ? (
|
{table.getRowModel().rows?.length ? (
|
||||||
table.getRowModel().rows.map((row) => (
|
table.getRowModel().rows.map((row) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
|
|||||||
@ -100,6 +100,7 @@ export function EmbeddingModelItem({ line = 1, isEdit = true }: IProps) {
|
|||||||
options={embeddingModelOptions}
|
options={embeddingModelOptions}
|
||||||
disabled={isEdit ? disabled : false}
|
disabled={isEdit ? disabled : false}
|
||||||
placeholder={t('embeddingModelPlaceholder')}
|
placeholder={t('embeddingModelPlaceholder')}
|
||||||
|
triggerClassName="!bg-bg-base"
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,15 +20,15 @@ export function ApplicationCard({
|
|||||||
}: ApplicationCardProps) {
|
}: ApplicationCardProps) {
|
||||||
return (
|
return (
|
||||||
<Card className="w-[264px]" onClick={onClick}>
|
<Card className="w-[264px]" onClick={onClick}>
|
||||||
<CardContent className="p-2.5 group flex justify-between">
|
<CardContent className="p-2.5 group flex justify-between w-full">
|
||||||
<div className="flex items-center gap-2.5">
|
<div className="flex items-center gap-2.5 w-full">
|
||||||
<RAGFlowAvatar
|
<RAGFlowAvatar
|
||||||
className="size-14 rounded-lg"
|
className="size-14 rounded-lg"
|
||||||
avatar={app.avatar}
|
avatar={app.avatar}
|
||||||
name={app.title || 'CN'}
|
name={app.title || 'CN'}
|
||||||
></RAGFlowAvatar>
|
></RAGFlowAvatar>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h3 className="text-sm font-normal line-clamp-1 mb-1">
|
<h3 className="text-sm font-normal line-clamp-1 mb-1 text-ellipsis w-[180px] overflow-hidden">
|
||||||
{app.title}
|
{app.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-xs font-normal text-text-secondary">
|
<p className="text-xs font-normal text-text-secondary">
|
||||||
|
|||||||
@ -134,7 +134,7 @@ export const BgSvg = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`w-full -mt-40`}
|
className={`w-full -mt-48`}
|
||||||
style={{ height: aspectRatio['middle'] + 'px' }}
|
style={{ height: aspectRatio['middle'] + 'px' }}
|
||||||
>
|
>
|
||||||
{def(
|
{def(
|
||||||
@ -144,7 +144,7 @@ export const BgSvg = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`w-full -mt-52`}
|
className={`w-full -mt-72`}
|
||||||
style={{ height: aspectRatio['bottom'] + 'px' }}
|
style={{ height: aspectRatio['bottom'] + 'px' }}
|
||||||
>
|
>
|
||||||
{def(
|
{def(
|
||||||
|
|||||||
@ -23,12 +23,12 @@ const FlipCard3D = (props: IProps) => {
|
|||||||
className={`relative w-full h-full transition-transform transform-style-3d ${isFlipped ? 'rotate-y-180' : ''}`}
|
className={`relative w-full h-full transition-transform transform-style-3d ${isFlipped ? 'rotate-y-180' : ''}`}
|
||||||
>
|
>
|
||||||
{/* Front Face */}
|
{/* Front Face */}
|
||||||
<div className="absolute inset-0 flex items-center justify-center bg-blue-500 text-white rounded-xl backface-hidden">
|
<div className="absolute inset-0 flex items-center justify-center backface-hidden">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Back Face */}
|
{/* Back Face */}
|
||||||
<div className="absolute inset-0 flex items-center justify-center bg-green-500 text-white rounded-xl backface-hidden rotate-y-180">
|
<div className="absolute inset-0 flex items-center justify-center backface-hidden rotate-y-180">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -42,6 +42,10 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
.perspective-1000 {
|
.perspective-1000 {
|
||||||
perspective: 1000px;
|
perspective: 1000px;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 680px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.transform-style-3d {
|
.transform-style-3d {
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { Eye, EyeOff } from 'lucide-react';
|
import { Eye, EyeOff } from 'lucide-react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
@ -135,8 +136,7 @@ const Login = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen relative overflow-hidden">
|
<>
|
||||||
<BgSvg />
|
|
||||||
<Spotlight opcity={0.4} coverage={60} color={'rgb(128, 255, 248)'} />
|
<Spotlight opcity={0.4} coverage={60} color={'rgb(128, 255, 248)'} />
|
||||||
<Spotlight
|
<Spotlight
|
||||||
opcity={0.3}
|
opcity={0.3}
|
||||||
@ -152,11 +152,13 @@ const Login = () => {
|
|||||||
Y={'-10%'}
|
Y={'-10%'}
|
||||||
color={'rgb(128, 255, 248)'}
|
color={'rgb(128, 255, 248)'}
|
||||||
/>
|
/>
|
||||||
|
<div className=" h-[inherit] relative overflow-auto">
|
||||||
|
<BgSvg />
|
||||||
|
|
||||||
{/* <SpotlightTopRight opcity={0.7} coverage={10} /> */}
|
{/* <SpotlightTopRight opcity={0.7} coverage={10} /> */}
|
||||||
<div className="absolute top-3 flex flex-col items-center mb-12 w-full text-text-primary">
|
<div className="absolute top-3 flex flex-col items-center mb-12 w-full text-text-primary">
|
||||||
<div className="flex items-center mb-4 w-full pl-10 pt-10 ">
|
<div className="flex items-center mb-4 w-full pl-10 pt-10 ">
|
||||||
<div className="w-12 h-12 p-2 rounded-lg border-2 border-border flex items-center justify-center mr-3">
|
<div className="w-12 h-12 p-2 rounded-lg bg-bg-base border-2 border-border flex items-center justify-center mr-3">
|
||||||
<img
|
<img
|
||||||
src={'/logo.svg'}
|
src={'/logo.svg'}
|
||||||
alt="logo"
|
alt="logo"
|
||||||
@ -165,12 +167,15 @@ const Login = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-xl font-bold self-center">RAGFlow</div>
|
<div className="text-xl font-bold self-center">RAGFlow</div>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-2xl font-bold text-center mb-2">{t('title')}</h1>
|
<h1 className="text-[36px] font-medium text-center mb-2">
|
||||||
<div className="mt-4 px-6 py-1 text-sm font-medium text-cyan-600 border border-accent-primary rounded-full hover:bg-cyan-50 transition-colors duration-200 border-glow relative overflow-hidden">
|
{t('title')}
|
||||||
|
</h1>
|
||||||
|
{/* border border-accent-primary rounded-full */}
|
||||||
|
{/* <div className="mt-4 px-6 py-1 text-sm font-medium text-cyan-600 hover:bg-cyan-50 transition-colors duration-200 border-glow relative overflow-hidden">
|
||||||
{t('start')}
|
{t('start')}
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="relative z-10 flex flex-col items-center justify-center min-h-[1050px] px-4 sm:px-6 lg:px-8">
|
||||||
<div className="relative z-10 flex flex-col items-center justify-center min-h-screen px-4 sm:px-6 lg:px-8">
|
|
||||||
{/* Logo and Header */}
|
{/* Logo and Header */}
|
||||||
|
|
||||||
{/* Login Form */}
|
{/* Login Form */}
|
||||||
@ -181,10 +186,10 @@ const Login = () => {
|
|||||||
{title === 'login' ? t('loginTitle') : t('signUpTitle')}
|
{title === 'login' ? t('loginTitle') : t('signUpTitle')}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full max-w-md bg-bg-base backdrop-blur-sm rounded-2xl shadow-xl pt-14 pl-8 pr-8 pb-2 border border-border-button ">
|
<div className=" w-full max-w-[540px] bg-bg-component backdrop-blur-sm rounded-2xl shadow-xl pt-14 pl-10 pr-10 pb-2 border border-border-button ">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
className="flex flex-col gap-6 text-text-primary"
|
className="flex flex-col gap-8 text-text-primary "
|
||||||
onSubmit={form.handleSubmit((data) => onCheck(data))}
|
onSubmit={form.handleSubmit((data) => onCheck(data))}
|
||||||
>
|
>
|
||||||
<FormField
|
<FormField
|
||||||
@ -274,7 +279,14 @@ const Login = () => {
|
|||||||
field.onChange(checked);
|
field.onChange(checked);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<FormLabel>{t('rememberMe')}</FormLabel>
|
<FormLabel
|
||||||
|
className={cn(' hover:text-text-primary', {
|
||||||
|
'text-text-disabled': !field.value,
|
||||||
|
'text-text-primary': field.value,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{t('rememberMe')}
|
||||||
|
</FormLabel>
|
||||||
</div>
|
</div>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@ -315,13 +327,13 @@ const Login = () => {
|
|||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
{title === 'login' && registerEnabled && (
|
{title === 'login' && registerEnabled && (
|
||||||
<div className="mt-6 text-right">
|
<div className="mt-10 text-right">
|
||||||
<p className="text-text-disabled text-sm">
|
<p className="text-text-disabled text-sm">
|
||||||
{t('signInTip')}
|
{t('signInTip')}
|
||||||
<Button
|
<Button
|
||||||
variant={'transparent'}
|
variant={'transparent'}
|
||||||
onClick={changeTitle}
|
onClick={changeTitle}
|
||||||
className="text-cyan-600 hover:text-cyan-800 font-medium border-none transition-colors duration-200"
|
className="text-accent-primary/90 hover:text-accent-primary hover:bg-transparent font-medium border-none transition-colors duration-200"
|
||||||
>
|
>
|
||||||
{t('signUp')}
|
{t('signUp')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -329,13 +341,13 @@ const Login = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{title === 'register' && (
|
{title === 'register' && (
|
||||||
<div className="mt-6 text-right">
|
<div className="mt-10 text-right">
|
||||||
<p className="text-text-disabled text-sm">
|
<p className="text-text-disabled text-sm">
|
||||||
{t('signUpTip')}
|
{t('signUpTip')}
|
||||||
<Button
|
<Button
|
||||||
variant={'transparent'}
|
variant={'transparent'}
|
||||||
onClick={changeTitle}
|
onClick={changeTitle}
|
||||||
className="text-cyan-600 hover:text-cyan-800 font-medium border-none transition-colors duration-200"
|
className="text-accent-primary/90 hover:text-accent-primary hover:bg-transparent font-medium border-none transition-colors duration-200"
|
||||||
>
|
>
|
||||||
{t('login')}
|
{t('login')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -347,6 +359,7 @@ const Login = () => {
|
|||||||
</FlipCard3D>
|
</FlipCard3D>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,10 @@ const MarkdownContent = ({
|
|||||||
const { setDocumentIds, data: fileThumbnails } =
|
const { setDocumentIds, data: fileThumbnails } =
|
||||||
useFetchDocumentThumbnailsByIds();
|
useFetchDocumentThumbnailsByIds();
|
||||||
const contentWithCursor = useMemo(() => {
|
const contentWithCursor = useMemo(() => {
|
||||||
let text = DOMPurify.sanitize(content);
|
let text = DOMPurify.sanitize(content, {
|
||||||
|
ADD_TAGS: ['think', 'section'],
|
||||||
|
ADD_ATTR: ['class'],
|
||||||
|
});
|
||||||
// let text = content;
|
// let text = content;
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
text = t('chat.searching');
|
text = t('chat.searching');
|
||||||
|
|||||||
Reference in New Issue
Block a user