Bläddra i källkod

Merge pull request #9584 from overleaf/jel-copy-modal-wrapper

[web] Add wrapper for copy modal

GitOrigin-RevId: 8291f953e418815797e8474a69de8f15c39af7b5
Davinder Singh 3 år sedan
förälder
incheckning
9cde88a9e8

+ 7 - 5
services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.js

@@ -9,16 +9,16 @@ import {
   FormControl,
   FormGroup,
 } from 'react-bootstrap'
-import { useProjectContext } from '../../../shared/context/project-context'
 import { postJSON } from '../../../infrastructure/fetch-json'
 
 export default function CloneProjectModalContent({
   handleHide,
   inFlight,
   setInFlight,
-  openProject,
+  handleAfterCloned,
+  projectId,
+  projectName,
 }) {
-  const { _id: projectId, name: projectName } = useProjectContext()
   const { t } = useTranslation()
 
   const [error, setError] = useState()
@@ -49,7 +49,7 @@ export default function CloneProjectModalContent({
     })
       .then(data => {
         // open the cloned project
-        openProject(data.project_id)
+        handleAfterCloned(data)
       })
       .catch(({ response, data }) => {
         if (response?.status === 400) {
@@ -115,5 +115,7 @@ CloneProjectModalContent.propTypes = {
   handleHide: PropTypes.func.isRequired,
   inFlight: PropTypes.bool,
   setInFlight: PropTypes.func.isRequired,
-  openProject: PropTypes.func.isRequired,
+  handleAfterCloned: PropTypes.func.isRequired,
+  projectId: PropTypes.string,
+  projectName: PropTypes.string,
 }

+ 13 - 8
services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.js

@@ -1,13 +1,14 @@
-import React, { useCallback, useState } from 'react'
+import React, { memo, useCallback, useState } from 'react'
 import PropTypes from 'prop-types'
 import CloneProjectModalContent from './clone-project-modal-content'
 import AccessibleModal from '../../../shared/components/accessible-modal'
-import withErrorBoundary from '../../../infrastructure/error-boundary'
 
-const CloneProjectModal = React.memo(function CloneProjectModal({
+function CloneProjectModal({
   show,
   handleHide,
-  openProject,
+  handleAfterCloned,
+  projectId,
+  projectName,
 }) {
   const [inFlight, setInFlight] = useState(false)
 
@@ -29,16 +30,20 @@ const CloneProjectModal = React.memo(function CloneProjectModal({
         handleHide={onHide}
         inFlight={inFlight}
         setInFlight={setInFlight}
-        openProject={openProject}
+        handleAfterCloned={handleAfterCloned}
+        projectId={projectId}
+        projectName={projectName}
       />
     </AccessibleModal>
   )
-})
+}
 
 CloneProjectModal.propTypes = {
   handleHide: PropTypes.func.isRequired,
   show: PropTypes.bool.isRequired,
-  openProject: PropTypes.func.isRequired,
+  handleAfterCloned: PropTypes.func.isRequired,
+  projectId: PropTypes.string,
+  projectName: PropTypes.string,
 }
 
-export default withErrorBoundary(CloneProjectModal)
+export default memo(CloneProjectModal)

+ 34 - 0
services/web/frontend/js/features/clone-project-modal/components/editor-clone-project-modal-wrapper.js

@@ -0,0 +1,34 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { useProjectContext } from '../../../shared/context/project-context'
+import withErrorBoundary from '../../../infrastructure/error-boundary'
+import CloneProjectModal from './clone-project-modal'
+
+const EditorCloneProjectModalWrapper = React.memo(
+  function EditorCloneProjectModalWrapper({ show, handleHide, openProject }) {
+    const { _id: projectId, name: projectName } = useProjectContext()
+
+    if (!projectName) {
+      // wait for useProjectContext
+      return null
+    } else {
+      return (
+        <CloneProjectModal
+          handleHide={handleHide}
+          show={show}
+          handleAfterCloned={openProject}
+          projectId={projectId}
+          projectName={projectName}
+        />
+      )
+    }
+  }
+)
+
+EditorCloneProjectModalWrapper.propTypes = {
+  handleHide: PropTypes.func.isRequired,
+  show: PropTypes.bool.isRequired,
+  openProject: PropTypes.func.isRequired,
+}
+
+export default withErrorBoundary(EditorCloneProjectModalWrapper)

+ 5 - 5
services/web/frontend/js/features/clone-project-modal/controllers/left-menu-clone-project-modal-controller.js

@@ -1,6 +1,6 @@
 import App from '../../../base'
 import { react2angular } from 'react2angular'
-import CloneProjectModal from '../components/clone-project-modal'
+import EditorCloneProjectModalWrapper from '../components/editor-clone-project-modal-wrapper'
 import { rootContext } from '../../../shared/context/root-context'
 
 export default App.controller(
@@ -20,8 +20,8 @@ export default App.controller(
       })
     }
 
-    $scope.openProject = projectId => {
-      window.location.assign(`/project/${projectId}`)
+    $scope.openProject = project => {
+      window.location.assign(`/project/${project.project_id}`)
     }
   }
 )
@@ -29,7 +29,7 @@ export default App.controller(
 App.component(
   'cloneProjectModal',
   react2angular(
-    rootContext.use(CloneProjectModal),
-    Object.keys(CloneProjectModal.propTypes)
+    rootContext.use(EditorCloneProjectModalWrapper),
+    Object.keys(EditorCloneProjectModalWrapper.propTypes)
   )
 )

+ 6 - 6
services/web/test/frontend/features/clone-project-modal/components/clone-project-modal.test.js

@@ -2,10 +2,10 @@ import { fireEvent, screen, waitFor } from '@testing-library/react'
 import { expect } from 'chai'
 import sinon from 'sinon'
 import fetchMock from 'fetch-mock'
-import CloneProjectModal from '../../../../../frontend/js/features/clone-project-modal/components/clone-project-modal'
+import EditorCloneProjectModalWrapper from '../../../../../frontend/js/features/clone-project-modal/components/editor-clone-project-modal-wrapper'
 import { renderWithEditorContext } from '../../../helpers/render-with-context'
 
-describe('<CloneProjectModal />', function () {
+describe('<EditorCloneProjectModalWrapper />', function () {
   beforeEach(function () {
     fetchMock.reset()
   })
@@ -24,7 +24,7 @@ describe('<CloneProjectModal />', function () {
     const openProject = sinon.stub()
 
     renderWithEditorContext(
-      <CloneProjectModal
+      <EditorCloneProjectModalWrapper
         handleHide={handleHide}
         openProject={openProject}
         show
@@ -49,7 +49,7 @@ describe('<CloneProjectModal />', function () {
     const openProject = sinon.stub()
 
     renderWithEditorContext(
-      <CloneProjectModal
+      <EditorCloneProjectModalWrapper
         handleHide={handleHide}
         openProject={openProject}
         show
@@ -112,7 +112,7 @@ describe('<CloneProjectModal />', function () {
     const openProject = sinon.stub()
 
     renderWithEditorContext(
-      <CloneProjectModal
+      <EditorCloneProjectModalWrapper
         handleHide={handleHide}
         openProject={openProject}
         show
@@ -149,7 +149,7 @@ describe('<CloneProjectModal />', function () {
     const openProject = sinon.stub()
 
     renderWithEditorContext(
-      <CloneProjectModal
+      <EditorCloneProjectModalWrapper
         handleHide={handleHide}
         openProject={openProject}
         show