credential-item.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {
  2. memo,
  3. useMemo,
  4. } from 'react'
  5. import { useTranslation } from 'react-i18next'
  6. import {
  7. RiCheckLine,
  8. RiDeleteBinLine,
  9. RiEqualizer2Line,
  10. } from '@remixicon/react'
  11. import Indicator from '@/app/components/header/indicator'
  12. import ActionButton from '@/app/components/base/action-button'
  13. import Tooltip from '@/app/components/base/tooltip'
  14. import cn from '@/utils/classnames'
  15. import type { Credential } from '../../declarations'
  16. import Badge from '@/app/components/base/badge'
  17. type CredentialItemProps = {
  18. credential: Credential
  19. disabled?: boolean
  20. onDelete?: (credential: Credential) => void
  21. onEdit?: (credential?: Credential) => void
  22. onItemClick?: (credential: Credential) => void
  23. disableRename?: boolean
  24. disableEdit?: boolean
  25. disableDelete?: boolean
  26. disableDeleteButShowAction?: boolean
  27. disableDeleteTip?: string
  28. showSelectedIcon?: boolean
  29. selectedCredentialId?: string
  30. }
  31. const CredentialItem = ({
  32. credential,
  33. disabled,
  34. onDelete,
  35. onEdit,
  36. onItemClick,
  37. disableRename,
  38. disableEdit,
  39. disableDelete,
  40. disableDeleteButShowAction,
  41. disableDeleteTip,
  42. showSelectedIcon,
  43. selectedCredentialId,
  44. }: CredentialItemProps) => {
  45. const { t } = useTranslation()
  46. const showAction = useMemo(() => {
  47. return !(disableRename && disableEdit && disableDelete)
  48. }, [disableRename, disableEdit, disableDelete])
  49. const disableDeleteWhenSelected = useMemo(() => {
  50. return disableDeleteButShowAction && selectedCredentialId === credential.credential_id
  51. }, [disableDeleteButShowAction, selectedCredentialId, credential.credential_id])
  52. const Item = (
  53. <div
  54. key={credential.credential_id}
  55. className={cn(
  56. 'group flex h-8 items-center rounded-lg p-1 hover:bg-state-base-hover',
  57. (disabled || credential.not_allowed_to_use) && 'cursor-not-allowed opacity-50',
  58. )}
  59. onClick={() => {
  60. if (disabled || credential.not_allowed_to_use)
  61. return
  62. onItemClick?.(credential)
  63. }}
  64. >
  65. <div className='flex w-0 grow items-center space-x-1.5'>
  66. {
  67. showSelectedIcon && (
  68. <div className='h-4 w-4'>
  69. {
  70. selectedCredentialId === credential.credential_id && (
  71. <RiCheckLine className='h-4 w-4 text-text-accent' />
  72. )
  73. }
  74. </div>
  75. )
  76. }
  77. <Indicator className='ml-2 mr-1.5 shrink-0' />
  78. <div
  79. className='system-md-regular truncate text-text-secondary'
  80. title={credential.credential_name}
  81. >
  82. {credential.credential_name}
  83. </div>
  84. </div>
  85. {
  86. credential.from_enterprise && (
  87. <Badge className='shrink-0'>
  88. Enterprise
  89. </Badge>
  90. )
  91. }
  92. {
  93. showAction && (
  94. <div className='ml-2 hidden shrink-0 items-center group-hover:flex'>
  95. {
  96. !disableEdit && !credential.not_allowed_to_use && !credential.from_enterprise && (
  97. <Tooltip popupContent={t('common.operation.edit')}>
  98. <ActionButton
  99. disabled={disabled}
  100. onClick={(e) => {
  101. e.stopPropagation()
  102. onEdit?.(credential)
  103. }}
  104. >
  105. <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
  106. </ActionButton>
  107. </Tooltip>
  108. )
  109. }
  110. {
  111. !disableDelete && !credential.from_enterprise && (
  112. <Tooltip popupContent={disableDeleteWhenSelected ? disableDeleteTip : t('common.operation.delete')}>
  113. <ActionButton
  114. className='hover:bg-transparent'
  115. onClick={(e) => {
  116. if (disabled || disableDeleteWhenSelected)
  117. return
  118. e.stopPropagation()
  119. onDelete?.(credential)
  120. }}
  121. >
  122. <RiDeleteBinLine className={cn(
  123. 'h-4 w-4 text-text-tertiary',
  124. !disableDeleteWhenSelected && 'hover:text-text-destructive',
  125. disableDeleteWhenSelected && 'opacity-50',
  126. )} />
  127. </ActionButton>
  128. </Tooltip>
  129. )
  130. }
  131. </div>
  132. )
  133. }
  134. </div>
  135. )
  136. if (credential.not_allowed_to_use) {
  137. return (
  138. <Tooltip popupContent={t('plugin.auth.customCredentialUnavailable')}>
  139. {Item}
  140. </Tooltip>
  141. )
  142. }
  143. return Item
  144. }
  145. export default memo(CredentialItem)