index.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import cn from 'classnames'
  5. import { useBoolean, useClickAway } from 'ahooks'
  6. import { ChevronDownIcon } from '@heroicons/react/24/outline'
  7. import { useTranslation } from 'react-i18next'
  8. import ModelIcon from '@/app/components/app/configuration/config-model/model-icon'
  9. import { UNIVERSAL_CHAT_MODEL_LIST as MODEL_LIST } from '@/config'
  10. import { Checked as CheckedIcon } from '@/app/components/base/icons/src/public/model'
  11. export type IModelConfigProps = {
  12. modelId: string
  13. onChange?: (model: string) => void
  14. readonly?: boolean
  15. }
  16. const ModelConfig: FC<IModelConfigProps> = ({
  17. modelId,
  18. onChange,
  19. readonly,
  20. }) => {
  21. const { t } = useTranslation()
  22. const currModel = MODEL_LIST.find(item => item.id === modelId)
  23. const [isShowOption, { setFalse: hideOption, toggle: toogleOption }] = useBoolean(false)
  24. const triggerRef = React.useRef(null)
  25. useClickAway(() => {
  26. hideOption()
  27. }, triggerRef)
  28. return (
  29. <div className='flex items-center justify-between h-[52px] px-3 rounded-xl bg-gray-50'>
  30. <div className='text-sm font-semibold text-gray-800'>{t('explore.universalChat.model')}</div>
  31. <div className="relative z-10">
  32. <div
  33. ref={triggerRef}
  34. onClick={() => !readonly && toogleOption()}
  35. className={cn(
  36. readonly ? 'cursor-not-allowed' : 'cursor-pointer', 'flex items-center h-9 px-3 space-x-2 rounded-lg',
  37. isShowOption && 'bg-gray-100',
  38. )}>
  39. <ModelIcon modelId={currModel?.id as string} />
  40. <div className="text-sm gray-900">{currModel?.name}</div>
  41. {!readonly && <ChevronDownIcon className={cn(isShowOption && 'rotate-180', 'w-[14px] h-[14px] text-gray-500')} />}
  42. </div>
  43. {isShowOption && (
  44. <div className={cn('absolute top-10 right-0 bg-white rounded-lg shadow')}>
  45. {MODEL_LIST.map(item => (
  46. <div key={item.id} onClick={() => onChange?.(item.id)} className="w-[232px] flex items-center h-9 px-4 rounded-lg cursor-pointer hover:bg-gray-100">
  47. <ModelIcon className='shrink-0 mr-2' modelId={item?.id} />
  48. <div className="text-sm gray-900 whitespace-nowrap">{item.name}</div>
  49. {(item.id === currModel?.id) && <CheckedIcon className='absolute right-4' />}
  50. </div>
  51. ))}
  52. </div>
  53. )}
  54. </div>
  55. </div>
  56. )
  57. }
  58. export default React.memo(ModelConfig)