clone-project-modal.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import React, { useCallback, useEffect, useState } from 'react'
  2. import { Modal } from 'react-bootstrap'
  3. import PropTypes from 'prop-types'
  4. import CloneProjectModalContent from './clone-project-modal-content'
  5. function CloneProjectModal({ handleHide, show, projectId, projectName }) {
  6. const [inFlight, setInFlight] = useState(false)
  7. const [error, setError] = useState()
  8. // reset error when the modal is opened
  9. useEffect(() => {
  10. if (show) {
  11. setError(undefined)
  12. }
  13. }, [show])
  14. // clone the project when the form is submitted
  15. const cloneProject = useCallback(
  16. cloneName => {
  17. setInFlight(true)
  18. fetch(`/project/${projectId}/clone`, {
  19. method: 'POST',
  20. body: JSON.stringify({
  21. _csrf: window.csrfToken,
  22. projectName: cloneName
  23. }),
  24. headers: {
  25. 'Content-Type': 'application/json'
  26. }
  27. })
  28. .then(async response => {
  29. if (response.ok) {
  30. const { project_id: clonedProjectId } = await response.json()
  31. window.location.assign(`/project/${clonedProjectId}`)
  32. } else {
  33. if (response.status === 400) {
  34. setError({ message: await response.text() })
  35. } else {
  36. setError(true)
  37. }
  38. setInFlight(false)
  39. }
  40. })
  41. .catch(() => {
  42. setError(true)
  43. setInFlight(false)
  44. })
  45. },
  46. [projectId]
  47. )
  48. // close the modal if not in flight
  49. const cancel = useCallback(() => {
  50. if (!inFlight) {
  51. handleHide()
  52. }
  53. }, [handleHide, inFlight])
  54. return (
  55. <Modal show={show} onHide={cancel}>
  56. <CloneProjectModalContent
  57. cloneProject={cloneProject}
  58. error={error}
  59. cancel={cancel}
  60. inFlight={inFlight}
  61. projectName={projectName}
  62. />
  63. </Modal>
  64. )
  65. }
  66. CloneProjectModal.propTypes = {
  67. handleHide: PropTypes.func.isRequired,
  68. projectId: PropTypes.string.isRequired,
  69. projectName: PropTypes.string,
  70. show: PropTypes.bool.isRequired
  71. }
  72. export default CloneProjectModal