regeneration-modal.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import React, { type FC, useRef, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { RiLoader2Line } from '@remixicon/react'
  4. import { useCountDown } from 'ahooks'
  5. import Modal from '@/app/components/base/modal'
  6. import Button from '@/app/components/base/button'
  7. import { useEventEmitterContextContext } from '@/context/event-emitter'
  8. type IDefaultContentProps = {
  9. onCancel: () => void
  10. onConfirm: () => void
  11. }
  12. const DefaultContent: FC<IDefaultContentProps> = React.memo(({
  13. onCancel,
  14. onConfirm,
  15. }) => {
  16. const { t } = useTranslation()
  17. return (
  18. <>
  19. <div className='pb-4'>
  20. <span className='text-text-primary title-2xl-semi-bold'>{t('datasetDocuments.segment.regenerationConfirmTitle')}</span>
  21. <p className='text-text-secondary system-md-regular'>{t('datasetDocuments.segment.regenerationConfirmMessage')}</p>
  22. </div>
  23. <div className='flex justify-end gap-x-2 pt-6'>
  24. <Button onClick={onCancel}>
  25. {t('common.operation.cancel')}
  26. </Button>
  27. <Button variant='warning' destructive onClick={onConfirm}>
  28. {t('common.operation.regenerate')}
  29. </Button>
  30. </div>
  31. </>
  32. )
  33. })
  34. DefaultContent.displayName = 'DefaultContent'
  35. const RegeneratingContent: FC = React.memo(() => {
  36. const { t } = useTranslation()
  37. return (
  38. <>
  39. <div className='pb-4'>
  40. <span className='text-text-primary title-2xl-semi-bold'>{t('datasetDocuments.segment.regeneratingTitle')}</span>
  41. <p className='text-text-secondary system-md-regular'>{t('datasetDocuments.segment.regeneratingMessage')}</p>
  42. </div>
  43. <div className='flex justify-end pt-6'>
  44. <Button variant='warning' destructive disabled className='inline-flex items-center gap-x-0.5'>
  45. <RiLoader2Line className='w-4 h-4 text-components-button-destructive-primary-text-disabled animate-spin' />
  46. <span>{t('common.operation.regenerate')}</span>
  47. </Button>
  48. </div>
  49. </>
  50. )
  51. })
  52. RegeneratingContent.displayName = 'RegeneratingContent'
  53. type IRegenerationCompletedContentProps = {
  54. onClose: () => void
  55. }
  56. const RegenerationCompletedContent: FC<IRegenerationCompletedContentProps> = React.memo(({
  57. onClose,
  58. }) => {
  59. const { t } = useTranslation()
  60. const targetTime = useRef(Date.now() + 5000)
  61. const [countdown] = useCountDown({
  62. targetDate: targetTime.current,
  63. onEnd: () => {
  64. onClose()
  65. },
  66. })
  67. return (
  68. <>
  69. <div className='pb-4'>
  70. <span className='text-text-primary title-2xl-semi-bold'>{t('datasetDocuments.segment.regenerationSuccessTitle')}</span>
  71. <p className='text-text-secondary system-md-regular'>{t('datasetDocuments.segment.regenerationSuccessMessage')}</p>
  72. </div>
  73. <div className='flex justify-end pt-6'>
  74. <Button variant='primary' onClick={onClose}>
  75. {`${t('common.operation.close')}${countdown === 0 ? '' : `(${Math.round(countdown / 1000)})`}`}
  76. </Button>
  77. </div>
  78. </>
  79. )
  80. })
  81. RegenerationCompletedContent.displayName = 'RegenerationCompletedContent'
  82. type IRegenerationModalProps = {
  83. isShow: boolean
  84. onConfirm: () => void
  85. onCancel: () => void
  86. onClose: () => void
  87. }
  88. const RegenerationModal: FC<IRegenerationModalProps> = ({
  89. isShow,
  90. onConfirm,
  91. onCancel,
  92. onClose,
  93. }) => {
  94. const [loading, setLoading] = useState(false)
  95. const [updateSucceeded, setUpdateSucceeded] = useState(false)
  96. const { eventEmitter } = useEventEmitterContextContext()
  97. eventEmitter?.useSubscription((v) => {
  98. if (v === 'update-segment') {
  99. setLoading(true)
  100. setUpdateSucceeded(false)
  101. }
  102. if (v === 'update-segment-success')
  103. setUpdateSucceeded(true)
  104. if (v === 'update-segment-done')
  105. setLoading(false)
  106. })
  107. return (
  108. <Modal isShow={isShow} onClose={() => {}} className='!max-w-[480px] !rounded-2xl'>
  109. {!loading && !updateSucceeded && <DefaultContent onCancel={onCancel} onConfirm={onConfirm} />}
  110. {loading && !updateSucceeded && <RegeneratingContent />}
  111. {!loading && updateSucceeded && <RegenerationCompletedContent onClose={onClose} />}
  112. </Modal>
  113. )
  114. }
  115. export default RegenerationModal