Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

authorized-in-node.tsx 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {
  2. memo,
  3. useCallback,
  4. useState,
  5. } from 'react'
  6. import { useTranslation } from 'react-i18next'
  7. import { RiArrowDownSLine } from '@remixicon/react'
  8. import Button from '@/app/components/base/button'
  9. import Indicator from '@/app/components/header/indicator'
  10. import cn from '@/utils/classnames'
  11. import type {
  12. Credential,
  13. PluginPayload,
  14. } from './types'
  15. import {
  16. Authorized,
  17. usePluginAuth,
  18. } from '.'
  19. type AuthorizedInNodeProps = {
  20. pluginPayload: PluginPayload
  21. onAuthorizationItemClick: (id: string) => void
  22. credentialId?: string
  23. }
  24. const AuthorizedInNode = ({
  25. pluginPayload,
  26. onAuthorizationItemClick,
  27. credentialId,
  28. }: AuthorizedInNodeProps) => {
  29. const { t } = useTranslation()
  30. const [isOpen, setIsOpen] = useState(false)
  31. const {
  32. canApiKey,
  33. canOAuth,
  34. credentials,
  35. disabled,
  36. invalidPluginCredentialInfo,
  37. notAllowCustomCredential,
  38. } = usePluginAuth(pluginPayload, isOpen || !!credentialId)
  39. const renderTrigger = useCallback((open?: boolean) => {
  40. let label = ''
  41. let removed = false
  42. let unavailable = false
  43. let color = 'green'
  44. if (!credentialId) {
  45. label = t('plugin.auth.workspaceDefault')
  46. }
  47. else {
  48. const credential = credentials.find(c => c.id === credentialId)
  49. label = credential ? credential.name : t('plugin.auth.authRemoved')
  50. removed = !credential
  51. unavailable = !!credential?.not_allowed_to_use && !credential?.from_enterprise
  52. if (removed)
  53. color = 'red'
  54. else if (unavailable)
  55. color = 'gray'
  56. }
  57. return (
  58. <Button
  59. size='small'
  60. className={cn(
  61. open && !removed && 'bg-components-button-ghost-bg-hover',
  62. removed && 'bg-transparent text-text-destructive',
  63. )}
  64. >
  65. <Indicator
  66. className='mr-1.5'
  67. color={color as any}
  68. />
  69. {label}
  70. {
  71. unavailable && t('plugin.auth.unavailable')
  72. }
  73. <RiArrowDownSLine
  74. className={cn(
  75. 'h-3.5 w-3.5 text-components-button-ghost-text',
  76. removed && 'text-text-destructive',
  77. )}
  78. />
  79. </Button>
  80. )
  81. }, [credentialId, credentials, t])
  82. const extraAuthorizationItems: Credential[] = [
  83. {
  84. id: '__workspace_default__',
  85. name: t('plugin.auth.workspaceDefault'),
  86. provider: '',
  87. is_default: !credentialId,
  88. isWorkspaceDefault: true,
  89. },
  90. ]
  91. const handleAuthorizationItemClick = useCallback((id: string) => {
  92. onAuthorizationItemClick(id)
  93. setIsOpen(false)
  94. }, [
  95. onAuthorizationItemClick,
  96. setIsOpen,
  97. ])
  98. return (
  99. <Authorized
  100. pluginPayload={pluginPayload}
  101. credentials={credentials}
  102. canOAuth={canOAuth}
  103. canApiKey={canApiKey}
  104. renderTrigger={renderTrigger}
  105. isOpen={isOpen}
  106. onOpenChange={setIsOpen}
  107. offset={4}
  108. placement='bottom-end'
  109. triggerPopupSameWidth={false}
  110. popupClassName='w-[360px]'
  111. disabled={disabled}
  112. disableSetDefault
  113. onItemClick={handleAuthorizationItemClick}
  114. extraAuthorizationItems={extraAuthorizationItems}
  115. showItemSelectedIcon
  116. selectedCredentialId={credentialId || '__workspace_default__'}
  117. onUpdate={invalidPluginCredentialInfo}
  118. notAllowCustomCredential={notAllowCustomCredential}
  119. />
  120. )
  121. }
  122. export default memo(AuthorizedInNode)