index.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useState } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import Textarea from 'rc-textarea'
  6. import cn from 'classnames'
  7. import { Robot, User } from '@/app/components/base/icons/src/public/avatar'
  8. import { Edit04, Trash03 } from '@/app/components/base/icons/src/vender/line/general'
  9. import { Edit04 as EditSolid } from '@/app/components/base/icons/src/vender/solid/general'
  10. import Button from '@/app/components/base/button'
  11. export enum EditItemType {
  12. Query = 'query',
  13. Answer = 'answer',
  14. }
  15. type Props = {
  16. type: EditItemType
  17. content: string
  18. readonly?: boolean
  19. onSave: (content: string) => void
  20. }
  21. export const EditTitle: FC<{ className?: string; title: string }> = ({ className, title }) => (
  22. <div className={cn(className, 'flex items-center height-[18px] text-xs font-medium text-gray-500')}>
  23. <EditSolid className='mr-1 w-3.5 h-3.5' />
  24. <div>{title}</div>
  25. <div
  26. className='ml-2 grow h-[1px]'
  27. style={{
  28. background: 'linear-gradient(90deg, rgba(0, 0, 0, 0.05) -1.65%, rgba(0, 0, 0, 0.00) 100%)',
  29. }}
  30. ></div>
  31. </div>
  32. )
  33. const EditItem: FC<Props> = ({
  34. type,
  35. readonly,
  36. content,
  37. onSave,
  38. }) => {
  39. const { t } = useTranslation()
  40. const [newContent, setNewContent] = useState('')
  41. const showNewContent = newContent && newContent !== content
  42. const avatar = type === EditItemType.Query ? <User className='w-6 h-6' /> : <Robot className='w-6 h-6' />
  43. const name = type === EditItemType.Query ? t('appAnnotation.editModal.queryName') : t('appAnnotation.editModal.answerName')
  44. const editTitle = type === EditItemType.Query ? t('appAnnotation.editModal.yourQuery') : t('appAnnotation.editModal.yourAnswer')
  45. const placeholder = type === EditItemType.Query ? t('appAnnotation.editModal.queryPlaceholder') : t('appAnnotation.editModal.answerPlaceholder')
  46. const [isEdit, setIsEdit] = useState(false)
  47. const handleSave = () => {
  48. onSave(newContent)
  49. setIsEdit(false)
  50. }
  51. const handleCancel = () => {
  52. setNewContent('')
  53. setIsEdit(false)
  54. }
  55. return (
  56. <div className='flex' onClick={e => e.stopPropagation()}>
  57. <div className='shrink-0 mr-3'>
  58. {avatar}
  59. </div>
  60. <div className='grow'>
  61. <div className='mb-1 leading-[18px] text-xs font-semibold text-gray-900'>{name}</div>
  62. <div className='leading-5 text-sm font-normal text-gray-900'>{content}</div>
  63. {!isEdit
  64. ? (
  65. <div>
  66. {showNewContent && (
  67. <div className='mt-3'>
  68. <EditTitle title={editTitle} />
  69. <div className='mt-1 leading-5 text-sm font-normal text-gray-900'>{newContent}</div>
  70. </div>
  71. )}
  72. <div className='mt-2 flex items-center'>
  73. {!readonly && (
  74. <div
  75. className='flex items-center space-x-1 leading-[18px] text-xs font-medium text-[#155EEF] cursor-pointer'
  76. onClick={(e) => {
  77. setIsEdit(true)
  78. }}
  79. >
  80. <Edit04 className='mr-1 w-3.5 h-3.5' />
  81. <div>{t('common.operation.edit')}</div>
  82. </div>
  83. )}
  84. {showNewContent && (
  85. <div className='ml-2 flex items-center leading-[18px] text-xs font-medium text-gray-500'>
  86. <div className='mr-2'>·</div>
  87. <div
  88. className='flex items-center space-x-1 cursor-pointer'
  89. onClick={() => {
  90. setNewContent(content)
  91. onSave(content)
  92. }}
  93. >
  94. <div className='w-3.5 h-3.5'>
  95. <Trash03 className='w-3.5 h-3.5' />
  96. </div>
  97. <div>{t('common.operation.delete')}</div>
  98. </div>
  99. </div>
  100. )}
  101. </div>
  102. </div>
  103. )
  104. : (
  105. <div className='mt-3'>
  106. <EditTitle title={editTitle} />
  107. <Textarea
  108. className='mt-1 block w-full leading-5 max-h-none text-sm text-gray-700 outline-none appearance-none resize-none'
  109. value={newContent}
  110. onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setNewContent(e.target.value)}
  111. autoSize={{ minRows: 3 }}
  112. placeholder={placeholder}
  113. autoFocus
  114. />
  115. <div className='mt-2 flex space-x-2'>
  116. <Button className='!h-7 !text-xs !font-medium' type='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
  117. <Button className='!h-7 !text-xs !font-medium' onClick={handleCancel}>{t('common.operation.cancel')}</Button>
  118. </div>
  119. </div>
  120. )}
  121. </div>
  122. </div>
  123. )
  124. }
  125. export default React.memo(EditItem)