Merge pull request #23940 from overleaf/td-react-18

Upgrade to React 18

GitOrigin-RevId: 9b81936e6eea2bccd97fe5c2c5841f0b946371b8
This commit is contained in:
Tim Down
2025-05-02 08:05:29 +00:00
committed by Copybot
parent 4464320757
commit 7abafb01ea
213 changed files with 2469 additions and 2105 deletions
@@ -9,13 +9,15 @@ import { FC } from 'react'
// FileTreeActionable: global UI state for actions (rename, delete, etc.)
// FileTreeMutable: provides entities mutation operations
// FileTreeSelectable: handles selection and multi-selection
const FileTreeContext: FC<{
refProviders: Record<string, boolean>
setRefProviderEnabled: (provider: string, value: boolean) => void
setStartedFreeTrial: (value: boolean) => void
onSelect: () => void
fileTreeContainer?: HTMLDivElement
}> = ({
const FileTreeContext: FC<
React.PropsWithChildren<{
refProviders: Record<string, boolean>
setRefProviderEnabled: (provider: string, value: boolean) => void
setStartedFreeTrial: (value: boolean) => void
onSelect: () => void
fileTreeContainer?: HTMLDivElement
}>
> = ({
refProviders,
setRefProviderEnabled,
setStartedFreeTrial,
@@ -50,7 +50,7 @@ export default function FileTreeImportFromProject() {
// use the basename of a path as the file name
const setNameFromPath = useCallback(
path => {
(path: string) => {
const filename = path.split('/').pop()
if (filename) {
@@ -1,7 +1,7 @@
import { useFileTreeSelectable } from '../contexts/file-tree-selectable'
import { FC, useCallback } from 'react'
const FileTreeInner: FC = ({ children }) => {
const FileTreeInner: FC<React.PropsWithChildren> = ({ children }) => {
const { setIsRootFolderSelected, selectedEntityIds, select } =
useFileTreeSelectable()
@@ -218,7 +218,9 @@ function fileTreeActionableReducer(state: State, action: Action) {
}
}
export const FileTreeActionableProvider: FC = ({ children }) => {
export const FileTreeActionableProvider: FC<React.PropsWithChildren> = ({
children,
}) => {
const { _id: projectId } = useProjectContext()
const { fileTreeReadOnly } = useFileTreeData()
const { indexAllReferences } = useReferencesContext()
@@ -400,7 +402,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
}, [fileTreeData, selectedEntityIds])
const finishCreatingEntity = useCallback(
entity => {
(entity: any) => {
const error = validateCreate(fileTreeData, parentFolderId, entity)
if (error) {
return Promise.reject(error)
@@ -412,7 +414,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
)
const finishCreatingFolder = useCallback(
name => {
(name: any) => {
dispatch({ type: ACTION_TYPES.CREATING_FOLDER })
return finishCreatingEntity({ endpoint: 'folder', name })
.then(() => {
@@ -425,7 +427,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
[finishCreatingEntity]
)
const startCreatingFile = useCallback(newFileCreateMode => {
const startCreatingFile = useCallback((newFileCreateMode: any) => {
dispatch({ type: ACTION_TYPES.START_CREATE_FILE, newFileCreateMode })
}, [])
@@ -438,7 +440,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
}, [startCreatingFile])
const finishCreatingDocOrFile = useCallback(
entity => {
(entity: any) => {
dispatch({ type: ACTION_TYPES.CREATING_FILE })
return finishCreatingEntity(entity)
@@ -453,7 +455,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
)
const finishCreatingDoc = useCallback(
entity => {
(entity: any) => {
entity.endpoint = 'doc'
return finishCreatingDocOrFile(entity)
},
@@ -461,7 +463,7 @@ export const FileTreeActionableProvider: FC = ({ children }) => {
)
const finishCreatingLinkedFile = useCallback(
entity => {
(entity: any) => {
entity.endpoint = 'linked_file'
return finishCreatingDocOrFile(entity)
},
@@ -16,7 +16,9 @@ export const useFileTreeCreateForm = () => {
return context
}
const FileTreeCreateFormProvider: FC = ({ children }) => {
const FileTreeCreateFormProvider: FC<React.PropsWithChildren> = ({
children,
}) => {
// is the form valid
const [valid, setValid] = useState(false)
@@ -28,10 +28,9 @@ type State = {
touchedName: boolean
}
const FileTreeCreateNameProvider: FC<{ initialName?: string }> = ({
children,
initialName = '',
}) => {
const FileTreeCreateNameProvider: FC<
React.PropsWithChildren<{ initialName?: string }>
> = ({ children, initialName = '' }) => {
const [state, setName] = useReducer(
(state: State, name: string) => ({
name, // the file name
@@ -18,9 +18,11 @@ import { isAcceptableFile } from '@/features/file-tree/util/is-acceptable-file'
import { FileTreeFindResult } from '@/features/ide-react/types/file-tree'
const DRAGGABLE_TYPE = 'ENTITY'
export const FileTreeDraggableProvider: FC<{
fileTreeContainer?: HTMLDivElement
}> = ({ fileTreeContainer, children }) => {
export const FileTreeDraggableProvider: FC<
React.PropsWithChildren<{
fileTreeContainer?: HTMLDivElement
}>
> = ({ fileTreeContainer, children }) => {
const options = useMemo(
() => ({ rootElement: fileTreeContainer }),
[fileTreeContainer]
@@ -25,11 +25,13 @@ export function useFileTreeMainContext() {
return context
}
export const FileTreeMainProvider: FC<{
refProviders: object
setRefProviderEnabled: (provider: string, value: boolean) => void
setStartedFreeTrial: (value: boolean) => void
}> = ({
export const FileTreeMainProvider: FC<
React.PropsWithChildren<{
refProviders: object
setRefProviderEnabled: (provider: string, value: boolean) => void
setStartedFreeTrial: (value: boolean) => void
}>
> = ({
refProviders,
setRefProviderEnabled,
setStartedFreeTrial,
@@ -22,7 +22,9 @@ export const FileTreePathContext = createContext<
FileTreePathContextValue | undefined
>(undefined)
export const FileTreePathProvider: FC = ({ children }) => {
export const FileTreePathProvider: FC<React.PropsWithChildren> = ({
children,
}) => {
const { fileTreeData }: { fileTreeData: Folder } = useFileTreeData()
const projectId = getMeta('ol-project_id')
@@ -1,3 +1,6 @@
// TODO: The types in this file have mismatches between string and string[] and
// it's not immediately clear how to resolve it. I've therefore left in a bunch
// of `any` types. We should fix this.
import {
createContext,
useCallback,
@@ -120,9 +123,11 @@ function fileTreeSelectableReadOnlyReducer(
}
}
export const FileTreeSelectableProvider: FC<{
onSelect: (value: FindResult[]) => void
}> = ({ onSelect, children }) => {
export const FileTreeSelectableProvider: FC<
React.PropsWithChildren<{
onSelect: (value: FindResult[]) => void
}>
> = ({ onSelect, children }) => {
const { _id: projectId, rootDocId } = useProjectContext()
const [initialSelectedEntityId] = usePersistedState(
@@ -206,21 +211,24 @@ export const FileTreeSelectableProvider: FC<{
)
)
const select = useCallback(id => {
const select = useCallback((id: any) => {
dispatch({ type: ACTION_TYPES.SELECT, id })
}, [])
const unselect = useCallback(id => {
const unselect = useCallback((id: any) => {
dispatch({ type: ACTION_TYPES.UNSELECT, id })
}, [])
const selectOrMultiSelectEntity = useCallback((id, isMultiSelect) => {
const actionType = isMultiSelect
? ACTION_TYPES.MULTI_SELECT
: ACTION_TYPES.SELECT
const selectOrMultiSelectEntity = useCallback(
(id: any, isMultiSelect: any) => {
const actionType = isMultiSelect
? ACTION_TYPES.MULTI_SELECT
: ACTION_TYPES.SELECT
dispatch({ type: actionType, id })
}, [])
dispatch({ type: actionType, id })
},
[]
)
// TODO: wrap in useMemo
const value = {
@@ -254,7 +262,7 @@ export function useSelectableEntity(id: string, type: string) {
const isSelected = selectedEntityIds.has(id)
const buildSelectedRange = useCallback(
id => {
(id: string) => {
const selected = []
let started = false
@@ -306,7 +314,7 @@ export function useSelectableEntity(id: string, type: string) {
}, [fileTreeData, selectedEntityIds, view])
const handleEvent = useCallback(
ev => {
(ev: any) => {
ev.stopPropagation()
// use Command (macOS) or Ctrl (other OS) to select multiple items,
// as long as the root folder wasn't selected
@@ -342,7 +350,7 @@ export function useSelectableEntity(id: string, type: string) {
)
const handleClick = useCallback(
ev => {
(ev: any) => {
handleEvent(ev)
if (!ev.ctrlKey && !ev.metaKey) {
setContextMenuCoords(null)
@@ -352,7 +360,7 @@ export function useSelectableEntity(id: string, type: string) {
)
const handleKeyPress = useCallback(
ev => {
(ev: any) => {
if (ev.key === 'Enter' || ev.key === ' ') {
handleEvent(ev)
}
@@ -361,7 +369,7 @@ export function useSelectableEntity(id: string, type: string) {
)
const handleContextMenu = useCallback(
ev => {
(ev: any) => {
// make sure the right-clicked entity gets selected
if (!selectedEntityIds.has(id)) {
handleEvent(ev)
@@ -25,7 +25,7 @@ export function useFileTreeSocketListener(onDelete: (entity: any) => void) {
const selectEntityIfCreatedByUser = useCallback(
// hack to automatically re-open refreshed linked files
(entityId, entityName, userId) => {
(entityId: any, entityName: any, userId: string) => {
// If the created entity's user exists and is the current user
if (userId && user?.id === userId) {
// And we're expecting a refreshed socket for this entity