From acca25721375ab7b99c817bbce770da6aa1dfe80 Mon Sep 17 00:00:00 2001 From: Davinder Singh Date: Thu, 15 Sep 2022 10:59:11 +0100 Subject: [PATCH] Merge pull request #9584 from overleaf/jel-copy-modal-wrapper [web] Add wrapper for copy modal GitOrigin-RevId: 8291f953e418815797e8474a69de8f15c39af7b5 --- .../components/clone-project-modal-content.js | 12 ++++--- .../components/clone-project-modal.js | 21 +++++++----- .../editor-clone-project-modal-wrapper.js | 34 +++++++++++++++++++ ...eft-menu-clone-project-modal-controller.js | 10 +++--- .../components/clone-project-modal.test.js | 12 +++---- 5 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 services/web/frontend/js/features/clone-project-modal/components/editor-clone-project-modal-wrapper.js diff --git a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.js b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.js index 6b71689816..ee7d89cae4 100644 --- a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal-content.js +++ b/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, } diff --git a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.js b/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.js index 8d88604bdc..e28043d15b 100644 --- a/services/web/frontend/js/features/clone-project-modal/components/clone-project-modal.js +++ b/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} /> ) -}) +} 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) diff --git a/services/web/frontend/js/features/clone-project-modal/components/editor-clone-project-modal-wrapper.js b/services/web/frontend/js/features/clone-project-modal/components/editor-clone-project-modal-wrapper.js new file mode 100644 index 0000000000..6b16326366 --- /dev/null +++ b/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 ( + + ) + } + } +) + +EditorCloneProjectModalWrapper.propTypes = { + handleHide: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired, + openProject: PropTypes.func.isRequired, +} + +export default withErrorBoundary(EditorCloneProjectModalWrapper) diff --git a/services/web/frontend/js/features/clone-project-modal/controllers/left-menu-clone-project-modal-controller.js b/services/web/frontend/js/features/clone-project-modal/controllers/left-menu-clone-project-modal-controller.js index a56be78768..042fa2c07b 100644 --- a/services/web/frontend/js/features/clone-project-modal/controllers/left-menu-clone-project-modal-controller.js +++ b/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) ) ) diff --git a/services/web/test/frontend/features/clone-project-modal/components/clone-project-modal.test.js b/services/web/test/frontend/features/clone-project-modal/components/clone-project-modal.test.js index df8d137448..22f8411896 100644 --- a/services/web/test/frontend/features/clone-project-modal/components/clone-project-modal.test.js +++ b/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('', function () { +describe('', function () { beforeEach(function () { fetchMock.reset() }) @@ -24,7 +24,7 @@ describe('', function () { const openProject = sinon.stub() renderWithEditorContext( - ', function () { const openProject = sinon.stub() renderWithEditorContext( - ', function () { const openProject = sinon.stub() renderWithEditorContext( - ', function () { const openProject = sinon.stub() renderWithEditorContext( -