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:
@ -48,7 +48,11 @@ const MarkdownContent = ({
|
||||
const { setDocumentIds, data: fileThumbnails } =
|
||||
useFetchDocumentThumbnailsByIds();
|
||||
const contentWithCursor = useMemo(() => {
|
||||
let text = DOMPurify.sanitize(content);
|
||||
let text = DOMPurify.sanitize(content, {
|
||||
ADD_TAGS: ['think', 'section'],
|
||||
ADD_ATTR: ['class'],
|
||||
});
|
||||
|
||||
// let text = content;
|
||||
if (text === '') {
|
||||
text = t('chat.searching');
|
||||
|
||||
@ -44,7 +44,7 @@ const FormatPreserveEditor = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
{['text', 'html'].includes(initialValue.key) && (
|
||||
{['text', 'html', 'markdown'].includes(initialValue.key) && (
|
||||
<ObjectContainer
|
||||
isReadonly={isReadonly}
|
||||
className={className}
|
||||
|
||||
@ -194,7 +194,7 @@ const ParserContainer = (props: IProps) => {
|
||||
|
||||
<div
|
||||
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-180px)]': !isChunck,
|
||||
|
||||
@ -10,5 +10,5 @@ export enum ProcessingType {
|
||||
|
||||
export const ProcessingTypeMap = {
|
||||
[ProcessingType.knowledgeGraph]: 'Knowledge Graph',
|
||||
[ProcessingType.raptor]: 'Raptor',
|
||||
[ProcessingType.raptor]: 'RAPTOR',
|
||||
};
|
||||
|
||||
@ -109,7 +109,9 @@ export const getFileLogsTableColumns = (
|
||||
name={row.original.pipeline_title}
|
||||
className="size-4"
|
||||
/>
|
||||
{row.original.pipeline_title}
|
||||
{row.original.pipeline_title === 'naive'
|
||||
? 'general'
|
||||
: row.original.pipeline_title}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@ -396,7 +398,7 @@ const FileLogsTable: FC<FileLogsTableProps> = ({
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
<TableBody className="relative">
|
||||
<TableBody className="relative min-w-[1280px] overflow-auto">
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
|
||||
@ -100,6 +100,7 @@ export function EmbeddingModelItem({ line = 1, isEdit = true }: IProps) {
|
||||
options={embeddingModelOptions}
|
||||
disabled={isEdit ? disabled : false}
|
||||
placeholder={t('embeddingModelPlaceholder')}
|
||||
triggerClassName="!bg-bg-base"
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
|
||||
@ -20,15 +20,15 @@ export function ApplicationCard({
|
||||
}: ApplicationCardProps) {
|
||||
return (
|
||||
<Card className="w-[264px]" onClick={onClick}>
|
||||
<CardContent className="p-2.5 group flex justify-between">
|
||||
<div className="flex items-center gap-2.5">
|
||||
<CardContent className="p-2.5 group flex justify-between w-full">
|
||||
<div className="flex items-center gap-2.5 w-full">
|
||||
<RAGFlowAvatar
|
||||
className="size-14 rounded-lg"
|
||||
avatar={app.avatar}
|
||||
name={app.title || 'CN'}
|
||||
></RAGFlowAvatar>
|
||||
<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}
|
||||
</h3>
|
||||
<p className="text-xs font-normal text-text-secondary">
|
||||
|
||||
@ -134,7 +134,7 @@ export const BgSvg = () => {
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`w-full -mt-40`}
|
||||
className={`w-full -mt-48`}
|
||||
style={{ height: aspectRatio['middle'] + 'px' }}
|
||||
>
|
||||
{def(
|
||||
@ -144,7 +144,7 @@ export const BgSvg = () => {
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`w-full -mt-52`}
|
||||
className={`w-full -mt-72`}
|
||||
style={{ height: aspectRatio['bottom'] + 'px' }}
|
||||
>
|
||||
{def(
|
||||
|
||||
@ -23,12 +23,12 @@ const FlipCard3D = (props: IProps) => {
|
||||
className={`relative w-full h-full transition-transform transform-style-3d ${isFlipped ? 'rotate-y-180' : ''}`}
|
||||
>
|
||||
{/* 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}
|
||||
</div>
|
||||
|
||||
{/* 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}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -42,6 +42,10 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
.perspective-1000 {
|
||||
perspective: 1000px;
|
||||
overflow: hidden;
|
||||
min-height: 680px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.transform-style-3d {
|
||||
transform-style: preserve-3d;
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { Eye, EyeOff } from 'lucide-react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -135,8 +136,7 @@ const Login = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen relative overflow-hidden">
|
||||
<BgSvg />
|
||||
<>
|
||||
<Spotlight opcity={0.4} coverage={60} color={'rgb(128, 255, 248)'} />
|
||||
<Spotlight
|
||||
opcity={0.3}
|
||||
@ -152,69 +152,56 @@ const Login = () => {
|
||||
Y={'-10%'}
|
||||
color={'rgb(128, 255, 248)'}
|
||||
/>
|
||||
<div className=" h-[inherit] relative overflow-auto">
|
||||
<BgSvg />
|
||||
|
||||
{/* <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="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">
|
||||
<img
|
||||
src={'/logo.svg'}
|
||||
alt="logo"
|
||||
className="size-8 mr-[12] cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xl font-bold self-center">RAGFlow</div>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-center mb-2">{t('title')}</h1>
|
||||
<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('start')}
|
||||
</div>
|
||||
</div>
|
||||
<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 */}
|
||||
|
||||
{/* Login Form */}
|
||||
<FlipCard3D isLoginPage={isLoginPage}>
|
||||
<div className="flex flex-col items-center justify-center w-full">
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-xl font-semibold text-text-primary">
|
||||
{title === 'login' ? t('loginTitle') : t('signUpTitle')}
|
||||
</h2>
|
||||
{/* <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="flex items-center mb-4 w-full pl-10 pt-10 ">
|
||||
<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
|
||||
src={'/logo.svg'}
|
||||
alt="logo"
|
||||
className="size-8 mr-[12] cursor-pointer"
|
||||
/>
|
||||
</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 ">
|
||||
<Form {...form}>
|
||||
<form
|
||||
className="flex flex-col gap-6 text-text-primary"
|
||||
onSubmit={form.handleSubmit((data) => onCheck(data))}
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required>{t('emailLabel')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('emailPlaceholder')}
|
||||
autoComplete="email"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{title === 'register' && (
|
||||
<div className="text-xl font-bold self-center">RAGFlow</div>
|
||||
</div>
|
||||
<h1 className="text-[36px] font-medium text-center mb-2">
|
||||
{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')}
|
||||
</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">
|
||||
{/* Logo and Header */}
|
||||
|
||||
{/* Login Form */}
|
||||
<FlipCard3D isLoginPage={isLoginPage}>
|
||||
<div className="flex flex-col items-center justify-center w-full">
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-xl font-semibold text-text-primary">
|
||||
{title === 'login' ? t('loginTitle') : t('signUpTitle')}
|
||||
</h2>
|
||||
</div>
|
||||
<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
|
||||
className="flex flex-col gap-8 text-text-primary "
|
||||
onSubmit={form.handleSubmit((data) => onCheck(data))}
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nickname"
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required>{t('nicknameLabel')}</FormLabel>
|
||||
<FormLabel required>{t('emailLabel')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('nicknamePlaceholder')}
|
||||
autoComplete="username"
|
||||
placeholder={t('emailPlaceholder')}
|
||||
autoComplete="email"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
@ -222,131 +209,157 @@ const Login = () => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="password"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required>{t('passwordLabel')}</FormLabel>
|
||||
<FormControl>
|
||||
<div className="relative">
|
||||
<Input
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
placeholder={t('passwordPlaceholder')}
|
||||
autoComplete={
|
||||
title === 'login'
|
||||
? 'current-password'
|
||||
: 'new-password'
|
||||
}
|
||||
{...field}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? (
|
||||
<EyeOff className="h-4 w-4 text-gray-500" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4 text-gray-500" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
{title === 'register' && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nickname"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required>{t('nicknameLabel')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('nicknamePlaceholder')}
|
||||
autoComplete="username"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{title === 'login' && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="remember"
|
||||
name="password"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required>{t('passwordLabel')}</FormLabel>
|
||||
<FormControl>
|
||||
<div className="flex gap-2">
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
<div className="relative">
|
||||
<Input
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
placeholder={t('passwordPlaceholder')}
|
||||
autoComplete={
|
||||
title === 'login'
|
||||
? 'current-password'
|
||||
: 'new-password'
|
||||
}
|
||||
{...field}
|
||||
/>
|
||||
<FormLabel>{t('rememberMe')}</FormLabel>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? (
|
||||
<EyeOff className="h-4 w-4 text-gray-500" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4 text-gray-500" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<ButtonLoading
|
||||
type="submit"
|
||||
loading={loading}
|
||||
className="bg-metallic-gradient border-b-[#00BEB4] border-b-2 hover:bg-metallic-gradient hover:border-b-[#02bcdd] w-full my-8"
|
||||
>
|
||||
{title === 'login' ? t('login') : t('continue')}
|
||||
</ButtonLoading>
|
||||
{title === 'login' && channels && channels.length > 0 && (
|
||||
<div className="mt-3 border">
|
||||
{channels.map((item) => (
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
key={item.channel}
|
||||
onClick={() => handleLoginWithChannel(item.channel)}
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<SvgIcon
|
||||
name={item.icon || 'sso'}
|
||||
width={20}
|
||||
height={20}
|
||||
style={{ marginRight: 5 }}
|
||||
/>
|
||||
Sign in with {item.display_name}
|
||||
</div>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
{title === 'login' && registerEnabled && (
|
||||
<div className="mt-6 text-right">
|
||||
<p className="text-text-disabled text-sm">
|
||||
{t('signInTip')}
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
onClick={changeTitle}
|
||||
className="text-cyan-600 hover:text-cyan-800 font-medium border-none transition-colors duration-200"
|
||||
{title === 'login' && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="remember"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<div className="flex gap-2">
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
<FormLabel
|
||||
className={cn(' hover:text-text-primary', {
|
||||
'text-text-disabled': !field.value,
|
||||
'text-text-primary': field.value,
|
||||
})}
|
||||
>
|
||||
{t('rememberMe')}
|
||||
</FormLabel>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<ButtonLoading
|
||||
type="submit"
|
||||
loading={loading}
|
||||
className="bg-metallic-gradient border-b-[#00BEB4] border-b-2 hover:bg-metallic-gradient hover:border-b-[#02bcdd] w-full my-8"
|
||||
>
|
||||
{t('signUp')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{title === 'register' && (
|
||||
<div className="mt-6 text-right">
|
||||
<p className="text-text-disabled text-sm">
|
||||
{t('signUpTip')}
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
onClick={changeTitle}
|
||||
className="text-cyan-600 hover:text-cyan-800 font-medium border-none transition-colors duration-200"
|
||||
>
|
||||
{t('login')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{title === 'login' ? t('login') : t('continue')}
|
||||
</ButtonLoading>
|
||||
{title === 'login' && channels && channels.length > 0 && (
|
||||
<div className="mt-3 border">
|
||||
{channels.map((item) => (
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
key={item.channel}
|
||||
onClick={() => handleLoginWithChannel(item.channel)}
|
||||
style={{ marginTop: 10 }}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<SvgIcon
|
||||
name={item.icon || 'sso'}
|
||||
width={20}
|
||||
height={20}
|
||||
style={{ marginRight: 5 }}
|
||||
/>
|
||||
Sign in with {item.display_name}
|
||||
</div>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
{title === 'login' && registerEnabled && (
|
||||
<div className="mt-10 text-right">
|
||||
<p className="text-text-disabled text-sm">
|
||||
{t('signInTip')}
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
onClick={changeTitle}
|
||||
className="text-accent-primary/90 hover:text-accent-primary hover:bg-transparent font-medium border-none transition-colors duration-200"
|
||||
>
|
||||
{t('signUp')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{title === 'register' && (
|
||||
<div className="mt-10 text-right">
|
||||
<p className="text-text-disabled text-sm">
|
||||
{t('signUpTip')}
|
||||
<Button
|
||||
variant={'transparent'}
|
||||
onClick={changeTitle}
|
||||
className="text-accent-primary/90 hover:text-accent-primary hover:bg-transparent font-medium border-none transition-colors duration-200"
|
||||
>
|
||||
{t('login')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FlipCard3D>
|
||||
</FlipCard3D>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -64,7 +64,10 @@ const MarkdownContent = ({
|
||||
const { setDocumentIds, data: fileThumbnails } =
|
||||
useFetchDocumentThumbnailsByIds();
|
||||
const contentWithCursor = useMemo(() => {
|
||||
let text = DOMPurify.sanitize(content);
|
||||
let text = DOMPurify.sanitize(content, {
|
||||
ADD_TAGS: ['think', 'section'],
|
||||
ADD_ATTR: ['class'],
|
||||
});
|
||||
// let text = content;
|
||||
if (text === '') {
|
||||
text = t('chat.searching');
|
||||
|
||||
Reference in New Issue
Block a user