config-credentials.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useEffect, useState } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { addDefaultValue, toolCredentialToFormSchemas } from '../../utils/to-form-schema'
  6. import type { Collection } from '../../types'
  7. import cn from '@/utils/classnames'
  8. import Drawer from '@/app/components/base/drawer-plus'
  9. import Button from '@/app/components/base/button'
  10. import Toast from '@/app/components/base/toast'
  11. import { fetchBuiltInToolCredential, fetchBuiltInToolCredentialSchema } from '@/service/tools'
  12. import Loading from '@/app/components/base/loading'
  13. import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
  14. import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
  15. import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
  16. type Props = {
  17. collection: Collection
  18. onCancel: () => void
  19. onSaved: (value: Record<string, any>) => void
  20. isHideRemoveBtn?: boolean
  21. onRemove?: () => void
  22. isSaving?: boolean
  23. }
  24. const ConfigCredential: FC<Props> = ({
  25. collection,
  26. onCancel,
  27. onSaved,
  28. isHideRemoveBtn,
  29. onRemove = () => { },
  30. isSaving,
  31. }) => {
  32. const { t } = useTranslation()
  33. const language = useLanguage()
  34. const [credentialSchema, setCredentialSchema] = useState<any>(null)
  35. const { name: collectionName } = collection
  36. const [tempCredential, setTempCredential] = React.useState<any>({})
  37. const [isLoading, setIsLoading] = React.useState(false)
  38. useEffect(() => {
  39. fetchBuiltInToolCredentialSchema(collectionName).then(async (res) => {
  40. const toolCredentialSchemas = toolCredentialToFormSchemas(res)
  41. const credentialValue = await fetchBuiltInToolCredential(collectionName)
  42. setTempCredential(credentialValue)
  43. const defaultCredentials = addDefaultValue(credentialValue, toolCredentialSchemas)
  44. setCredentialSchema(toolCredentialSchemas)
  45. setTempCredential(defaultCredentials)
  46. })
  47. }, [])
  48. const handleSave = async () => {
  49. for (const field of credentialSchema) {
  50. if (field.required && !tempCredential[field.name]) {
  51. Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: field.label[language] || field.label.en_US }) })
  52. return
  53. }
  54. }
  55. setIsLoading(true)
  56. try {
  57. await onSaved(tempCredential)
  58. setIsLoading(false)
  59. }
  60. finally {
  61. setIsLoading(false)
  62. }
  63. }
  64. return (
  65. <Drawer
  66. isShow
  67. onHide={onCancel}
  68. title={t('tools.auth.setupModalTitle') as string}
  69. titleDescription={t('tools.auth.setupModalTitleDescription') as string}
  70. panelClassName='mt-[64px] mb-2 !w-[420px] border-components-panel-border'
  71. maxWidthClassName='!max-w-[420px]'
  72. height='calc(100vh - 64px)'
  73. contentClassName='!bg-components-panel-bg'
  74. headerClassName='!border-b-divider-subtle'
  75. body={
  76. <div className='h-full px-6 py-3'>
  77. {!credentialSchema
  78. ? <Loading type='app' />
  79. : (
  80. <>
  81. <Form
  82. value={tempCredential}
  83. onChange={(v) => {
  84. setTempCredential(v)
  85. }}
  86. formSchemas={credentialSchema}
  87. isEditMode={true}
  88. showOnVariableMap={{}}
  89. validating={false}
  90. inputClassName='!bg-components-input-bg-normal'
  91. fieldMoreInfo={item => item.url
  92. ? (<a
  93. href={item.url}
  94. target='_blank' rel='noopener noreferrer'
  95. className='inline-flex items-center text-xs text-text-accent'
  96. >
  97. {t('tools.howToGet')}
  98. <LinkExternal02 className='ml-1 h-3 w-3' />
  99. </a>)
  100. : null}
  101. />
  102. <div className={cn((collection.is_team_authorization && !isHideRemoveBtn) ? 'justify-between' : 'justify-end', 'mt-2 flex ')} >
  103. {
  104. (collection.is_team_authorization && !isHideRemoveBtn) && (
  105. <Button onClick={onRemove}>{t('common.operation.remove')}</Button>
  106. )
  107. }
  108. < div className='flex space-x-2'>
  109. <Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
  110. <Button loading={isLoading || isSaving} disabled={isLoading || isSaving} variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
  111. </div>
  112. </div>
  113. </>
  114. )
  115. }
  116. </div >
  117. }
  118. isShowMask={true}
  119. clickOutsideNotOpen={false}
  120. />
  121. )
  122. }
  123. export default React.memo(ConfigCredential)