Browse Source

Merge pull request #34923 from overleaf/mj-left-menu-field

[web] Clean up "left menu" concepts in new editor

GitOrigin-RevId: 9597c1c53af15f3a1587e62176bca36cd7c9069c
Mathias Jakobsen 1 tháng trước cách đây
mục cha
commit
75f7f82a3f

+ 0 - 46
services/web/frontend/js/features/editor-left-menu/components/editor-left-menu-context.tsx

@@ -1,46 +0,0 @@
-import { createContext, FC, useCallback, useContext, useState } from 'react'
-import useEventListener from '@/shared/hooks/use-event-listener'
-
-type EditorLeftMenuState = {
-  settingToFocus?: string
-}
-
-export const EditorLeftMenuContext = createContext<
-  EditorLeftMenuState | undefined
->(undefined)
-
-export const EditorLeftMenuProvider: FC<React.PropsWithChildren> = ({
-  children,
-}) => {
-  const [value, setValue] = useState<EditorLeftMenuState>(() => ({
-    settingToFocus: undefined,
-  }))
-
-  useEventListener(
-    'ui.focus-setting',
-    useCallback((event: CustomEvent<string>) => {
-      setValue(value => ({
-        ...value,
-        settingToFocus: event.detail,
-      }))
-    }, [])
-  )
-
-  return (
-    <EditorLeftMenuContext.Provider value={value}>
-      {children}
-    </EditorLeftMenuContext.Provider>
-  )
-}
-
-export const useEditorLeftMenuContext = () => {
-  const value = useContext(EditorLeftMenuContext)
-
-  if (!value) {
-    throw new Error(
-      `useEditorLeftMenuContext is only available inside EditorLeftMenuProvider`
-    )
-  }
-
-  return value
-}

+ 5 - 5
services/web/frontend/js/features/ide-react/components/rail/rail.tsx

@@ -73,7 +73,7 @@ export const RailLayout = () => {
   const gitBridgeEnabled = getMeta('ol-gitBridgeEnabled')
   const { isOverleaf } = getMeta('ol-ExposedSettings')
 
-  const { view, setLeftMenuShown, focusMode } = useLayoutContext()
+  const { view, setSettingsShown, focusMode } = useLayoutContext()
 
   const { markMessagesAsRead } = useChatContext()
 
@@ -166,11 +166,11 @@ export const RailLayout = () => {
         title: t('settings'),
         action: () => {
           sendEvent('rail-click', { tab: 'settings' })
-          setLeftMenuShown(true)
+          setSettingsShown(true)
         },
       },
     ],
