clone-project-modal.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { useCallback, useEffect, useMemo, useState } from 'react'
  2. import PropTypes from 'prop-types'
  3. import { cloneProject } from '../utils/api'
  4. import CloneProjectModalContent from './clone-project-modal-content'
  5. function CloneProjectModal({
  6. show,
  7. handleHide,
  8. projectId,
  9. projectName = '',
  10. openProject,
  11. }) {
  12. const [inFlight, setInFlight] = useState(false)
  13. const [error, setError] = useState()
  14. const [clonedProjectName, setClonedProjectName] = useState('')
  15. // set the cloned project name when the modal opens
  16. useEffect(() => {
  17. if (show) {
  18. setClonedProjectName(`${projectName} (Copy)`)
  19. }
  20. }, [show, projectName])
  21. // reset error when the modal is opened
  22. useEffect(() => {
  23. if (show) {
  24. setError(undefined)
  25. }
  26. }, [show])
  27. // close the modal if not in flight
  28. const cancel = useCallback(() => {
  29. if (!inFlight) {
  30. handleHide()
  31. }
  32. }, [handleHide, inFlight])
  33. // valid if the cloned project has a name
  34. const valid = useMemo(() => !!clonedProjectName, [clonedProjectName])
  35. // form submission: clone the project if the name is valid
  36. const handleSubmit = event => {
  37. event.preventDefault()
  38. if (!valid) {
  39. return
  40. }
  41. setError(false)
  42. setInFlight(true)
  43. // clone the project
  44. cloneProject(projectId, clonedProjectName)
  45. .then(data => {
  46. // open the cloned project
  47. openProject(data.project_id)
  48. })
  49. .catch(({ response, data }) => {
  50. if (response?.status === 400) {
  51. setError(data.message)
  52. } else {
  53. setError(true)
  54. }
  55. })
  56. .finally(() => {
  57. setInFlight(false)
  58. })
  59. }
  60. return (
  61. <CloneProjectModalContent
  62. show={show}
  63. cancel={cancel}
  64. inFlight={inFlight}
  65. valid={valid}
  66. error={error}
  67. clonedProjectName={clonedProjectName}
  68. setClonedProjectName={setClonedProjectName}
  69. handleSubmit={handleSubmit}
  70. />
  71. )
  72. }
  73. CloneProjectModal.propTypes = {
  74. handleHide: PropTypes.func.isRequired,
  75. projectId: PropTypes.string.isRequired,
  76. projectName: PropTypes.string,
  77. openProject: PropTypes.func.isRequired,
  78. show: PropTypes.bool.isRequired,
  79. }
  80. export default CloneProjectModal