endpoint-modal.tsx 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { RiArrowRightUpLine, RiCloseLine } from '@remixicon/react'
  6. import ActionButton from '@/app/components/base/action-button'
  7. import Button from '@/app/components/base/button'
  8. import Drawer from '@/app/components/base/drawer'
  9. import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
  10. import Toast from '@/app/components/base/toast'
  11. import { useRenderI18nObject } from '@/hooks/use-i18n'
  12. import cn from '@/utils/classnames'
  13. type Props = {
  14. formSchemas: any
  15. defaultValues?: any
  16. onCancel: () => void
  17. onSaved: (value: Record<string, any>) => void
  18. }
  19. const EndpointModal: FC<Props> = ({
  20. formSchemas,
  21. defaultValues = {},
  22. onCancel,
  23. onSaved,
  24. }) => {
  25. const getValueFromI18nObject = useRenderI18nObject()
  26. const { t } = useTranslation()
  27. const [tempCredential, setTempCredential] = React.useState<any>(defaultValues)
  28. const handleSave = () => {
  29. for (const field of formSchemas) {
  30. if (field.required && !tempCredential[field.name]) {
  31. Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: getValueFromI18nObject(field.label) }) })
  32. return
  33. }
  34. }
  35. onSaved(tempCredential)
  36. }
  37. return (
  38. <Drawer
  39. isOpen
  40. clickOutsideNotOpen={false}
  41. onClose={onCancel}
  42. footer={null}
  43. mask
  44. positionCenter={false}
  45. panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
  46. >
  47. <>
  48. <div className='p-4 pb-2'>
  49. <div className='flex items-center justify-between'>
  50. <div className='text-text-primary system-xl-semibold'>{t('plugin.detailPanel.endpointModalTitle')}</div>
  51. <ActionButton onClick={onCancel}>
  52. <RiCloseLine className='w-4 h-4' />
  53. </ActionButton>
  54. </div>
  55. <div className='mt-0.5 text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointModalDesc')}</div>
  56. </div>
  57. <div className='grow overflow-y-auto'>
  58. <div className='px-4 py-2'>
  59. <Form
  60. value={tempCredential}
  61. onChange={(v) => {
  62. setTempCredential(v)
  63. }}
  64. formSchemas={formSchemas}
  65. isEditMode={true}
  66. showOnVariableMap={{}}
  67. validating={false}
  68. inputClassName='bg-components-input-bg-normal hover:bg-components-input-bg-hover'
  69. fieldMoreInfo={item => item.url
  70. ? (<a
  71. href={item.url}
  72. target='_blank' rel='noopener noreferrer'
  73. className='inline-flex items-center body-xs-regular text-text-accent-secondary'
  74. >
  75. {t('tools.howToGet')}
  76. <RiArrowRightUpLine className='ml-1 w-3 h-3' />
  77. </a>)
  78. : null}
  79. />
  80. </div>
  81. <div className={cn('p-4 pt-0 flex justify-end')} >
  82. <div className='flex gap-2'>
  83. <Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
  84. <Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
  85. </div>
  86. </div>
  87. </div>
  88. </>
  89. </Drawer>
  90. )
  91. }
  92. export default React.memo(EndpointModal)