mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-19 20:43:11 +00:00
Refactor project-wide settings:
- Change api function argument (readability) - create a new wrapper hooks for saving the project to both server-side and angular scope - Implement the new save project settings hooks on project-wide settings update - On spell check language update function, add new comment to give more context about the decision GitOrigin-RevId: 93d558d1e1d4db265a943eeb4366842430900c43
This commit is contained in:
parent
654144dd40
commit
7475237170
5 changed files with 60 additions and 54 deletions
|
@ -1,40 +1,27 @@
|
|||
import { useCallback } from 'react'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import useScopeValue from '../../../shared/hooks/use-scope-value'
|
||||
import { type ProjectSettings, saveProjectSettings } from '../utils/api'
|
||||
import type { ProjectSettings } from '../utils/api'
|
||||
import useRootDocId from './use-root-doc-id'
|
||||
import useSaveProjectSettings from './use-save-project-settings'
|
||||
import useSetSpellCheckLanguage from './use-set-spell-check-language'
|
||||
|
||||
export default function useProjectWideSettings() {
|
||||
// The value will be undefined on mount
|
||||
const [project, setProject] = useScopeValue<ProjectSettings | undefined>(
|
||||
'project',
|
||||
true
|
||||
)
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const [project] = useScopeValue<ProjectSettings | undefined>('project', true)
|
||||
const saveProjectSettings = useSaveProjectSettings()
|
||||
|
||||
const setCompiler = useCallback(
|
||||
(compiler: ProjectSettings['compiler']) => {
|
||||
const allowUpdate = project?.compiler
|
||||
|
||||
if (allowUpdate) {
|
||||
setProject({ ...project, compiler })
|
||||
saveProjectSettings({ projectId, compiler })
|
||||
}
|
||||
(newCompiler: ProjectSettings['compiler']) => {
|
||||
saveProjectSettings('compiler', newCompiler)
|
||||
},
|
||||
[projectId, project, setProject]
|
||||
[saveProjectSettings]
|
||||
)
|
||||
|
||||
const setImageName = useCallback(
|
||||
(imageName: ProjectSettings['imageName']) => {
|
||||
const allowUpdate = project?.imageName
|
||||
|
||||
if (allowUpdate) {
|
||||
setProject({ ...project, imageName })
|
||||
saveProjectSettings({ projectId, imageName })
|
||||
}
|
||||
(newImageName: ProjectSettings['imageName']) => {
|
||||
saveProjectSettings('imageName', newImageName)
|
||||
},
|
||||
[projectId, project, setProject]
|
||||
[saveProjectSettings]
|
||||
)
|
||||
|
||||
const { setRootDocId, rootDocId } = useRootDocId()
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
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 { type ProjectSettings, saveProjectSettings } from '../utils/api'
|
||||
import type { ProjectSettings } from '../utils/api'
|
||||
import useSaveProjectSettings from './use-save-project-settings'
|
||||
|
||||
export default function useRootDocId() {
|
||||
const [rootDocId, setRootDocId] =
|
||||
const [rootDocId] =
|
||||
useScopeValue<ProjectSettings['rootDocId']>('project.rootDoc_id')
|
||||
const { permissionsLevel } = useEditorContext()
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const saveProjectSettings = useSaveProjectSettings()
|
||||
|
||||
const setRootDocIdFunc = useCallback(
|
||||
async (newRootDocId: ProjectSettings['rootDocId']) => {
|
||||
// rootDoc_id will be undefined on angular scope on initialisation
|
||||
const allowUpdate =
|
||||
typeof rootDocId !== 'undefined' &&
|
||||
permissionsLevel !== 'readOnly' &&
|
||||
rootDocId !== newRootDocId
|
||||
typeof rootDocId !== 'undefined' && permissionsLevel !== 'readOnly'
|
||||
|
||||
if (allowUpdate) {
|
||||
try {
|
||||
await saveProjectSettings({ projectId, rootDocId: newRootDocId })
|
||||
setRootDocId(newRootDocId)
|
||||
await saveProjectSettings('rootDocId', newRootDocId)
|
||||
} catch (err) {
|
||||
// TODO: retry mechanism (max 10x before failed completely and rollback the old value)
|
||||
}
|
||||
}
|
||||
},
|
||||
[permissionsLevel, projectId, rootDocId, setRootDocId]
|
||||
[permissionsLevel, rootDocId, saveProjectSettings]
|
||||
)
|
||||
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import { type ProjectSettings, saveProjectSettings } from '../utils/api'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import useScopeValue from '../../../shared/hooks/use-scope-value'
|
||||
|
||||
export default function useSaveProjectSettings() {
|
||||
// projectSettings value will be undefined on mount
|
||||
const [projectSettings, setProjectSettings] = useScopeValue<
|
||||
ProjectSettings | undefined
|
||||
>('project', true)
|
||||
const { _id: projectId } = useProjectContext()
|
||||
|
||||
return async (
|
||||
key: keyof ProjectSettings,
|
||||
newSetting: ProjectSettings[keyof ProjectSettings]
|
||||
) => {
|
||||
if (projectSettings) {
|
||||
const currentSetting = projectSettings[key]
|
||||
|
||||
if (currentSetting !== newSetting) {
|
||||
await saveProjectSettings(projectId, {
|
||||
[key]: newSetting,
|
||||
})
|
||||
|
||||
setProjectSettings({ ...projectSettings, [key]: newSetting })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,13 @@
|
|||
import { useCallback } from 'react'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import useScopeValue from '../../../shared/hooks/use-scope-value'
|
||||
import {
|
||||
type ProjectSettings,
|
||||
saveProjectSettings,
|
||||
saveUserSettings,
|
||||
} from '../utils/api'
|
||||
import { type ProjectSettings, saveUserSettings } from '../utils/api'
|
||||
import useSaveProjectSettings from './use-save-project-settings'
|
||||
|
||||
export default function useSetSpellCheckLanguage() {
|
||||
const [spellCheckLanguage, setSpellCheckLanguage] = useScopeValue<
|
||||
ProjectSettings['spellCheckLanguage']
|
||||
>('project.spellCheckLanguage')
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const saveProjectSettings = useSaveProjectSettings()
|
||||
|
||||
return useCallback(
|
||||
(newSpellCheckLanguage: ProjectSettings['spellCheckLanguage']) => {
|
||||
|
@ -21,14 +17,15 @@ export default function useSetSpellCheckLanguage() {
|
|||
if (allowUpdate) {
|
||||
setSpellCheckLanguage(newSpellCheckLanguage)
|
||||
|
||||
// save to both project setting and user setting
|
||||
saveProjectSettings({
|
||||
projectId,
|
||||
spellCheckLanguage: newSpellCheckLanguage,
|
||||
})
|
||||
// Save project settings is created from hooks because it will save the value on
|
||||
// both server-side and client-side (angular scope)
|
||||
saveProjectSettings('spellCheckLanguage', newSpellCheckLanguage)
|
||||
|
||||
// For user settings, we only need to save it on server-side,
|
||||
// so we import the function directly without hooks
|
||||
saveUserSettings('spellCheckLanguage', newSpellCheckLanguage)
|
||||
}
|
||||
},
|
||||
[projectId, setSpellCheckLanguage, spellCheckLanguage]
|
||||
[setSpellCheckLanguage, spellCheckLanguage, saveProjectSettings]
|
||||
)
|
||||
}
|
||||
|
|
|
@ -53,14 +53,10 @@ export function saveUserSettings(
|
|||
})
|
||||
}
|
||||
|
||||
type SaveProjectSettings = {
|
||||
projectId: string
|
||||
} & Partial<ProjectSettings>
|
||||
|
||||
export const saveProjectSettings = async ({
|
||||
projectId,
|
||||
...data
|
||||
}: SaveProjectSettings) => {
|
||||
export const saveProjectSettings = async (
|
||||
projectId: string,
|
||||
data: Partial<ProjectSettings>
|
||||
) => {
|
||||
await postJSON<never>(`/project/${projectId}/settings`, {
|
||||
body: {
|
||||
...data,
|
||||
|
|
Loading…
Add table
Reference in a new issue