-    [setLeftMenuShown, t, sendEvent]
+    [setSettingsShown, t, sendEvent]
   )
 
   useCommandProvider(
@@ -178,13 +178,13 @@ export const RailLayout = () => {
       {
         id: 'open-settings',
         handler: () => {
-          setLeftMenuShown(true)
+          setSettingsShown(true)
         },
         menuLabel: t('settings'),
         label: t('open_settings'),
       },
     ],
-    [t, setLeftMenuShown]
+    [t, setSettingsShown]
   )
 
   const onTabSelect = useCallback(

+ 3 - 3
services/web/frontend/js/features/ide-react/hooks/use-layout-event-tracking.ts

@@ -3,7 +3,7 @@ import { useEffect } from 'react'
 import { sendMBOnce } from '@/infrastructure/event-tracking'
 
 export function useLayoutEventTracking() {
-  const { view, leftMenuShown, chatIsOpen } = useLayoutContext()
+  const { view, settingsShown, chatIsOpen } = useLayoutContext()
 
   useEffect(() => {
     if (view && view !== 'editor' && view !== 'pdf') {
@@ -12,10 +12,10 @@ export function useLayoutEventTracking() {
   }, [view])
 
   useEffect(() => {
-    if (leftMenuShown) {
+    if (settingsShown) {
       sendMBOnce(`ide-open-left-menu-once`)
     }
-  }, [leftMenuShown])
+  }, [settingsShown])
 
   useEffect(() => {
     if (chatIsOpen) {

+ 3 - 5
services/web/frontend/js/features/settings/components/editor-settings/dictionary-setting.tsx

@@ -8,14 +8,12 @@ export default function DictionarySetting() {
   const { t } = useTranslation()
   const { setActiveModal } = useRailContext()
 
-  // TODO ide-redesign-cleanup: leftMenu is a misnomer, in the
-  // redesign it refers to the settings modal
-  const { setLeftMenuShown } = useLayoutContext()
+  const { setSettingsShown } = useLayoutContext()
 
   const onClick = useCallback(() => {
     setActiveModal('dictionary')
-    setLeftMenuShown(false)
-  }, [setLeftMenuShown, setActiveModal])
+    setSettingsShown(false)
+  }, [setSettingsShown, setActiveModal])
 
   return (
     <ButtonSetting

+ 30 - 14
services/web/frontend/js/features/settings/context/settings-modal-context.tsx

@@ -1,4 +1,11 @@
-import { createContext, FC, useContext, useMemo, useState } from 'react'
+import {
+  createContext,
+  FC,
+  useCallback,
+  useContext,
+  useMemo,
+  useState,
+} from 'react'
 import { useLayoutContext } from '@/shared/context/layout-context'
 import AutoCloseBracketsSetting from '@/features/settings/components/editor-settings/auto-close-brackets-setting'
 import AutoCompleteSetting from '@/features/settings/components/editor-settings/auto-complete-setting'
@@ -24,7 +31,6 @@ import EditorThemeSetting from '@/features/settings/components/appearance-settin
 import FontSizeSetting from '@/features/settings/components/appearance-settings/font-size-setting'
 import LineHeightSetting from '@/features/settings/components/appearance-settings/line-height-setting'
 import FontFamilySetting from '@/features/settings/components/appearance-settings/font-family-setting'
-import { EditorLeftMenuProvider } from '@/features/editor-left-menu/components/editor-left-menu-context'
 import DarkModePdfSetting from '@/features/settings/components/appearance-settings/dark-mode-pdf-setting'
 
 import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
@@ -38,6 +44,7 @@ import type {
 } from '@/features/settings/context/types'
 import EditorTabsSetting from '../components/editor-settings/editor-tabs-setting'
 import FloatingMenuSetting from '../components/editor-settings/floating-menu-setting'
+import useEventListener from '@/shared/hooks/use-event-listener'
 
 const [referenceSearchSettingModule] = importOverleafModules(
   'referenceSearchSetting'
@@ -65,6 +72,7 @@ type SettingsModalState = {
   setActiveTab: (tab: string | null | undefined) => void
   settingsTabs: SettingsEntry[]
   settingToTabMap: Map<string, string>
+  settingToFocus?: string
 }
 
 export const SettingsModalContext = createContext<
@@ -77,9 +85,18 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
   const { t } = useTranslation()
   const { isOverleaf } = getMeta('ol-ExposedSettings')
   const { overallTheme, floatingMenu } = useProjectSettingsContext()
+  const [settingToFocus, setSettingToFocus] = useState<string | undefined>(
+    undefined
+  )
+
+  useEventListener(
+    'ui.focus-setting',
+    useCallback((event: CustomEvent<string | undefined>) => {
+      setSettingToFocus(event.detail)
+    }, [])
+  )
 
-  // TODO ide-redesign-cleanup: Rename this field and move it directly into this context
-  const { leftMenuShown, setLeftMenuShown } = useLayoutContext()
+  const { settingsShown, setSettingsShown } = useLayoutContext()
 
   const hasEmailNotifications = useFeatureFlag('email-notifications')
   const hasEditorTabs = useFeatureFlag('editor-tabs')
@@ -327,30 +344,29 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
 
   const value = useMemo(
     () => ({
-      show: leftMenuShown,
-      setShow: setLeftMenuShown,
+      show: settingsShown,
+      setShow: setSettingsShown,
       activeTab,
       setActiveTab,
       settingsTabs,
       settingToTabMap,
+      settingToFocus,
     }),
     [
-      leftMenuShown,
-      setLeftMenuShown,
+      settingsShown,
+      setSettingsShown,
       activeTab,
       setActiveTab,
       settingsTabs,
       settingToTabMap,
+      settingToFocus,
     ]
   )
 
   return (
-    // TODO ide-redesign-cleanup: Merge <EditorLeftMenuProvider> into <SettingsModalProvider>
-    <EditorLeftMenuProvider>
-      <SettingsModalContext.Provider value={value}>
-        {children}
-      </SettingsModalContext.Provider>
-    </EditorLeftMenuProvider>
+    <SettingsModalContext.Provider value={value}>
+      {children}
+    </SettingsModalContext.Provider>
   )
 }
 

+ 2 - 3
services/web/frontend/js/features/settings/hooks/use-focus-on-setting.tsx

@@ -1,4 +1,3 @@
-import { useEditorLeftMenuContext } from '@/features/editor-left-menu/components/editor-left-menu-context'
 import { useEffect, useState } from 'react'
 import { useSettingsModalContext } from '../context/settings-modal-context'
 
@@ -6,8 +5,8 @@ import { useSettingsModalContext } from '../context/settings-modal-context'
  *  A hook to scroll to and focus on a specific setting in the settings modal
  */
 export default function useFocusOnSetting() {
-  const { activeTab, setActiveTab, settingToTabMap } = useSettingsModalContext()
-  const { settingToFocus } = useEditorLeftMenuContext()
+  const { activeTab, setActiveTab, settingToTabMap, settingToFocus } =
+    useSettingsModalContext()
 
   const [eltToScrollTo, setEltToScrollTo] = useState<{
     tab: string | undefined

+ 1 - 1
services/web/frontend/js/features/source-editor/components/tabs/tabs-context-menu.tsx

@@ -118,7 +118,7 @@ export function TabsContextMenu() {
             as="button"
             onClick={() => {
               window.dispatchEvent(
-                new CustomEvent('ui.toggle-left-menu', { detail: true })
+                new CustomEvent('ui.toggle-settings', { detail: true })
               )
               // focus the tab setting
               window.dispatchEvent(

+ 2 - 2
services/web/frontend/js/features/source-editor/extensions/spelling/spelling-suggestions-language.tsx

@@ -11,9 +11,9 @@ export const SpellingSuggestionsLanguage = memo<{
   const { t } = useTranslation()
 
   const handleClick = useCallback(() => {
-    // open the left menu
+    // open settings
     window.dispatchEvent(
-      new CustomEvent('ui.toggle-left-menu', { detail: true })
+      new CustomEvent('ui.toggle-settings', { detail: true })
     )
     // focus the spell check setting
     window.dispatchEvent(

+ 12 - 12
services/web/frontend/js/shared/context/layout-context.tsx

@@ -34,7 +34,7 @@ export type LayoutContextOwnStates = {
   chatIsOpen: boolean
   reviewPanelOpen: boolean
   miniReviewPanelVisible: boolean
-  leftMenuShown: boolean
+  settingsShown: boolean
   loadingStyleSheet: boolean
   pdfLayout: IdeLayout
   projectSearchIsOpen: boolean
@@ -56,8 +56,8 @@ export type LayoutContextValue = LayoutContextOwnStates & {
   setMiniReviewPanelVisible: Dispatch<
     SetStateAction<LayoutContextValue['miniReviewPanelVisible']>
   >
-  setLeftMenuShown: Dispatch<
-    SetStateAction<LayoutContextValue['leftMenuShown']>
+  setSettingsShown: Dispatch<
+    SetStateAction<LayoutContextValue['settingsShown']>
   >
   setLoadingStyleSheet: Dispatch<
     SetStateAction<LayoutContextValue['loadingStyleSheet']>
@@ -151,8 +151,8 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
   const [miniReviewPanelVisible, setMiniReviewPanelVisible] =
     useState<boolean>(false)
 
-  // whether the menu pane is open
-  const [leftMenuShown, setLeftMenuShown] = useState<boolean>(false)
+  // whether the settings modal is open
+  const [settingsShown, setSettingsShown] = useState<boolean>(false)
 
   // whether the project search is open
   const [projectSearchIsOpen, setProjectSearchIsOpen] = useState(false)
@@ -189,12 +189,12 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
   )
 
   useEventListener(
-    'ui.toggle-left-menu',
+    'ui.toggle-settings',
     useCallback(
       (event: CustomEvent<boolean>) => {
-        setLeftMenuShown(event.detail)
+        setSettingsShown(event.detail)
       },
-      [setLeftMenuShown]
+      [setSettingsShown]
     )
   )
 
@@ -388,7 +388,7 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
       detachRole,
       changeLayout,
       chatIsOpen,
-      leftMenuShown,
+      settingsShown,
       openFile,
       pdfLayout,
       pdfPreviewOpen,
@@ -398,7 +398,7 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
       miniReviewPanelVisible,
       loadingStyleSheet,
       setChatIsOpen,
-      setLeftMenuShown,
+      setSettingsShown,
       setOpenFile,
       setPdfLayout,
       setReviewPanelOpen,
@@ -419,7 +419,7 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
       detachRole,
       changeLayout,
       chatIsOpen,
-      leftMenuShown,
+      settingsShown,
       openFile,
       pdfLayout,
       pdfPreviewOpen,
@@ -429,7 +429,7 @@ export const LayoutProvider: FC<React.PropsWithChildren> = ({ children }) => {
       miniReviewPanelVisible,
       loadingStyleSheet,
       setChatIsOpen,
-      setLeftMenuShown,
+      setSettingsShown,
       setOpenFile,
       setPdfLayout,
       setReviewPanelOpen,

+ 2 - 2
services/web/test/frontend/features/full-project-search/components/full-project-search.spec.tsx

@@ -85,8 +85,8 @@ const createInitialValue = () =>
     setReviewPanelOpen: cy.stub(),
     miniReviewPanelVisible: false,
     setMiniReviewPanelVisible: cy.stub(),
-    leftMenuShown: false,
-    setLeftMenuShown: cy.stub(),
+    settingsShown: false,
+    setSettingsShown: cy.stub(),
     loadingStyleSheet: false,
     setLoadingStyleSheet: cy.stub(),
     pdfLayout: 'flat',

+ 7 - 7
services/web/test/frontend/features/settings-modal/settings-modal.test.tsx

@@ -117,7 +117,7 @@ describe('<SettingsModal />', function () {
     render(
       <EditorProviders
         rootFolder={[rootFolder as any]}
-        layoutContext={{ leftMenuShown: true }}
+        layoutContext={{ settingsShown: true }}
       >
         <SettingsModal />
       </EditorProviders>
@@ -144,7 +144,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>
@@ -158,7 +158,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>
@@ -184,7 +184,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>
@@ -203,7 +203,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>
@@ -222,7 +222,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>
@@ -242,7 +242,7 @@ describe('<SettingsModal />', function () {
       render(
         <EditorProviders
           rootFolder={[rootFolder as any]}
-          layoutContext={{ leftMenuShown: true }}
+          layoutContext={{ settingsShown: true }}
         >
           <SettingsModal />
         </EditorProviders>

+ 2 - 2
services/web/test/frontend/features/source-editor/components/tabs.spec.tsx

@@ -647,10 +647,10 @@ describe('File Tabs', function () {
       cy.findByRole('tab', { name: /intro\.tex/ }).rightclick()
       cy.findByRole('menuitem', { name: 'Tab settings…' }).click()
 
-      // opens the left settings menu...
+      // opens the settings modal...
       cy.get('@dispatchEvent').should(
         'have.been.calledWithMatch',
-        Cypress.sinon.match({ type: 'ui.toggle-left-menu', detail: true })
+        Cypress.sinon.match({ type: 'ui.toggle-settings', detail: true })
       )
       // ...and focuses the editorTabs setting
       cy.get('@dispatchEvent').should(

+ 6 - 6
services/web/test/frontend/helpers/editor-providers.tsx

@@ -146,7 +146,7 @@ const layoutContextDefault = {
   chatIsOpen: true, // false in the application, true in tests
   reviewPanelOpen: false,
   miniReviewPanelVisible: false,
-  leftMenuShown: false,
+  settingsShown: false,
   projectSearchIsOpen: false,
   pdfLayout: 'sideBySide',
   loadingStyleSheet: false,
@@ -487,7 +487,7 @@ const makeLayoutProvider = (
     const [miniReviewPanelVisible, setMiniReviewPanelVisible] = useState(
       layout.miniReviewPanelVisible
     )
-    const [leftMenuShown, setLeftMenuShown] = useState(layout.leftMenuShown)
+    const [settingsShown, setSettingsShown] = useState(layout.settingsShown)
     const [projectSearchIsOpen, setProjectSearchIsOpen] = useState(
       layout.projectSearchIsOpen
     )
@@ -558,7 +558,7 @@ const makeLayoutProvider = (
         detachRole,
         changeLayout,
         chatIsOpen,
-        leftMenuShown,
+        settingsShown,
         openFile,
         pdfLayout,
         pdfPreviewOpen,
@@ -568,7 +568,7 @@ const makeLayoutProvider = (
         miniReviewPanelVisible,
         loadingStyleSheet,
         setChatIsOpen,
-        setLeftMenuShown,
+        setSettingsShown,
         setOpenFile,
         setPdfLayout,
         setReviewPanelOpen,
@@ -589,7 +589,7 @@ const makeLayoutProvider = (
         detachRole,
         changeLayout,
         chatIsOpen,
-        leftMenuShown,
+        settingsShown,
         openFile,
         pdfLayout,
         pdfPreviewOpen,
@@ -599,7 +599,7 @@ const makeLayoutProvider = (
         miniReviewPanelVisible,
         loadingStyleSheet,
         setChatIsOpen,
-        setLeftMenuShown,
+        setSettingsShown,
         setOpenFile,
         setPdfLayout,
         setReviewPanelOpen,