Open selected file on project restore (#28145)

* Open selected file on project restore

* check if restorationState is "restoring" before opening a file

GitOrigin-RevId: c6f4cf69ecbe55b1d1949e4524fe7e39737c5487
This commit is contained in:
Domagoj Kriskovic
2025-09-02 10:03:46 +02:00
committed by Copybot
parent 7a5ec40c96
commit e4cc12d5e4
5 changed files with 70 additions and 9 deletions

View File

@@ -204,9 +204,13 @@ async function revertProject(req, res, next) {
const { version } = req.body
const userId = SessionManager.getLoggedInUserId(req.session)
await RestoreManager.promises.revertProject(userId, projectId, version)
const reverted = await RestoreManager.promises.revertProject(
userId,
projectId,
version
)
res.sendStatus(200)
res.json(reverted)
}
async function getLabels(req, res, next) {

View File

@@ -359,8 +359,9 @@ const RestoreManager = {
}
const threadIds = await getCommentThreadIds(projectId)
const reverted = []
for (const pathname of pathsAtPastVersion) {
await RestoreManager._revertSingleFile(
const res = await RestoreManager._revertSingleFile(
userId,
projectId,
version,
@@ -368,6 +369,11 @@ const RestoreManager = {
threadIds,
{ origin }
)
reverted.push({
id: res._id,
type: res.type,
path: pathname,
})
}
const entitiesAtLiveVersion =
@@ -391,6 +397,8 @@ const RestoreManager = {
)
}
}
return reverted
},
async _writeFileVersionToDisk(projectId, version, pathname) {

View File

@@ -1,7 +1,12 @@
import { useCallback, useState } from 'react'
import { useCallback, useState, useEffect } from 'react'
import { useErrorBoundary } from 'react-error-boundary'
import { restoreProjectToVersion } from '../../services/api'
import { useLayoutContext } from '@/shared/context/layout-context'
import { useHistoryContext } from '../history-context'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import { findInTree } from '@/features/file-tree/util/find-in-tree'
import { RestoreProjectResponse } from '../../services/types/restore-file'
type RestorationState = 'initial' | 'restoring' | 'restored' | 'error'
@@ -11,21 +16,56 @@ export const useRestoreProject = () => {
const [restorationState, setRestorationState] =
useState<RestorationState>('initial')
const { selection } = useHistoryContext()
const { openDocWithId, openFileWithId } = useEditorManagerContext()
const { fileTreeData } = useFileTreeData()
const [restoredEntities, setRestoredEntities] =
useState<RestoreProjectResponse | null>(null)
useEffect(() => {
if (restorationState === 'restoring' && restoredEntities) {
const entity =
restoredEntities.find(
item => item.path === selection.selectedFile?.pathname
) || restoredEntities[0]
if (entity) {
const result = findInTree(fileTreeData, entity.id)
if (result) {
if (entity.type === 'doc') {
openDocWithId(entity.id)
} else if (entity.type === 'file') {
openFileWithId(entity.id)
}
}
}
setRestorationState('restored')
restoreView()
}
}, [
fileTreeData,
restoredEntities,
openDocWithId,
openFileWithId,
restoreView,
restorationState,
selection.selectedFile?.pathname,
])
const restoreProject = useCallback(
(projectId: string, version: number) => {
setRestorationState('restoring')
restoreProjectToVersion(projectId, version)
.then(() => {
setRestorationState('restored')
restoreView()
.then((res: RestoreProjectResponse) => {
setRestoredEntities(res)
})
.catch(err => {
setRestorationState('error')
showBoundary(err)
})
},
[showBoundary, restoreView]
[showBoundary]
)
return {

View File

@@ -2,3 +2,9 @@ export type RestoreFileResponse = {
id: string
type: 'doc' | 'file'
}
export type RestoreProjectResponse = Array<{
id: string
path: string
type: 'doc' | 'file'
}>

View File

@@ -993,7 +993,10 @@ describe('RestoreManager', function () {
this.ProjectGetter.promises.getProject
.withArgs(this.project_id)
.resolves({ overleaf: { history: { rangesSupportEnabled: true } } })
this.RestoreManager.promises._revertSingleFile = sinon.stub().resolves()
this.RestoreManager.promises._revertSingleFile = sinon.stub().resolves({
_id: 'mock-doc-id',
type: 'doc',
})
this.RestoreManager.promises._getProjectPathsAtVersion = sinon
.stub()
.resolves([])