diff --git a/services/web/frontend/js/features/review-panel/context/track-changes-state-context.tsx b/services/web/frontend/js/features/review-panel/context/track-changes-state-context.tsx index f2fb4c7ebe..a817539fc4 100644 --- a/services/web/frontend/js/features/review-panel/context/track-changes-state-context.tsx +++ b/services/web/frontend/js/features/review-panel/context/track-changes-state-context.tsx @@ -14,11 +14,13 @@ import { useEditorPropertiesContext } from '@/features/ide-react/context/editor- import { useUserContext } from '@/shared/context/user-context' import { postJSON } from '@/infrastructure/fetch-json' import useEventListener from '@/shared/hooks/use-event-listener' -import { ProjectMetadata } from '@/shared/context/types/project-metadata' +import { + ProjectMetadata, + TrackChangesStateData, +} from '@/shared/context/types/project-metadata' import { usePermissionsContext } from '@/features/ide-react/context/permissions-context' export type TrackChangesState = { - onForEveryone: boolean onForGuests: boolean onForMembers: Record } @@ -28,7 +30,6 @@ export const TrackChangesStateContext = createContext< >(undefined) type SaveTrackChangesRequestBody = { - on?: boolean on_for?: Record on_for_guests?: boolean } @@ -51,8 +52,13 @@ export const TrackChangesStateProvider: FC = ({ const user = useUserContext() const { setWantTrackChanges } = useEditorPropertiesContext() - const trackChangesValue: ProjectMetadata['trackChangesState'] = - project?.trackChangesState ?? false + const trackChangesValue = useMemo(() => { + if (typeof project?.trackChangesState === 'object') { + return project.trackChangesState + } else { + return {} + } + }, [project?.trackChangesState]) useSocketListener( socket, @@ -66,31 +72,19 @@ export const TrackChangesStateProvider: FC = ({ ) useEffect(() => { - setWantTrackChanges( - trackChangesValue === true || - (trackChangesValue !== false && - trackChangesValue[user.id ?? '__guests__']) - ) + setWantTrackChanges(Boolean(trackChangesValue[user.id ?? '__guests__'])) }, [setWantTrackChanges, trackChangesValue, user.id]) - - const trackChangesIsObject = - trackChangesValue !== true && trackChangesValue !== false - const onForEveryone = trackChangesValue === true - const onForGuests = - onForEveryone || - (trackChangesIsObject && trackChangesValue.__guests__ === true) + const onForGuests = trackChangesValue.__guests__ === true const onForMembers = useMemo(() => { const onForMembers: Record = {} - if (trackChangesIsObject) { - for (const key of Object.keys(trackChangesValue)) { - if (key !== '__guests__') { - onForMembers[key as UserId] = trackChangesValue[key as UserId] - } + for (const key of Object.keys(trackChangesValue)) { + if (key !== '__guests__') { + onForMembers[key as UserId] = trackChangesValue[key as UserId] } } return onForMembers - }, [trackChangesIsObject, trackChangesValue]) + }, [trackChangesValue]) const saveTrackChanges = useCallback( async (trackChangesBody: SaveTrackChangesRequestBody) => { @@ -126,12 +120,7 @@ export const TrackChangesStateProvider: FC = ({ useEventListener( 'toggle-track-changes', useCallback(() => { - if ( - user.id && - features.trackChanges && - permissions.write && - !onForEveryone - ) { + if (user.id && features.trackChanges && permissions.write) { const value = onForMembers[user.id] actions.saveTrackChanges({ on_for: { @@ -143,7 +132,6 @@ export const TrackChangesStateProvider: FC = ({ }, [ actions, onForMembers, - onForEveryone, permissions.write, features.trackChanges, user.id, @@ -151,8 +139,8 @@ export const TrackChangesStateProvider: FC = ({ ) const value = useMemo( - () => ({ onForEveryone, onForGuests, onForMembers }), - [onForEveryone, onForGuests, onForMembers] + () => ({ onForGuests, onForMembers }), + [onForGuests, onForMembers] ) return ( diff --git a/services/web/frontend/js/shared/context/types/project-metadata.tsx b/services/web/frontend/js/shared/context/types/project-metadata.tsx index e69a25c910..489c254e23 100644 --- a/services/web/frontend/js/shared/context/types/project-metadata.tsx +++ b/services/web/frontend/js/shared/context/types/project-metadata.tsx @@ -41,7 +41,14 @@ export interface ProjectMetadata extends ProjectSettings { signUpDate: string } rootFolder?: Folder[] - trackChangesState: boolean | Record + trackChangesState?: false | TrackChangesStateData } +// The explicit per-user track changes format, keyed by user id. The +// `__guests__` key toggles track changes for link-sharing guests (it is still +// used by some Server Pro organisations) +export type TrackChangesStateData = Partial< + Record +> + export type ProjectUpdate = Partial diff --git a/services/web/frontend/js/shared/hooks/use-tracking-changes-mode.ts b/services/web/frontend/js/shared/hooks/use-tracking-changes-mode.ts index 55d6898fed..9ec51ca47d 100644 --- a/services/web/frontend/js/shared/hooks/use-tracking-changes-mode.ts +++ b/services/web/frontend/js/shared/hooks/use-tracking-changes-mode.ts @@ -15,10 +15,9 @@ export const useTrackingChangesMode = (): Mode => { return 'review' } - const trackChangesForCurrentUser = - trackChanges?.onForEveryone || - (user?.id && trackChanges?.onForMembers[user.id]) || - (!user?.id && trackChanges?.onForGuests) + const trackChangesForCurrentUser = user?.id + ? trackChanges?.onForMembers[user.id] + : trackChanges?.onForGuests if (trackChangesForCurrentUser) { return 'review' diff --git a/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx b/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx index 1635e96324..16e5afc79f 100644 --- a/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx +++ b/services/web/test/frontend/features/source-editor/components/codemirror-editor-context-menu.spec.tsx @@ -566,7 +566,7 @@ describe('editor context menu', { scrollBehavior: false }, function () { ProjectProvider: makeProjectProvider( mockProject({ // Re-assigns `withTrackChanges` value in the `track-changes-state-context` useEffect hook - trackChangesState: true, + trackChangesState: { [USER_ID]: true }, projectFeatures: { trackChanges: true, trackChangesVisible: true, diff --git a/services/web/test/frontend/helpers/editor-providers.tsx b/services/web/test/frontend/helpers/editor-providers.tsx index 4ecfc22588..194e937fa9 100644 --- a/services/web/test/frontend/helpers/editor-providers.tsx +++ b/services/web/test/frontend/helpers/editor-providers.tsx @@ -44,6 +44,7 @@ import type { DocumentContainer } from '@/features/ide-react/editor/document-con import { ProjectMetadata, ProjectUpdate, + TrackChangesStateData, } from '@/shared/context/types/project-metadata' import { User, UserId } from '../../../types/user' import { ProjectCompiler } from '../../../types/project-settings' @@ -132,7 +133,7 @@ export const projectDefaults: ProjectMetadata = { compiler: 'pdflatex' as ProjectCompiler, members: [], invites: [], - trackChangesState: {} as Record, + trackChangesState: {} as TrackChangesStateData, spellCheckLanguage: 'en', } @@ -233,7 +234,7 @@ export function EditorProviders({ compiler, members: [], invites: [], - trackChangesState: false, + trackChangesState: {} as TrackChangesStateData, spellCheckLanguage: 'en', }