clone-project-modal.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { 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. setError(undefined)
  24. }, [])
  25. // close the modal if not in flight
  26. const cancel = useCallback(() => {
  27. if (!inFlight) {
  28. handleHide()
  29. }
  30. }, [handleHide, inFlight])
  31. // valid if the cloned project has a name
  32. const valid = useMemo(() => !!clonedProjectName, [clonedProjectName])
  33. // form submission: clone the project if the name is valid
  34. const handleSubmit = event => {
  35. event.preventDefault()
  36. if (!valid) {
  37. return
  38. }
  39. setError(false)
  40. setInFlight(true)
  41. // clone the project
  42. cloneProject(projectId, clonedProjectName)
  43. .then(data => {
  44. // open the cloned project
  45. openProject(data.project_id)
  46. })
  47. .catch(({ response, data }) => {
  48. if (response.status === 400) {
  49. setError(data.message)
  50. } else {
  51. setError(true)
  52. }
  53. })
  54. .finally(() => {
  55. setInFlight(false)
  56. })
  57. }
  58. return (
  59. <CloneProjectModalContent
  60. show={show}
  61. cancel={cancel}
  62. inFlight={inFlight}
  63. valid={valid}
  64. error={error}
  65. clonedProjectName={clonedProjectName}
  66. setClonedProjectName={setClonedProjectName}
  67. handleSubmit={handleSubmit}
  68. />
  69. )
  70. }
  71. CloneProjectModal.propTypes = {
  72. handleHide: PropTypes.func.isRequired,
  73. projectId: PropTypes.string.isRequired,
  74. projectName: PropTypes.string,
  75. openProject: PropTypes.func.isRequired,
  76. show: PropTypes.bool.isRequired
  77. }
  78. export default CloneProjectModal