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

[web] Show DS Navigation for all users regardless of feature flag (#23767)

* Remove uses of `useIsDsNav`

* Remove `sidebar-navigation-ui-update` as true from analytics events

* Hide "ds-nav" survey for users who have the feature flag

* `make cleanup_unused_locales` & `bin/run web npm run extract-translations`

* Update frontend tests

GitOrigin-RevId: 83f429d81ca1b46e9eab4fc667a921026a85912f
Antoine Clausse 1 год назад
Родитель
Сommit
7b2f51aad5

+ 0 - 1
services/web/frontend/extracted-translations.json

@@ -1099,7 +1099,6 @@
   "optional": "",
   "or": "",
   "organization_name": "",
-  "organize_projects": "",
   "organize_tags": "",
   "other": "",
   "other_causes_of_compile_timeouts": "",

+ 2 - 8
services/web/frontend/js/features/project-list/components/project-list-events.ts

@@ -1,5 +1,4 @@
 import { useCallback } from 'react'
-import { useSplitTestContext } from '@/shared/context/split-test-context'
 import { sendMB } from '@/infrastructure/event-tracking'
 
 export type ExtraSegmentations = {
@@ -39,16 +38,11 @@ export type ExtraSegmentations = {
 }
 
 export const useSendProjectListMB = () => {
-  const { splitTestVariants } = useSplitTestContext()
-  const hasDsNav = splitTestVariants['sidebar-navigation-ui-update'] as
-    | 'default'
-    | 'active'
   return useCallback(
     <T extends keyof ExtraSegmentations>(
       event: T,
       payload: ExtraSegmentations[T]
-    ) =>
-      sendMB(event, { ...payload, 'sidebar-navigation-ui-update': hasDsNav }),
-    [hasDsNav]
+    ) => sendMB(event, payload),
+    []
   )
 }

+ 3 - 27
services/web/frontend/js/features/project-list/components/project-list-root.tsx

@@ -16,12 +16,8 @@ import getMeta from '@/utils/meta'
 import DefaultNavbar from '@/features/ui/components/bootstrap-5/navbar/default-navbar'
 import Footer from '@/features/ui/components/bootstrap-5/footer/footer'
 import WelcomePageContent from '@/features/project-list/components/welcome-page-content'
-import ProjectListDefault from '@/features/project-list/components/project-list-default'
 import { ProjectListDsNav } from '@/features/project-list/components/project-list-ds-nav'
-import {
-  DsNavStyleProvider,
-  useIsDsNav,
-} from '@/features/project-list/components/use-is-ds-nav'
+import { DsNavStyleProvider } from '@/features/project-list/components/use-is-ds-nav'
 
 function ProjectListRoot() {
   const { isReady } = useWaitForI18n()
@@ -82,22 +78,8 @@ function ProjectListPageContent() {
 
   const { t } = useTranslation()
 
-  const hasDsNav = useIsDsNav()
-
   if (isLoading) {
-    const loadingComponent = (
-      <LoadingBranded loadProgress={loadProgress} label={t('loading')} />
-    )
-
-    if (hasDsNav) {
-      return loadingComponent
-    } else {
-      return (
-        <DefaultNavbarAndFooter>
-          <div className="loading-container">{loadingComponent}</div>
-        </DefaultNavbarAndFooter>
-      )
-    }
+    return <LoadingBranded loadProgress={loadProgress} label={t('loading')} />
   }
 
   if (totalProjectsCount === 0) {
@@ -106,18 +88,12 @@ function ProjectListPageContent() {
         <WelcomePageContent />
       </DefaultPageContentWrapper>
     )
-  } else if (hasDsNav) {
+  } else {
     return (
       <DsNavStyleProvider>
         <ProjectListDsNav />
       </DsNavStyleProvider>
     )
-  } else {
-    return (
-      <DefaultPageContentWrapper>
-        <ProjectListDefault />
-      </DefaultPageContentWrapper>
-    )
   }
 }
 

+ 3 - 7
services/web/frontend/js/features/project-list/components/sidebar/sidebar-filters.tsx

@@ -5,7 +5,6 @@ import {
 } from '../../context/project-list-context'
 import TagsList from './tags-list'
 import ProjectsFilterMenu from '../projects-filter-menu'
-import { useIsDsNav } from '@/features/project-list/components/use-is-ds-nav'
 
 type SidebarFilterProps = {
   filter: Filter
@@ -30,7 +29,6 @@ export function SidebarFilter({ filter, text }: SidebarFilterProps) {
 
 export default function SidebarFilters() {
   const { t } = useTranslation()
-  const hasDsNav = useIsDsNav()
 
   return (
     <ul className="list-unstyled project-list-filters">
@@ -39,11 +37,9 @@ export default function SidebarFilters() {
       <SidebarFilter filter="shared" text={t('shared_with_you')} />
       <SidebarFilter filter="archived" text={t('archived_projects')} />
       <SidebarFilter filter="trashed" text={t('trashed_projects')} />
-      {hasDsNav && (
-        <li role="none">
-          <hr />
-        </li>
-      )}
+      <li role="none">
+        <hr />
+      </li>
       <TagsList />
     </ul>
   )

+ 4 - 15
services/web/frontend/js/features/project-list/components/sidebar/tags-list.tsx

@@ -1,7 +1,6 @@
 import { sortBy } from 'lodash'
 import { useTranslation } from 'react-i18next'
 import { DotsThreeVertical, Plus, TagSimple } from '@phosphor-icons/react'
-import MaterialIcon from '../../../../shared/components/material-icon'
 import {
   UNCATEGORIZED_KEY,
   useProjectListContext,
@@ -14,7 +13,6 @@ import {
   DropdownMenu,
   DropdownToggle,
 } from '@/features/ui/components/bootstrap-5/dropdown-menu'
-import { useIsDsNav } from '@/features/project-list/components/use-is-ds-nav'
 
 export default function TagsList() {
   const { t } = useTranslation()
@@ -35,7 +33,6 @@ export default function TagsList() {
     DeleteTagModal,
   } = useTag()
 
-  const isDsNav = useIsDsNav()
   return (
     <>
       <li
@@ -43,15 +40,11 @@ export default function TagsList() {
         aria-hidden="true"
         data-testid="organize-projects"
       >
-        {isDsNav ? t('organize_tags') : t('organize_projects')}
+        {t('organize_tags')}
       </li>
       <li className="tag">
         <button type="button" className="tag-name" onClick={openCreateTagModal}>
-          {isDsNav ? (
-            <Plus weight="bold" />
-          ) : (
-            <MaterialIcon type="add" className="tag-list-icon" />
-          )}
+          <Plus weight="bold" />
 
           <span className="name">{t('new_tag')}</span>
         </button>
@@ -74,11 +67,7 @@ export default function TagsList() {
                   color: getTagColor(tag),
                 }}
               >
-                {isDsNav ? (
-                  <TagSimple weight="fill" className="tag-list-icon" />
-                ) : (
-                  <MaterialIcon type="label" className="tag-list-icon" />
-                )}
+                <TagSimple weight="fill" className="tag-list-icon" />
               </span>
               <span className="name">
                 {tag.name}{' '}
@@ -94,7 +83,7 @@ export default function TagsList() {
                 id={`${tag._id}-dropdown-toggle`}
                 data-testid="tag-dropdown-toggle"
               >
-                {isDsNav && <DotsThreeVertical weight="bold" />}
+                <DotsThreeVertical weight="bold" />
               </DropdownToggle>
               <DropdownMenu className="dropdown-menu-sm-width">
                 <DropdownItem

+ 8 - 0
services/web/frontend/js/features/project-list/components/survey-widget-ds-nav.tsx

@@ -5,6 +5,7 @@ import classnames from 'classnames'
 import OLButton from '@/features/ui/components/ol/ol-button'
 import { useTranslation } from 'react-i18next'
 import { X } from '@phosphor-icons/react'
+import { useIsDsNav } from '@/features/project-list/components/use-is-ds-nav'
 
 export function SurveyWidgetDsNav() {
   const { t } = useTranslation()
@@ -13,6 +14,7 @@ export function SurveyWidgetDsNav() {
     `dismissed-${survey?.name}`,
     false
   )
+  const hasDsNav = useIsDsNav()
 
   const dismissSurvey = useCallback(() => {
     setDismissedSurvey(true)
@@ -22,6 +24,12 @@ export function SurveyWidgetDsNav() {
     return null
   }
 
+  // Hide the survey for users who have sidebar-navigation-ui-update:
+  // They've had it for months. We don't need their feedback anymore
+  if (hasDsNav && survey?.name === 'ds-nav') {
+    return null
+  }
+
   return (
     <div className={classnames('user-notifications', `survey-${survey.name}`)}>
       <div className="notification-entry">

+ 0 - 1
services/web/locales/en.json

@@ -1461,7 +1461,6 @@
   "organization_name": "Organization name",
   "organization_or_company_name": "Organization or company name",
   "organization_or_company_type": "Organization or company type",
-  "organize_projects": "Organize Projects",
   "organize_tags": "Organize Tags",
   "original_price": "Original price",
   "other": "Other",

+ 1 - 1
services/web/test/frontend/features/project-list/components/sidebar/tags-list.test.tsx

@@ -42,7 +42,7 @@ describe('<TagsList />', function () {
 
   it('displays the tags list', function () {
     const header = screen.getByTestId('organize-projects')
-    expect(header.textContent).to.equal('Organize Projects')
+    expect(header.textContent).to.equal('Organize Tags')
 
     screen.getByRole('button', {
       name: 'New Tag',

+ 20 - 6
services/web/test/frontend/features/project-list/components/survey-widget.test.tsx

@@ -1,8 +1,9 @@
 import { expect } from 'chai'
 import { fireEvent, render, screen } from '@testing-library/react'
-import SurveyWidget from '../../../../../frontend/js/features/project-list/components/survey-widget'
+import { SurveyWidgetDsNav } from '../../../../../frontend/js/features/project-list/components/survey-widget-ds-nav'
+import { SplitTestProvider } from '@/shared/context/split-test-context'
 
-describe('<SurveyWidget />', function () {
+describe('<SurveyWidgetDsNav />', function () {
   beforeEach(function () {
     this.name = 'my-survey'
     this.preText = 'To help shape the future of Overleaf'
@@ -21,7 +22,11 @@ describe('<SurveyWidget />', function () {
         url: this.url,
       })
 
-      render(<SurveyWidget />)
+      render(
+        <SplitTestProvider>
+          <SurveyWidgetDsNav />
+        </SplitTestProvider>
+      )
     })
 
     it('shows text and link', function () {
@@ -29,9 +34,10 @@ describe('<SurveyWidget />', function () {
       expect(dismissed).to.equal(null)
 
       screen.getByText(this.preText)
+      screen.getByText(this.linkText)
 
       const link = screen.getByRole('link', {
-        name: this.linkText,
+        name: 'Take survey',
       }) as HTMLAnchorElement
       expect(link.href).to.equal(this.url)
     })
@@ -63,7 +69,11 @@ describe('<SurveyWidget />', function () {
       })
       localStorage.setItem('dismissed-my-survey', 'true')
 
-      render(<SurveyWidget />)
+      render(
+        <SplitTestProvider>
+          <SurveyWidgetDsNav />
+        </SplitTestProvider>
+      )
     })
 
     it('nothing is displayed', function () {
@@ -77,7 +87,11 @@ describe('<SurveyWidget />', function () {
 
   describe('survey widget is not shown when no survey is configured', function () {
     beforeEach(function () {
-      render(<SurveyWidget />)
+      render(
+        <SplitTestProvider>
+          <SurveyWidgetDsNav />
+        </SplitTestProvider>
+      )
     })
 
     it('nothing is displayed', function () {

+ 3 - 1
services/web/test/frontend/features/project-list/components/table/project-tools/project-tools-rename.test.tsx

@@ -63,12 +63,14 @@ describe('<ProjectTools />', function () {
       projects,
       totalSize: 100,
     })
-
     window.metaAttributesCache.set('ol-footer', {
       showThinFooter: false,
       translatedLanguages: { en: 'English' },
       subdomainLang: { en: { lngCode: 'en', url: 'overleaf.com' } },
     })
+    window.metaAttributesCache.set('ol-navbar', {
+      items: [],
+    })
     fetchMock.get('/system/messages', [])
   })