toolbar.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { useTranslation } from 'react-i18next'
  2. import { ToolbarMenuBar } from './menu-bar'
  3. import { ToolbarProjectTitle } from './project-title'
  4. import { OnlineUsers } from './online-users'
  5. import ShareProjectButton from './share-project-button'
  6. import ChangeLayoutButton from './change-layout-button'
  7. import ShowHistoryButton from './show-history-button'
  8. import { useLayoutContext } from '@/shared/context/layout-context'
  9. import BackToEditorButton from '@/features/editor-navigation-toolbar/components/back-to-editor-button'
  10. import { useCallback } from 'react'
  11. import * as eventTracking from '../../../../infrastructure/event-tracking'
  12. import { ToolbarLogos } from './logos'
  13. import { useEditorContext } from '@/shared/context/editor-context'
  14. import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
  15. import UpgradeButton from './upgrade-button'
  16. import getMeta from '@/utils/meta'
  17. import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
  18. import { useFeatureFlag } from '@/shared/context/split-test-context'
  19. import OLIconButton from '@/shared/components/ol/ol-icon-button'
  20. import OLTooltip from '@/shared/components/ol/ol-tooltip'
  21. import SplitTestBadge from '@/shared/components/split-test-badge'
  22. const [publishModalModules] = importOverleafModules('publishModal')
  23. const SubmitProjectButton = publishModalModules?.import.NewPublishToolbarButton
  24. export const Toolbar = () => {
  25. const { view, restoreView, focusMode, setFocusMode, pdfLayout, setView } =
  26. useLayoutContext()
  27. const { cobranding, isRestrictedTokenMember } = useEditorContext()
  28. const { permissionsLevel } = useIdeReactContext()
  29. const showUpgradePrompt = getMeta('ol-showUpgradePrompt')
  30. const upgradeButtonRelocation = useFeatureFlag(
  31. 'editor-upgrade-button-relocation'
  32. )
  33. const { t } = useTranslation()
  34. const shouldDisplaySubmitButton =
  35. (permissionsLevel === 'owner' || permissionsLevel === 'readAndWrite') &&
  36. SubmitProjectButton
  37. const handleBackToEditorClick = useCallback(() => {
  38. eventTracking.sendMB('navigation-clicked-history', { action: 'close' })
  39. restoreView()
  40. }, [restoreView])
  41. const handleExitFocusMode = useCallback(() => {
  42. setFocusMode(false)
  43. eventTracking.sendMB('focus-mode-exit')
  44. }, [setFocusMode])
  45. const handleSwitchView = useCallback(() => {
  46. const newView = view === 'pdf' ? 'editor' : 'pdf'
  47. setView(newView)
  48. eventTracking.sendMB('focus-mode-switch-view', { view: newView })
  49. }, [view, setView])
  50. if (focusMode) {
  51. const showViewSwitcher = pdfLayout === 'flat'
  52. const switchTooltip =
  53. view === 'pdf' ? t('switch_to_editor') : t('switch_to_pdf')
  54. const switchIcon = view === 'pdf' ? 'edit' : 'picture_as_pdf'
  55. return (
  56. <nav className="ide-redesign-toolbar" aria-label={t('project_actions')}>
  57. <div className="ide-redesign-toolbar-menu">
  58. <ToolbarLogos cobranding={cobranding} />
  59. </div>
  60. <ToolbarProjectTitle />
  61. <div className="ide-redesign-toolbar-actions">
  62. <div className="ide-redesign-toolbar-button-container">
  63. <SplitTestBadge
  64. splitTestName="focus-mode"
  65. displayOnVariants={['enabled']}
  66. />
  67. </div>
  68. {showViewSwitcher && (
  69. <div className="ide-redesign-toolbar-button-container">
  70. <OLTooltip
  71. id="tooltip-switch-view"
  72. description={switchTooltip}
  73. overlayProps={{ delay: 0, placement: 'bottom' }}
  74. >
  75. <OLIconButton
  76. icon={switchIcon}
  77. className="ide-redesign-toolbar-button-subdued ide-redesign-toolbar-button-icon"
  78. onClick={handleSwitchView}
  79. accessibilityLabel={switchTooltip}
  80. />
  81. </OLTooltip>
  82. </div>
  83. )}
  84. <ChangeLayoutButton />
  85. <div className="ide-redesign-toolbar-button-container">
  86. <OLTooltip
  87. id="tooltip-exit-focus-mode"
  88. description={t('exit_focus_mode')}
  89. overlayProps={{ delay: 0, placement: 'bottom' }}
  90. >
  91. <OLIconButton
  92. icon="close_fullscreen"
  93. className="ide-redesign-toolbar-button-subdued ide-redesign-toolbar-button-icon"
  94. onClick={handleExitFocusMode}
  95. accessibilityLabel={t('exit_focus_mode')}
  96. />
  97. </OLTooltip>
  98. </div>
  99. </div>
  100. </nav>
  101. )
  102. }
  103. if (view === 'history') {
  104. return (
  105. <nav className="ide-redesign-toolbar" aria-label={t('project_actions')}>
  106. <div className="d-flex align-items-center">
  107. <BackToEditorButton onClick={handleBackToEditorClick} />
  108. </div>
  109. <ToolbarProjectTitle />
  110. <div /> {/* Empty div used for spacing */}
  111. </nav>
  112. )
  113. }
  114. return (
  115. <nav className="ide-redesign-toolbar" aria-label={t('project_actions')}>
  116. <div className="ide-redesign-toolbar-menu">
  117. <ToolbarLogos cobranding={cobranding} />
  118. <ToolbarMenuBar />
  119. {showUpgradePrompt && upgradeButtonRelocation && <UpgradeButton />}
  120. </div>
  121. <ToolbarProjectTitle />
  122. <div className="ide-redesign-toolbar-actions">
  123. <OnlineUsers />
  124. {!isRestrictedTokenMember && <ShowHistoryButton />}
  125. <ChangeLayoutButton />
  126. {shouldDisplaySubmitButton && cobranding && (
  127. <SubmitProjectButton cobranding={cobranding} />
  128. )}
  129. <ShareProjectButton />
  130. {showUpgradePrompt && !upgradeButtonRelocation && <UpgradeButton />}
  131. </div>
  132. </nav>
  133. )
  134. }