Feat: New search page components and features (#9344)

### What problem does this PR solve?

Feat: New search page components and features #3221

- Added search homepage, search settings, and ongoing search components
- Implemented features such as search app list, creating search apps,
and deleting search apps
- Optimized the multi-select component, adding disabled state and suffix
display
- Adjusted navigation hooks to support search page navigation

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
chanx
2025-08-11 10:34:22 +08:00
committed by GitHub
parent 597d88bf9a
commit 4c7b2ef46e
16 changed files with 1347 additions and 87 deletions

View File

@ -23,8 +23,8 @@ const getColorForName = (name: string): { from: string; to: string } => {
const hue = hash % 360;
return {
from: `hsl(${hue}, 70%, 80%)`,
to: `hsl(${hue}, 60%, 30%)`,
to: `hsl(${hue}, 70%, 80%)`,
from: `hsl(${hue}, 60%, 30%)`,
};
};
export const RAGFlowAvatar = memo(

View File

@ -34,6 +34,7 @@ export type MultiSelectOptionType = {
label: React.ReactNode;
value: string;
disabled?: boolean;
suffix?: React.ReactNode;
icon?: React.ComponentType<{ className?: string }>;
};
@ -54,23 +55,41 @@ function MultiCommandItem({
return (
<CommandItem
key={option.value}
onSelect={() => toggleOption(option.value)}
className="cursor-pointer"
onSelect={() => {
if (option.disabled) return false;
toggleOption(option.value);
}}
className={cn('cursor-pointer', {
'cursor-not-allowed text-text-disabled': option.disabled,
})}
>
<div
className={cn(
'mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary',
isSelected
? 'bg-primary text-primary-foreground'
: 'opacity-50 [&_svg]:invisible',
isSelected ? 'bg-primary ' : 'opacity-50 [&_svg]:invisible',
{ 'text-primary-foreground': !option.disabled },
{ 'text-text-disabled': option.disabled },
)}
>
<CheckIcon className="h-4 w-4" />
</div>
{option.icon && (
<option.icon className="mr-2 h-4 w-4 text-muted-foreground" />
<option.icon
className={cn('mr-2 h-4 w-4 ', {
'text-text-disabled': option.disabled,
'text-muted-foreground': !option.disabled,
})}
/>
)}
<span className={cn({ 'text-text-disabled': option.disabled })}>
{option.label}
</span>
{option.suffix && (
<span className={cn({ 'text-text-disabled': option.disabled })}>
{option.suffix}
</span>
)}
<span>{option.label}</span>
</CommandItem>
);
}
@ -156,6 +175,11 @@ interface MultiSelectProps
* Optional, can be used to add custom styles.
*/
className?: string;
/**
* If true, renders the multi-select component with a select all option.
*/
showSelectAll?: boolean;
}
export const MultiSelect = React.forwardRef<
@ -174,6 +198,7 @@ export const MultiSelect = React.forwardRef<
modalPopover = false,
asChild = false,
className,
showSelectAll = true,
...props
},
ref,
@ -340,23 +365,25 @@ export const MultiSelect = React.forwardRef<
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
<CommandItem
key="all"
onSelect={toggleAll}
className="cursor-pointer"
>
<div
className={cn(
'mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary',
selectedValues.length === flatOptions.length
? 'bg-primary text-primary-foreground'
: 'opacity-50 [&_svg]:invisible',
)}
{showSelectAll && (
<CommandItem
key="all"
onSelect={toggleAll}
className="cursor-pointer"
>
<CheckIcon className="h-4 w-4" />
</div>
<span>(Select All)</span>
</CommandItem>
<div
className={cn(
'mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary',
selectedValues.length === flatOptions.length
? 'bg-primary text-primary-foreground'
: 'opacity-50 [&_svg]:invisible',
)}
>
<CheckIcon className="h-4 w-4" />
</div>
<span>(Select All)</span>
</CommandItem>
)}
{!options.some((x) => 'options' in x) &&
(options as unknown as MultiSelectOptionType[]).map(
(option) => {