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

[web] Add wrapper for copy modal

GitOrigin-RevId: 8291f953e418815797e8474a69de8f15c39af7b5
This commit is contained in:
Davinder Singh 2022-09-15 10:59:11 +01:00 committed by Copybot
parent 70e63ca0e3
commit 9cde88a9e8
5 changed files with 65 additions and 24 deletions

View file

@ -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,
}

View file

@ -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)

View file

@ -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)

View file

@ -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)
)
)

View file

@ -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