Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

card.tsx 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import {
  2. memo,
  3. useCallback,
  4. useRef,
  5. } from 'react'
  6. import { useTranslation } from 'react-i18next'
  7. import Item from './item'
  8. import Configure from './configure'
  9. import type {
  10. DataSourceAuth,
  11. DataSourceCredential,
  12. } from './types'
  13. import { useRenderI18nObject } from '@/hooks/use-i18n'
  14. import { AuthCategory } from '@/app/components/plugins/plugin-auth/types'
  15. import {
  16. ApiKeyModal,
  17. usePluginAuthAction,
  18. } from '@/app/components/plugins/plugin-auth'
  19. import { useDataSourceAuthUpdate } from './hooks'
  20. import Confirm from '@/app/components/base/confirm'
  21. import { useGetDataSourceOAuthUrl } from '@/service/use-datasource'
  22. import { openOAuthPopup } from '@/hooks/use-oauth'
  23. type CardProps = {
  24. item: DataSourceAuth
  25. disabled?: boolean
  26. }
  27. const Card = ({
  28. item,
  29. disabled,
  30. }: CardProps) => {
  31. const { t } = useTranslation()
  32. const renderI18nObject = useRenderI18nObject()
  33. const {
  34. icon,
  35. label,
  36. author,
  37. name,
  38. credentials_list,
  39. credential_schema,
  40. } = item
  41. const pluginPayload = {
  42. category: AuthCategory.datasource,
  43. provider: `${item.plugin_id}/${item.name}`,
  44. }
  45. const { handleAuthUpdate } = useDataSourceAuthUpdate({
  46. pluginId: item.plugin_id,
  47. provider: item.name,
  48. })
  49. const {
  50. deleteCredentialId,
  51. doingAction,
  52. handleConfirm,
  53. handleEdit,
  54. handleRemove,
  55. handleRename,
  56. handleSetDefault,
  57. editValues,
  58. setEditValues,
  59. openConfirm,
  60. closeConfirm,
  61. pendingOperationCredentialId,
  62. } = usePluginAuthAction(pluginPayload, handleAuthUpdate)
  63. const changeCredentialIdRef = useRef<string | undefined>(undefined)
  64. const {
  65. mutateAsync: getPluginOAuthUrl,
  66. } = useGetDataSourceOAuthUrl(pluginPayload.provider)
  67. const handleOAuth = useCallback(async () => {
  68. const { authorization_url } = await getPluginOAuthUrl(changeCredentialIdRef.current)
  69. if (authorization_url) {
  70. openOAuthPopup(
  71. authorization_url,
  72. handleAuthUpdate,
  73. )
  74. }
  75. }, [getPluginOAuthUrl, handleAuthUpdate])
  76. const handleAction = useCallback((
  77. action: string,
  78. credentialItem: DataSourceCredential,
  79. renamePayload?: Record<string, any>,
  80. ) => {
  81. if (action === 'edit') {
  82. handleEdit(
  83. credentialItem.id,
  84. {
  85. ...credentialItem.credential,
  86. __name__: credentialItem.name,
  87. __credential_id__: credentialItem.id,
  88. },
  89. )
  90. }
  91. if (action === 'delete')
  92. openConfirm(credentialItem.id)
  93. if (action === 'setDefault')
  94. handleSetDefault(credentialItem.id)
  95. if (action === 'rename')
  96. handleRename(renamePayload as any)
  97. if (action === 'change') {
  98. changeCredentialIdRef.current = credentialItem.id
  99. handleOAuth()
  100. }
  101. }, [
  102. openConfirm,
  103. handleEdit,
  104. handleSetDefault,
  105. handleRename,
  106. ])
  107. return (
  108. <div className='rounded-xl bg-background-section-burn'>
  109. <div className='flex items-center p-3 pb-2'>
  110. <img
  111. src={icon}
  112. className='mr-3 flex h-10 w-10 shrink-0 items-center justify-center'
  113. />
  114. <div className='grow'>
  115. <div className='system-md-semibold text-text-primary'>
  116. {renderI18nObject(label)}
  117. </div>
  118. <div className='system-xs-regular flex h-4 items-center text-text-tertiary'>
  119. {author}
  120. <div className='mx-0.5 text-text-quaternary'>/</div>
  121. {name}
  122. </div>
  123. </div>
  124. <Configure
  125. pluginPayload={pluginPayload}
  126. item={item}
  127. onUpdate={handleAuthUpdate}
  128. />
  129. </div>
  130. <div className='system-xs-medium flex h-4 items-center pl-3 text-text-tertiary'>
  131. {t('plugin.auth.connectedWorkspace')}
  132. <div className='ml-3 h-[1px] grow bg-divider-subtle'></div>
  133. </div>
  134. {
  135. !!credentials_list.length && (
  136. <div className='space-y-1 p-3 pt-2'>
  137. {
  138. credentials_list.map(credentialItem => (
  139. <Item
  140. key={credentialItem.id}
  141. credentialItem={credentialItem}
  142. onAction={handleAction}
  143. />
  144. ))
  145. }
  146. </div>
  147. )
  148. }
  149. {
  150. !credentials_list.length && (
  151. <div className='p-3 pt-1'>
  152. <div className='system-xs-regular flex h-10 items-center justify-center rounded-[10px] bg-background-section text-text-tertiary'>
  153. {t('plugin.auth.emptyAuth')}
  154. </div>
  155. </div>
  156. )
  157. }
  158. {
  159. deleteCredentialId && (
  160. <Confirm
  161. isShow
  162. title={t('datasetDocuments.list.delete.title')}
  163. isDisabled={doingAction}
  164. onCancel={closeConfirm}
  165. onConfirm={handleConfirm}
  166. />
  167. )
  168. }
  169. {
  170. !!editValues && (
  171. <ApiKeyModal
  172. pluginPayload={pluginPayload}
  173. onClose={() => {
  174. setEditValues(null)
  175. pendingOperationCredentialId.current = null
  176. }}
  177. onUpdate={handleAuthUpdate}
  178. formSchemas={credential_schema}
  179. editValues={editValues}
  180. onRemove={handleRemove}
  181. disabled={disabled || doingAction}
  182. />
  183. )
  184. }
  185. </div>
  186. )
  187. }
  188. export default memo(Card)