mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-13 21:53:43 +01:00
Move project context out of scope value store (#26615)
* Refactor project context to not use scope store * Fix Cypress tests for project context changes * Fix frontend React Testing Library tests for project context changes * Remove redundant code * Fix some project types in tests * Remove unused import and fix a type * Throw an error if updating the project in the project context before joining the project * Fix some review panel tests * Remove unused imports GitOrigin-RevId: 2f0c928b651f387aa980c29aef7d1ba0649790a7
This commit is contained in:
@@ -39,7 +39,9 @@ const FileTreeOpenContext = createContext<
|
||||
export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { rootDocId, owner } = useProjectContext()
|
||||
const { project } = useProjectContext()
|
||||
const rootDocId = project?.rootDocId
|
||||
const projectOwner = project?.owner?._id
|
||||
const { eventEmitter, projectJoined } = useIdeReactContext()
|
||||
const { openDocWithId, openInitialDoc } = useEditorManagerContext()
|
||||
const { currentDocumentId } = useEditorOpenDocContext()
|
||||
@@ -81,7 +83,7 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
|
||||
openDocWithId(selected.entity._id, { keepCurrentView: true })
|
||||
if (selected.entity.name.endsWith('.bib')) {
|
||||
sendMB('open-bib-file', {
|
||||
projectOwner: owner._id,
|
||||
projectOwner,
|
||||
isSampleFile: selected.entity.name === 'sample.bib',
|
||||
linkedFileProvider: null,
|
||||
})
|
||||
@@ -96,7 +98,7 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
|
||||
if (openFile) {
|
||||
if (selected?.entity?.name?.endsWith('.bib')) {
|
||||
sendMB('open-bib-file', {
|
||||
projectOwner: owner._id,
|
||||
projectOwner,
|
||||
isSampleFile: false,
|
||||
linkedFileProvider: (selected.entity as FileRef).linkedFileData
|
||||
?.provider,
|
||||
@@ -105,7 +107,7 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
|
||||
window.dispatchEvent(new CustomEvent('file-view:file-opened'))
|
||||
}
|
||||
},
|
||||
[fileTreeReady, setOpenFile, openDocWithId, owner]
|
||||
[fileTreeReady, setOpenFile, openDocWithId, projectOwner]
|
||||
)
|
||||
|
||||
const handleFileTreeDelete = useCallback(
|
||||
|
||||
@@ -19,6 +19,8 @@ import { postJSON } from '@/infrastructure/fetch-json'
|
||||
import { ReactScopeEventEmitter } from '@/features/ide-react/scope-event-emitter/react-scope-event-emitter'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { type PermissionsLevel } from '@/features/ide-react/types/permissions'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import { ProjectMetadata } from '@/shared/context/types/project-metadata'
|
||||
|
||||
const LOADED_AT = new Date()
|
||||
|
||||
@@ -44,10 +46,6 @@ function populateIdeReactScope(store: ReactScopeValueStore) {
|
||||
store.set('settings', {})
|
||||
}
|
||||
|
||||
function populateProjectScope(store: ReactScopeValueStore) {
|
||||
store.allowNonExistentPath('project', true)
|
||||
}
|
||||
|
||||
function populatePdfScope(store: ReactScopeValueStore) {
|
||||
store.allowNonExistentPath('pdf', true)
|
||||
}
|
||||
@@ -61,7 +59,6 @@ export function createReactScopeValueStore() {
|
||||
// initialization code together with the context and would only populate
|
||||
// necessary values in the store, but this is simpler for now
|
||||
populateIdeReactScope(scopeStore)
|
||||
populateProjectScope(scopeStore)
|
||||
populatePdfScope(scopeStore)
|
||||
|
||||
scopeStore.allowNonExistentPath('hasLintingError')
|
||||
@@ -94,6 +91,8 @@ export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const [projectJoined, setProjectJoined] = useState(false)
|
||||
|
||||
const { socket, getSocketDebuggingInfo } = useConnectionContext()
|
||||
const { joinProject, project } = useProjectContext()
|
||||
const spellCheckLanguage = project?.spellCheckLanguage
|
||||
|
||||
const reportError = useCallback(
|
||||
(error: any, meta?: Record<string, any>) => {
|
||||
@@ -105,7 +104,7 @@ export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
performance_now: performance.now(),
|
||||
release,
|
||||
client_load: LOADED_AT,
|
||||
spellCheckLanguage: scopeStore.get('project.spellCheckLanguage'),
|
||||
spellCheckLanguage,
|
||||
...getSocketDebuggingInfo(),
|
||||
}
|
||||
|
||||
@@ -124,17 +123,28 @@ export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
},
|
||||
})
|
||||
},
|
||||
[release, projectId, getSocketDebuggingInfo, scopeStore]
|
||||
[release, projectId, getSocketDebuggingInfo, spellCheckLanguage]
|
||||
)
|
||||
|
||||
// Populate scope values when joining project, then fire project:joined event
|
||||
useEffect(() => {
|
||||
function handleJoinProjectResponse({
|
||||
project: { rootDoc_id: rootDocId, ..._project },
|
||||
project: {
|
||||
rootDoc_id: rootDocId,
|
||||
publicAccesLevel: publicAccessLevel,
|
||||
..._project
|
||||
},
|
||||
permissionsLevel,
|
||||
}: JoinProjectPayload) {
|
||||
const project = { ..._project, rootDocId }
|
||||
scopeStore.set('project', project)
|
||||
const project = { ..._project, rootDocId, publicAccessLevel }
|
||||
|
||||
// Cast the project from the payload as ProjectMetadata to ensure it has
|
||||
// the correct type for the context. It must be close enough because the
|
||||
// data structure hasn't changed and it worked previously. This type
|
||||
// coercion was previously sidestepped by adding the project to the scope
|
||||
// store, which does not enforce types.
|
||||
joinProject(project as unknown as ProjectMetadata)
|
||||
|
||||
setPermissionsLevel(permissionsLevel)
|
||||
// Make watchers update immediately
|
||||
scopeStore.flushUpdates()
|
||||
@@ -142,21 +152,12 @@ export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
setProjectJoined(true)
|
||||
}
|
||||
|
||||
function handleMainBibliographyDocUpdated(payload: string) {
|
||||
scopeStore.set('project.mainBibliographyDoc_id', payload)
|
||||
}
|
||||
|
||||
socket.on('joinProjectResponse', handleJoinProjectResponse)
|
||||
socket.on('mainBibliographyDocUpdated', handleMainBibliographyDocUpdated)
|
||||
|
||||
return () => {
|
||||
socket.removeListener('joinProjectResponse', handleJoinProjectResponse)
|
||||
socket.removeListener(
|
||||
'mainBibliographyDocUpdated',
|
||||
handleMainBibliographyDocUpdated
|
||||
)
|
||||
}
|
||||
}, [socket, eventEmitter, scopeStore])
|
||||
}, [socket, eventEmitter, scopeStore, joinProject])
|
||||
|
||||
const ide = useMemo(() => {
|
||||
return {
|
||||
|
||||
@@ -124,7 +124,7 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
[openDocName]
|
||||
)
|
||||
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const { projectId } = useProjectContext()
|
||||
const storageKey = `file_outline.expanded.${projectId}`
|
||||
|
||||
const [outlineExpanded, setOutlineExpanded] = useState(
|
||||
|
||||
@@ -98,7 +98,7 @@ export const PermissionsProvider: React.FC<React.PropsWithChildren> = ({
|
||||
const { permissionsLevel } = useIdeReactContext()
|
||||
const hasViewerPermissions = useViewerPermissions()
|
||||
const anonymous = getMeta('ol-anonymous')
|
||||
const project = useProjectContext()
|
||||
const { features } = useProjectContext()
|
||||
|
||||
useEffect(() => {
|
||||
let activePermissionsMap
|
||||
@@ -106,7 +106,7 @@ export const PermissionsProvider: React.FC<React.PropsWithChildren> = ({
|
||||
activePermissionsMap = linkSharingWarningPermissionsMap
|
||||
} else if (anonymous) {
|
||||
activePermissionsMap = anonymousPermissionsMap
|
||||
} else if (!project.features.trackChanges) {
|
||||
} else if (!features.trackChanges) {
|
||||
activePermissionsMap = noTrackChangesPermissionsMap
|
||||
} else {
|
||||
activePermissionsMap = permissionsMap
|
||||
@@ -117,7 +117,7 @@ export const PermissionsProvider: React.FC<React.PropsWithChildren> = ({
|
||||
permissionsLevel,
|
||||
setPermissions,
|
||||
hasViewerPermissions,
|
||||
project.features.trackChanges,
|
||||
features.trackChanges,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -75,10 +75,10 @@ export const ReactContextRoot: FC<
|
||||
<Providers.SplitTestProvider>
|
||||
<Providers.ModalsContextProvider>
|
||||
<Providers.ConnectionProvider>
|
||||
<Providers.IdeReactProvider>
|
||||
<Providers.UserProvider>
|
||||
<Providers.UserSettingsProvider>
|
||||
<Providers.ProjectProvider>
|
||||
<Providers.ProjectProvider>
|
||||
<Providers.IdeReactProvider>
|
||||
<Providers.UserProvider>
|
||||
<Providers.UserSettingsProvider>
|
||||
<Providers.SnapshotProvider>
|
||||
<Providers.DetachProvider>
|
||||
<Providers.EditorPropertiesProvider>
|
||||
@@ -128,10 +128,10 @@ export const ReactContextRoot: FC<
|
||||
</Providers.EditorPropertiesProvider>
|
||||
</Providers.DetachProvider>
|
||||
</Providers.SnapshotProvider>
|
||||
</Providers.ProjectProvider>
|
||||
</Providers.UserSettingsProvider>
|
||||
</Providers.UserProvider>
|
||||
</Providers.IdeReactProvider>
|
||||
</Providers.UserSettingsProvider>
|
||||
</Providers.UserProvider>
|
||||
</Providers.IdeReactProvider>
|
||||
</Providers.ProjectProvider>
|
||||
</Providers.ConnectionProvider>
|
||||
</Providers.ModalsContextProvider>
|
||||
</Providers.SplitTestProvider>
|
||||
|
||||
@@ -55,7 +55,7 @@ export const SnapshotContext = createContext<
|
||||
>(undefined)
|
||||
|
||||
export const SnapshotProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const { projectId } = useProjectContext()
|
||||
const [snapshotLoadingState, setSnapshotLoadingState] =
|
||||
useState<SnapshotLoadingState>('')
|
||||
const [snapshotUpdater] = useState(() => new SnapshotUpdater(projectId))
|
||||
|
||||
Reference in New Issue
Block a user