mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #15444 from overleaf/td-remove-root-folder-scope-use
Remove use of root folder scope in figure modal GitOrigin-RevId: d07247b644d312ef711f5601d3c10a3274e43416
This commit is contained in:
parent
13f246a85e
commit
c34c95b46d
9 changed files with 101 additions and 66 deletions
|
@ -6,9 +6,9 @@ import {
|
|||
useState,
|
||||
} from 'react'
|
||||
import { File, FileOrDirectory } from '../../utils/file'
|
||||
import useScopeValue from '../../../../shared/hooks/use-scope-value'
|
||||
import { Alert } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCurrentProjectFolders } from '@/features/source-editor/hooks/use-current-project-folders'
|
||||
|
||||
type FileNameInputProps = Omit<
|
||||
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,
|
||||
|
@ -57,7 +57,7 @@ export const FileNameInput = ({
|
|||
}: FileNameInputProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [overlap, setOverlap] = useState<boolean>(false)
|
||||
const [rootFolder] = useScopeValue<FileOrDirectory>('rootFolder')
|
||||
const { rootFolder } = useCurrentProjectFolders()
|
||||
const { value } = props
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useCallback } from 'react'
|
|||
import { FileNameInput } from './file-name-input'
|
||||
import { File } from '../../utils/file'
|
||||
import { Select } from '../../../../shared/components/select'
|
||||
import { useCurrentProjectFolders } from '../../hooks/useCurrentProjectFolders'
|
||||
import { useCurrentProjectFolders } from '../../hooks/use-current-project-folders'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export const FileRelocator = ({
|
||||
|
@ -25,7 +25,7 @@ export const FileRelocator = ({
|
|||
setNameDirty: (nameDirty: boolean) => void
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [folders, rootFile] = useCurrentProjectFolders()
|
||||
const { folders, rootFile } = useCurrentProjectFolders()
|
||||
|
||||
const nameChanged = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
useProjectOutputFiles,
|
||||
} from '../../../../file-tree/hooks/use-project-output-files'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/useCurrentProjectFolders'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/use-current-project-folders'
|
||||
import { File, isImageEntity } from '../../../utils/file'
|
||||
import { postJSON } from '../../../../../infrastructure/fetch-json'
|
||||
import { useProjectContext } from '../../../../../shared/context/project-context'
|
||||
|
@ -39,7 +39,7 @@ export const FigureModalOtherProjectSource: FC = () => {
|
|||
const [nameDirty, setNameDirty] = useState<boolean>(false)
|
||||
const [name, setName] = useState<string>('')
|
||||
const [folder, setFolder] = useState<File | null>(null)
|
||||
const [, rootFile] = useCurrentProjectFolders()
|
||||
const { rootFile } = useCurrentProjectFolders()
|
||||
const [file, setFile] = useState<OutputEntity | Entity | null>(null)
|
||||
const FileSelector = usingOutputFiles
|
||||
? SelectFromProjectOutputFiles
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { FC, useMemo } from 'react'
|
||||
import useScopeValue from '../../../../../shared/hooks/use-scope-value'
|
||||
import { Select } from '../../../../../shared/components/select'
|
||||
import { useFigureModalContext } from '../figure-modal-context'
|
||||
import { FileOrDirectory, filterFiles, isImageFile } from '../../../utils/file'
|
||||
import { filterFiles, isImageFile } from '../../../utils/file'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCurrentProjectFolders } from '@/features/source-editor/hooks/use-current-project-folders'
|
||||
|
||||
export const FigureModalCurrentProjectSource: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const [rootFolder] = useScopeValue<FileOrDirectory>('rootFolder')
|
||||
const { rootFolder } = useCurrentProjectFolders()
|
||||
const files = useMemo(
|
||||
() => filterFiles(rootFolder)?.filter(isImageFile),
|
||||
[rootFolder]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FC, useCallback, useEffect, useState } from 'react'
|
||||
import { useFigureModalContext } from '../figure-modal-context'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/useCurrentProjectFolders'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/use-current-project-folders'
|
||||
import { File } from '../../../utils/file'
|
||||
import { Dashboard, useUppy } from '@uppy/react'
|
||||
import '@uppy/core/dist/style.css'
|
||||
|
@ -33,7 +33,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
const view = useCodeMirrorViewContext()
|
||||
const { dispatch, pastedImageData } = useFigureModalContext()
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const [, rootFolder] = useCurrentProjectFolders()
|
||||
const { rootFile } = useCurrentProjectFolders()
|
||||
const [folder, setFolder] = useState<File | null>(null)
|
||||
const [nameDirty, setNameDirty] = useState<boolean>(false)
|
||||
// Files are immutable, so this will point to a (possibly) old version of the file
|
||||
|
@ -77,7 +77,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
if (!uploadResult.successful) {
|
||||
throw new Error('Upload failed')
|
||||
}
|
||||
const uploadFolder = folder ?? rootFolder
|
||||
const uploadFolder = folder ?? rootFile
|
||||
return uploadFolder.path === '' && uploadFolder.name === 'rootFolder'
|
||||
? `${name}`
|
||||
: `${uploadFolder.path ? uploadFolder.path + '/' : ''}${
|
||||
|
@ -86,7 +86,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
},
|
||||
})
|
||||
},
|
||||
[dispatch, rootFolder, uppy, view]
|
||||
[dispatch, rootFile, uppy, view]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -130,7 +130,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
xhrUpload: {
|
||||
...(file as any).xhrUpload,
|
||||
endpoint: `/project/${projectId}/upload?folder_id=${
|
||||
(folder ?? rootFolder).id
|
||||
(folder ?? rootFile).id
|
||||
}`,
|
||||
},
|
||||
})
|
||||
|
@ -179,7 +179,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
}, [
|
||||
uppy,
|
||||
folder,
|
||||
rootFolder,
|
||||
rootFile,
|
||||
name,
|
||||
nameDirty,
|
||||
dispatchUploadAction,
|
||||
|
@ -245,7 +245,7 @@ export const FigureModalUploadFileSource: FC = () => {
|
|||
name={name}
|
||||
nameDisabled={!file && !nameDirty}
|
||||
onFolderChanged={item =>
|
||||
dispatchUploadAction(name, file, item ?? rootFolder)
|
||||
dispatchUploadAction(name, file, item ?? rootFile)
|
||||
}
|
||||
onNameChanged={name => dispatchUploadAction(name, file, folder)}
|
||||
setFolder={setFolder}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useFigureModalContext } from '../figure-modal-context'
|
|||
import { postJSON } from '../../../../../infrastructure/fetch-json'
|
||||
import { useProjectContext } from '../../../../../shared/context/project-context'
|
||||
import { File } from '../../../utils/file'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/useCurrentProjectFolders'
|
||||
import { useCurrentProjectFolders } from '../../../hooks/use-current-project-folders'
|
||||
import { FileRelocator } from '../file-relocator'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useCodeMirrorViewContext } from '../../codemirror-editor'
|
||||
|
@ -44,7 +44,7 @@ export const FigureModalUrlSource: FC = () => {
|
|||
const [nameDirty, setNameDirty] = useState<boolean>(false)
|
||||
const [name, setName] = useState<string>('')
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const [, rootFile] = useCurrentProjectFolders()
|
||||
const { rootFile } = useCurrentProjectFolders()
|
||||
const [folder, setFolder] = useState<File>(rootFile)
|
||||
|
||||
const { dispatch, getPath } = useFigureModalContext()
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import { useMemo } from 'react'
|
||||
import { File, FileOrDirectory, filterFolders } from '../utils/file'
|
||||
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { Folder } from '../../../../../types/folder'
|
||||
import { Doc } from '../../../../../types/doc'
|
||||
import { FileRef } from '../../../../../types/file-ref'
|
||||
|
||||
function docAdapter(doc: Doc): FileOrDirectory {
|
||||
return {
|
||||
id: doc._id,
|
||||
name: doc.name,
|
||||
type: 'doc',
|
||||
}
|
||||
}
|
||||
|
||||
function fileRefAdapter(fileRef: FileRef): FileOrDirectory {
|
||||
return {
|
||||
id: fileRef._id,
|
||||
name: fileRef.name,
|
||||
type: 'file',
|
||||
}
|
||||
}
|
||||
|
||||
function folderAdapter(folder: Folder): FileOrDirectory {
|
||||
return {
|
||||
id: folder._id,
|
||||
name: folder.name,
|
||||
type: 'folder',
|
||||
children: folder.docs
|
||||
.map(docAdapter)
|
||||
.concat(
|
||||
folder.fileRefs.map(fileRefAdapter),
|
||||
folder.folders.map(folderAdapter)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
export const useCurrentProjectFolders: () => {
|
||||
folders: File[] | undefined
|
||||
rootFile: File
|
||||
rootFolder: FileOrDirectory
|
||||
} = () => {
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
|
||||
return useMemo(() => {
|
||||
const rootFolder = folderAdapter(fileTreeData)
|
||||
const rootFile = { ...rootFolder, path: '' }
|
||||
const folders = filterFolders(rootFolder)
|
||||
return { folders, rootFile, rootFolder }
|
||||
}, [fileTreeData])
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { useMemo } from 'react'
|
||||
import useScopeValue from '../../../shared/hooks/use-scope-value'
|
||||
import { File, FileOrDirectory, filterFolders } from '../utils/file'
|
||||
|
||||
export const useCurrentProjectFolders: () => [
|
||||
File[] | undefined,
|
||||
File
|
||||
] = () => {
|
||||
const [rootFolder] = useScopeValue<FileOrDirectory>('rootFolder')
|
||||
const rootFile = { ...rootFolder, path: '' }
|
||||
const folders = useMemo(() => filterFolders(rootFolder), [rootFolder])
|
||||
return [folders, rootFile]
|
||||
}
|
|
@ -1,45 +1,12 @@
|
|||
import { docId, mockDoc } from './mock-doc'
|
||||
import { Folder } from '../../../../../types/folder'
|
||||
import { sleep } from '../../../helpers/sleep'
|
||||
import { Folder } from '../../../../../types/folder'
|
||||
|
||||
export const rootFolderId = '012345678901234567890123'
|
||||
export const figuresFolderId = '123456789012345678901234'
|
||||
export const figureId = '234567890123456789012345'
|
||||
export const mockScope = (content?: string) => {
|
||||
return {
|
||||
rootFolder: {
|
||||
id: rootFolderId,
|
||||
name: 'rootFolder',
|
||||
selected: false,
|
||||
children: [
|
||||
{
|
||||
id: docId,
|
||||
name: 'test.tex',
|
||||
selected: false,
|
||||
type: 'doc',
|
||||
},
|
||||
{
|
||||
id: figuresFolderId,
|
||||
name: 'figures',
|
||||
selected: false,
|
||||
type: 'folder',
|
||||
children: [
|
||||
{
|
||||
id: figureId,
|
||||
name: 'frog.jpg',
|
||||
selected: false,
|
||||
type: 'file',
|
||||
},
|
||||
{
|
||||
id: 'fake-figure-id',
|
||||
name: 'unicorn.png',
|
||||
selected: false,
|
||||
type: 'file',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
fontSize: 12,
|
||||
fontFamily: 'monaco',
|
||||
|
@ -66,7 +33,37 @@ export const mockScope = (content?: string) => {
|
|||
_id: 'test-project',
|
||||
name: 'Test Project',
|
||||
spellCheckLanguage: 'en',
|
||||
rootFolder: [] as Folder[],
|
||||
rootFolder: [
|
||||
{
|
||||
_id: rootFolderId,
|
||||
name: 'rootFolder',
|
||||
docs: [
|
||||
{
|
||||
_id: docId,
|
||||
name: 'test.tex',
|
||||
},
|
||||
],
|
||||
folders: [
|
||||
{
|
||||
_id: figuresFolderId,
|
||||
name: 'figures',
|
||||
docs: [],
|
||||
folders: [],
|
||||
fileRefs: [
|
||||
{
|
||||
_id: figureId,
|
||||
name: 'frog.jpg',
|
||||
},
|
||||
{
|
||||
_id: 'fake-figure-id',
|
||||
name: 'unicorn.png',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
fileRefs: [],
|
||||
},
|
||||
] as Folder[],
|
||||
features: {
|
||||
trackChanges: true,
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue