Просмотр исходного кода

replace save project setting hooks with common function and implement set root doc id change

GitOrigin-RevId: e5b204cd93fc188288def529cb22018b3d4f89b6
M Fahru 3 лет назад
Родитель
Сommit
132bb40a21

+ 11 - 42
services/web/frontend/js/features/editor-left-menu/hooks/use-set-project-wide-settings.tsx

@@ -1,80 +1,49 @@
 import { useCallback } from 'react'
 import { ProjectCompiler } from '../../../../../types/project-settings'
-import { postJSON } from '../../../infrastructure/fetch-json'
 import { useProjectContext } from '../../../shared/context/project-context'
 import useScopeValue from '../../../shared/hooks/use-scope-value'
-
-type ProjectScope = {
-  compiler: ProjectCompiler
-  imageName: string
-  rootDoc_id: string
-  spellCheckLanguage: string
-}
-
-function useSaveProjectSettings() {
-  const { _id: projectId } = useProjectContext()
-
-  const saveProject = useCallback(
-    (data: Partial<ProjectScope>) => {
-      postJSON(`/project/${projectId}/settings`, {
-        body: data,
-      })
-    },
-    [projectId]
-  )
-
-  return saveProject
-}
+import { ProjectSettingsScope, saveProjectSettings } from '../utils/api'
+import useSetRootDocId from './use-set-root-doc-id'
 
 // TODO: handle ignoreUpdates
 export default function useSetProjectWideSettings() {
   // The value will be undefined on mount
-  const [project, setProject] = useScopeValue<ProjectScope | undefined>(
+  const [project, setProject] = useScopeValue<ProjectSettingsScope | undefined>(
     'project',
     true
   )
-
-  const saveProject = useSaveProjectSettings()
+  const { _id: projectId } = useProjectContext()
 
   const setCompiler = useCallback(
     (compiler: ProjectCompiler) => {
       if (project?.compiler) {
         setProject({ ...project, compiler })
-        saveProject({ compiler })
+        saveProjectSettings(projectId, { compiler })
       }
     },
-    [saveProject, project, setProject]
+    [projectId, project, setProject]
   )
 
   const setImageName = useCallback(
     (imageName: string) => {
       if (project?.imageName) {
         setProject({ ...project, imageName })
-        saveProject({ imageName })
+        saveProjectSettings(projectId, { imageName })
       }
     },
-    [saveProject, project, setProject]
+    [projectId, project, setProject]
   )
 
-  // TODO
-  const setRootDocId = useCallback(
-    (rootDocId: string) => {
-      if (project?.imageName) {
-        setProject({ ...project, rootDoc_id: rootDocId })
-        // saveProject({ root })
-      }
-    },
-    [project, setProject]
-  )
+  const setRootDocId = useSetRootDocId()
 
   const setSpellCheckLanguage = useCallback(
     (spellCheckLanguage: string) => {
       if (project?.spellCheckLanguage) {
         setProject({ ...project, spellCheckLanguage })
-        saveProject({ spellCheckLanguage })
+        saveProjectSettings(projectId, { spellCheckLanguage })
       }
     },
-    [saveProject, project, setProject]
+    [projectId, project, setProject]
   )
 
   return {

+ 32 - 0
services/web/frontend/js/features/editor-left-menu/hooks/use-set-root-doc-id.tsx

@@ -0,0 +1,32 @@
+import { useCallback } from 'react'
+import { useEditorContext } from '../../../shared/context/editor-context'
+import { useProjectContext } from '../../../shared/context/project-context'
+import useScopeValue from '../../../shared/hooks/use-scope-value'
+import { saveProjectSettings } from '../utils/api'
+
+export default function useSetRootDocId() {
+  const [rootDocIdScope, setRootDocIdScope] =
+    useScopeValue<string>('project.rootDoc_id')
+  const { permissionsLevel } = useEditorContext()
+  const { _id: projectId } = useProjectContext()
+
+  const setRootDocId = useCallback(
+    async (rootDocId: string) => {
+      const disallowChange =
+        typeof rootDocIdScope === 'undefined' ||
+        permissionsLevel === 'readOnly' ||
+        rootDocIdScope === rootDocId
+
+      if (!disallowChange) {
+        try {
+          await saveProjectSettings(projectId, { rootDoc_id: rootDocId })
+          setRootDocIdScope(rootDocId)
+        } catch (err) {
+          // TODO: retry mechanism (max 10x before failed completely and rollback the old value)
+        }
+      }
+    },
+    [permissionsLevel, projectId, rootDocIdScope, setRootDocIdScope]
+  )
+  return setRootDocId
+}

+ 21 - 1
services/web/frontend/js/features/editor-left-menu/utils/api.ts

@@ -3,7 +3,11 @@ import {
   LineHeight,
   OverallTheme,
 } from '../../../../../modules/source-editor/frontend/js/extensions/theme'
-import { Keybindings, PdfViewer } from '../../../../../types/project-settings'
+import {
+  Keybindings,
+  PdfViewer,
+  ProjectCompiler,
+} from '../../../../../types/project-settings'
 import { postJSON } from '../../../infrastructure/fetch-json'
 
 export type UserSettingsScope = {
@@ -24,3 +28,19 @@ export function saveUserSettings(data: Partial<UserSettingsScope>) {
     body: data,
   })
 }
+
+export type ProjectSettingsScope = {
+  compiler: ProjectCompiler
+  imageName: string
+  rootDoc_id: string
+  spellCheckLanguage: string
+}
+
+export const saveProjectSettings = async (
+  projectId: string,
+  data: Partial<ProjectSettingsScope>
+) => {
+  await postJSON<never>(`/project/${projectId}/settings`, {
+    body: data,
+  })
+}