From 065534819c4fcf37722b3df74c5d26a00a699266 Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 18 Jun 2026 07:50:02 +0000 Subject: [PATCH] Fix file tree refresh after convert and compiler sync on set-as-main - Convert: backend now returns parentFolderId+isNew; frontend calls dispatchCreateDoc directly so the new file appears without a page refresh - Set as main: infer compiler from file extension and POST both rootDocId and compiler together; updateProject propagates the change to the editor settings dropdown and project list immediately Co-Authored-By: Claude Sonnet 4.6 --- .../Downloads/ProjectDownloadsController.mjs | 2 +- .../file-tree-item-menu-items.tsx | 27 +++++++++++++++---- .../ide-react/hooks/use-convert-doc.ts | 17 +++++++++--- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs b/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs index 44dae22ee6..fde508a12e 100644 --- a/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs +++ b/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs @@ -264,7 +264,7 @@ async function convertDocInProject(req, res) { req.ip ) - res.json({ docId: resultDocId, name: resultName }) + res.json({ docId: resultDocId, name: resultName, parentFolderId: parentFolderId.toString(), isNew: !existingDoc }) } export default { diff --git a/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx b/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx index c014b20da9..da2f3bd439 100644 --- a/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx +++ b/services/web/frontend/js/features/file-tree/components/file-tree-item/file-tree-item-menu-items.tsx @@ -2,6 +2,8 @@ import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import * as eventTracking from '../../../../infrastructure/event-tracking' import { useProjectContext } from '@/shared/context/project-context' +import { postJSON } from '@/infrastructure/fetch-json' +import type { ProjectCompiler } from '@ol-types/project-settings' import { DropdownDivider, @@ -15,7 +17,16 @@ import { findInTree } from '../../util/find-in-tree' import useConvertDoc from '@/features/ide-react/hooks/use-convert-doc' import getMeta from '@/utils/meta' import { isValidTeXFile } from '@/main/is-valid-tex-file' -import { syncRootDocId } from '../../util/sync-mutation' + +const COMPILER_BY_EXT: Record = { + tex: 'pdflatex', + rtex: 'pdflatex', + ltx: 'pdflatex', + rnw: 'pdflatex', + typ: 'typst', + qmd: 'quarto', + rmd: 'quarto', +} function FileTreeItemMenuItems() { const { t } = useTranslation() @@ -74,10 +85,16 @@ function FileTreeItemMenuItems() { isValidTeXFile(convertEntityName) const handleSetAsMain = useCallback(async () => { - if (!convertEntityId) return - await syncRootDocId(projectId, convertEntityId) - updateProject({ rootDocId: convertEntityId }) - }, [convertEntityId, projectId, updateProject]) + if (!convertEntityId || !convertEntityName) return + const ext = convertEntityName.split('.').pop()?.toLowerCase() ?? '' + const newCompiler = COMPILER_BY_EXT[ext] + const body: Record = { rootDocId: convertEntityId } + if (newCompiler && newCompiler !== project?.compiler) body.compiler = newCompiler + await postJSON(`/project/${projectId}/settings`, { body }) + const update: Record = { rootDocId: convertEntityId } + if (newCompiler) update.compiler = newCompiler + updateProject(update) + }, [convertEntityId, convertEntityName, project, projectId, updateProject]) const { convert: convertToTypst } = useConvertDoc('typst', convertEntityId) const { convert: convertToLatex } = useConvertDoc('latex', convertEntityId) diff --git a/services/web/frontend/js/features/ide-react/hooks/use-convert-doc.ts b/services/web/frontend/js/features/ide-react/hooks/use-convert-doc.ts index 216ba933d7..74403cc051 100644 --- a/services/web/frontend/js/features/ide-react/hooks/use-convert-doc.ts +++ b/services/web/frontend/js/features/ide-react/hooks/use-convert-doc.ts @@ -1,5 +1,6 @@ import { postJSON } from '@/infrastructure/fetch-json' import { useProjectContext } from '@/shared/context/project-context' +import { useFileTreeData } from '@/shared/context/file-tree-data-context' import { useCallback, useState } from 'react' import { showExportDocumentError, @@ -12,6 +13,7 @@ export default function useConvertDoc( docId: string | null ) { const { projectId } = useProjectContext() + const { dispatchCreateDoc } = useFileTreeData() const [converting, setConverting] = useState(false) const convert = useCallback(async () => { @@ -19,17 +21,24 @@ export default function useConvertDoc( setConverting(true) hideExportDocumentError() try { - await postJSON(`/project/${projectId}/doc/${docId}/convert/${type}`, { - body: {}, - }) + const result = await postJSON( + `/project/${projectId}/doc/${docId}/convert/${type}`, + { body: {} } + ) showExportDocumentSuccess(type) + if (result.isNew) { + dispatchCreateDoc(result.parentFolderId, { + _id: result.docId, + name: result.name, + }) + } } catch (err: any) { const errorMessage = err?.data?.error showExportDocumentError(errorMessage) } finally { setConverting(false) } - }, [projectId, docId, type]) + }, [projectId, docId, type, dispatchCreateDoc]) return { convert, converting } }