Files
MemoryBear/web/src/views/Workflow/components/Properties/VariableSelect.tsx
2025-12-29 14:39:57 +08:00

83 lines
2.4 KiB
TypeScript

import { type FC } from 'react'
import { Select, type SelectProps } from 'antd'
import type { Suggestion } from '../Editor/plugin/AutocompletePlugin'
type LabelRender = SelectProps['labelRender'];
interface VariableSelectProps extends SelectProps {
options: Suggestion[];
value?: string;
onChange?: (value: string) => void;
}
const VariableSelect: FC<VariableSelectProps> = ({
placeholder,
options,
value,
onChange,
}) => {
const handleChange = (value: string) => {
onChange?.(value);
}
const labelRender: LabelRender = (props) => {
const { value } = props
const filterOption = options.find(vo => vo.value === value)
if (filterOption) {
return (
<span
className="rb:border rb:border-[#DFE4ED] rb:rounded-md rb:bg-white rb:leading-5.5! rb:text-[12px] rb:inline-flex rb:items-center rb:px-1.5 rb:cursor-pointer"
contentEditable={false}
>
<img
src={filterOption.nodeData?.icon}
style={{ width: '12px', height: '12px', marginRight: '4px' }}
alt=""
/>
{filterOption.nodeData?.name}
<span className="rb:text-[#DFE4ED] rb:mx-0.5">/</span>
<span className="rb:text-[#155EEF]">{filterOption.label}</span>
</span>
)
}
return null
}
const groupedSuggestions = options.reduce((groups: Record<string, any[]>, suggestion) => {
const { nodeData } = suggestion
const nodeId = nodeData.id as string;
if (!groups[nodeId]) {
groups[nodeId] = [];
}
groups[nodeId].push(suggestion);
return groups;
}, {});
const groupedOptions = Object.entries(groupedSuggestions).map(([nodeId, suggestions]) => ({
label: suggestions[0].nodeData.name,
options: suggestions.map(s => ({ label: s.label, value: s.value }))
}));
return (
<Select
placeholder={placeholder}
value={value}
style={{ width: '100%' }}
options={groupedOptions}
labelRender={labelRender}
onChange={handleChange}
showSearch
filterOption={(input, option) => {
if (option?.options) {
return option.label?.toLowerCase().includes(input.toLowerCase()) ||
option.options.some((opt: any) =>
opt.value.toLowerCase().includes(input.toLowerCase())
);
}
return option?.label?.toLowerCase().includes(input.toLowerCase()) ?? false;
}}
/>
)
}
export default VariableSelect