mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-30 12:24:25 +02:00
Merge pull request #27316 from overleaf/dp-file-menu-options
Add copy and submit project options to new editor file menu GitOrigin-RevId: 7f402d96f278f2b084375441089b286adaa731b8
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import React from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
||||
import CloneProjectModal from './clone-project-modal'
|
||||
|
||||
type ProjectCopyResponse = {
|
||||
project_id: string
|
||||
}
|
||||
|
||||
const EditorCloneProjectModalWrapper = React.memo(
|
||||
function EditorCloneProjectModalWrapper({
|
||||
show,
|
||||
@@ -11,9 +15,15 @@ const EditorCloneProjectModalWrapper = React.memo(
|
||||
}: {
|
||||
show: boolean
|
||||
handleHide: () => void
|
||||
openProject: ({ project_id }: { project_id: string }) => void
|
||||
openProject: (projectId: string) => void
|
||||
}) {
|
||||
const { project, tags: projectTags } = useProjectContext()
|
||||
const handleAfterCloned = useCallback(
|
||||
({ project_id: projectId }: ProjectCopyResponse) => {
|
||||
openProject(projectId)
|
||||
},
|
||||
[openProject]
|
||||
)
|
||||
|
||||
if (!project) {
|
||||
// wait for useProjectContext
|
||||
@@ -23,7 +33,7 @@ const EditorCloneProjectModalWrapper = React.memo(
|
||||
<CloneProjectModal
|
||||
handleHide={handleHide}
|
||||
show={show}
|
||||
handleAfterCloned={openProject}
|
||||
handleAfterCloned={handleAfterCloned}
|
||||
projectId={project._id}
|
||||
projectName={project.name}
|
||||
projectTags={projectTags}
|
||||
|
||||
@@ -2,24 +2,13 @@ import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import EditorCloneProjectModalWrapper from '../../clone-project-modal/components/editor-clone-project-modal-wrapper'
|
||||
import LeftMenuButton from './left-menu-button'
|
||||
import { useLocation } from '../../../shared/hooks/use-location'
|
||||
import * as eventTracking from '../../../infrastructure/event-tracking'
|
||||
|
||||
type ProjectCopyResponse = {
|
||||
project_id: string
|
||||
}
|
||||
import useOpenProject from '@/shared/hooks/use-open-project'
|
||||
|
||||
export default function ActionsCopyProject() {
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const { t } = useTranslation()
|
||||
const location = useLocation()
|
||||
|
||||
const openProject = useCallback(
|
||||
({ project_id: projectId }: ProjectCopyResponse) => {
|
||||
location.assign(`/project/${projectId}`)
|
||||
},
|
||||
[location]
|
||||
)
|
||||
const openProject = useOpenProject()
|
||||
|
||||
const handleShowModal = useCallback(() => {
|
||||
eventTracking.sendMB('left-menu-copy')
|
||||
|
||||
@@ -1,28 +1,17 @@
|
||||
import EditorCloneProjectModalWrapper from '@/features/clone-project-modal/components/editor-clone-project-modal-wrapper'
|
||||
import OLDropdownMenuItem from '@/shared/components/ol/ol-dropdown-menu-item'
|
||||
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
|
||||
import { useLocation } from '@/shared/hooks/use-location'
|
||||
import useOpenProject from '@/shared/hooks/use-open-project'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type ProjectCopyResponse = {
|
||||
project_id: string
|
||||
}
|
||||
|
||||
export const DuplicateProject = () => {
|
||||
const { sendEvent } = useEditorAnalytics()
|
||||
const { t } = useTranslation()
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const location = useLocation()
|
||||
const anonymous = getMeta('ol-anonymous')
|
||||
|
||||
const openProject = useCallback(
|
||||
({ project_id: projectId }: ProjectCopyResponse) => {
|
||||
location.assign(`/project/${projectId}`)
|
||||
},
|
||||
[location]
|
||||
)
|
||||
const openProject = useOpenProject()
|
||||
|
||||
const handleShowModal = useCallback(() => {
|
||||
sendEvent('copy-project', { location: 'project-title-dropdown' })
|
||||
|
||||
@@ -27,6 +27,9 @@ import { useDetachCompileContext as useCompileContext } from '@/shared/context/d
|
||||
import { useEditorAnalytics } from '@/shared/hooks/use-editor-analytics'
|
||||
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
|
||||
import { useSurveyUrl } from '../../hooks/use-survey-url'
|
||||
import getMeta from '@/utils/meta'
|
||||
import EditorCloneProjectModalWrapper from '@/features/clone-project-modal/components/editor-clone-project-modal-wrapper'
|
||||
import useOpenProject from '@/shared/hooks/use-open-project'
|
||||
|
||||
export const ToolbarMenuBar = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -38,6 +41,10 @@ export const ToolbarMenuBar = () => {
|
||||
const { pdfUrl } = useCompileContext()
|
||||
const wordCountEnabled = pdfUrl || isSplitTestEnabled('word-count-client')
|
||||
const [showWordCountModal, setShowWordCountModal] = useState(false)
|
||||
const [showCloneProjectModal, setShowCloneProjectModal] = useState(false)
|
||||
const openProject = useOpenProject()
|
||||
|
||||
const anonymous = getMeta('ol-anonymous')
|
||||
|
||||
useCommandProvider(
|
||||
() => [
|
||||
@@ -58,16 +65,26 @@ export const ToolbarMenuBar = () => {
|
||||
},
|
||||
id: 'word_count',
|
||||
},
|
||||
{
|
||||
type: 'command',
|
||||
label: t('make_a_copy'),
|
||||
disabled: anonymous,
|
||||
handler: () => {
|
||||
setShowCloneProjectModal(true)
|
||||
},
|
||||
id: 'copy_project',
|
||||
},
|
||||
],
|
||||
[t, setView, view, wordCountEnabled]
|
||||
[t, setView, view, wordCountEnabled, anonymous]
|
||||
)
|
||||
const fileMenuStructure: MenuStructure = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 'file-file-tree',
|
||||
children: ['new_file', 'new_folder', 'upload_file'],
|
||||
children: ['new_file', 'new_folder', 'upload_file', 'copy_project'],
|
||||
},
|
||||
{ id: 'file-tools', children: ['show_version_history', 'word_count'] },
|
||||
{ id: 'submit', children: ['submit-project'] },
|
||||
{
|
||||
id: 'file-download',
|
||||
children: ['download-as-source-zip', 'download-pdf'],
|
||||
@@ -286,6 +303,11 @@ export const ToolbarMenuBar = () => {
|
||||
show={showWordCountModal}
|
||||
handleHide={() => setShowWordCountModal(false)}
|
||||
/>
|
||||
<EditorCloneProjectModalWrapper
|
||||
show={showCloneProjectModal}
|
||||
handleHide={() => setShowCloneProjectModal(false)}
|
||||
openProject={openProject}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
15
services/web/frontend/js/shared/hooks/use-open-project.ts
Normal file
15
services/web/frontend/js/shared/hooks/use-open-project.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { useCallback } from 'react'
|
||||
import { useLocation } from './use-location'
|
||||
|
||||
export default function useOpenProject() {
|
||||
const location = useLocation()
|
||||
|
||||
const openProject = useCallback(
|
||||
(projectId: string) => {
|
||||
location.assign(`/project/${projectId}`)
|
||||
},
|
||||
[location]
|
||||
)
|
||||
|
||||
return openProject
|
||||
}
|
||||
Reference in New Issue
Block a user