mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 09:09:36 +02:00
[web] Tear down sidebar-navigation-ui-update, Update project-list look in SP/CE (#24920)
* Remove hacks that conditionally hid `ds-nav` survey * Remove `getAssignment` of `sidebar-navigation-ui-update` * Remove `hasDsNav`: make it true everywhere * Remove dead code * Update Footer so thin footer is shown in SP/CE * Run `web$ make cleanup_unused_locales` & `bin/run web npm run extract-translations` * [server-pro] fix learn wiki tests following DS navigation changes * [server-pro] tests: remove logout action before switching session * [server-pro] tests: fix logout test * [server-pro] tests: use new css class for sidebar on project dashboard * Revert "should add a documentation entry to the nav bar" test change --------- Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com> GitOrigin-RevId: 93eb7a1b03bb4e54ad1770150d83778b8f7f6727
This commit is contained in:
@@ -9,7 +9,7 @@ describe('Accounts', function () {
|
||||
it('can log in and out', function () {
|
||||
login('user@example.com')
|
||||
cy.visit('/project')
|
||||
cy.findByText('Account').click()
|
||||
cy.findByRole('menuitem', { name: 'Account' }).click()
|
||||
cy.findByText('Log Out').click()
|
||||
cy.url().should('include', '/login')
|
||||
cy.visit('/project')
|
||||
|
||||
@@ -293,7 +293,7 @@ describe('admin panel', function () {
|
||||
cy.findByText(deletedProjectName).should('not.exist')
|
||||
|
||||
cy.log('navigate to thrashed projects and delete the project')
|
||||
cy.get('.project-list-sidebar-react').within(() => {
|
||||
cy.get('.project-list-sidebar-scroll').within(() => {
|
||||
cy.findByText('Trashed Projects').click()
|
||||
})
|
||||
findProjectRow(deletedProjectName).within(() =>
|
||||
@@ -318,7 +318,7 @@ describe('admin panel', function () {
|
||||
cy.log('login as the user and verify the project is restored')
|
||||
login(user1)
|
||||
cy.visit('/project')
|
||||
cy.get('.project-list-sidebar-react').within(() => {
|
||||
cy.get('.project-list-sidebar-scroll').within(() => {
|
||||
cy.findByText('Trashed Projects').click()
|
||||
})
|
||||
cy.findByText(`${deletedProjectName} (Restored)`)
|
||||
|
||||
@@ -102,10 +102,6 @@ describe('Project creation and compilation', function () {
|
||||
cy.findByText('Invite not yet accepted.')
|
||||
})
|
||||
|
||||
cy.visit('/project')
|
||||
cy.findByText('Account').click()
|
||||
cy.findByText('Log Out').click()
|
||||
|
||||
login('collaborator@example.com')
|
||||
openProjectViaInviteNotification(targetProjectName)
|
||||
cy.get('@targetProjectId').then(targetProjectId => {
|
||||
|
||||
@@ -96,12 +96,12 @@ describe('Templates', () => {
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => cy.get('input[type="checkbox"]').first().check())
|
||||
cy.get('.project-list-sidebar-react').within(() => {
|
||||
cy.get('.project-list-sidebar-scroll').within(() => {
|
||||
cy.findAllByText('New Tag').first().click()
|
||||
})
|
||||
cy.focused().type(tagName)
|
||||
cy.findByText('Create').click()
|
||||
cy.get('.project-list-sidebar-react').within(() => {
|
||||
cy.get('.project-list-sidebar-scroll').within(() => {
|
||||
cy.findByText(tagName)
|
||||
.parent()
|
||||
.within(() => cy.get('.name').should('have.text', `${tagName} (1)`))
|
||||
|
||||
@@ -411,15 +411,6 @@ async function projectListPage(req, res, next) {
|
||||
logger.error({ err: error }, 'Failed to get individual subscription')
|
||||
}
|
||||
|
||||
// Get the user's assignment for the DS unified nav split test, which
|
||||
// populates splitTestVariants with a value for the split test name and allows
|
||||
// Pug to send it to the browser
|
||||
await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'sidebar-navigation-ui-update'
|
||||
)
|
||||
|
||||
// Get the user's assignment for the papers notification banner split test,
|
||||
// which populates splitTestVariants with a value for the split test name and
|
||||
// allows Pug to send it to the browser
|
||||
|
||||
@@ -1127,7 +1127,6 @@
|
||||
"optional": "",
|
||||
"or": "",
|
||||
"organization_name": "",
|
||||
"organize_projects": "",
|
||||
"organize_tags": "",
|
||||
"other": "",
|
||||
"other_causes_of_compile_timeouts": "",
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import { useProjectListContext } from '../context/project-list-context'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import CurrentPlanWidget from './current-plan-widget/current-plan-widget'
|
||||
import NewProjectButton from './new-project-button'
|
||||
import ProjectListTable from './table/project-list-table'
|
||||
import SurveyWidget from './survey-widget'
|
||||
import UserNotifications from './notifications/user-notifications'
|
||||
import SearchForm from './search-form'
|
||||
import ProjectsDropdown from './dropdown/projects-dropdown'
|
||||
import SortByDropdown from './dropdown/sort-by-dropdown'
|
||||
import ProjectTools from './table/project-tools/project-tools'
|
||||
import ProjectListTitle from './title/project-list-title'
|
||||
import Sidebar from './sidebar/sidebar'
|
||||
import LoadMore from './load-more'
|
||||
import OLCol from '@/features/ui/components/ol/ol-col'
|
||||
import OLRow from '@/features/ui/components/ol/ol-row'
|
||||
import { TableContainer } from '@/features/ui/components/bootstrap-5/table'
|
||||
import DashApiError from '@/features/project-list/components/dash-api-error'
|
||||
|
||||
export default function ProjectListDefault() {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
error,
|
||||
searchText,
|
||||
setSearchText,
|
||||
selectedProjects,
|
||||
filter,
|
||||
tags,
|
||||
selectedTagId,
|
||||
} = useProjectListContext()
|
||||
|
||||
const selectedTag = tags.find(tag => tag._id === selectedTagId)
|
||||
|
||||
const tableTopArea = (
|
||||
<div className="pt-2 pb-3 d-md-none d-flex gap-2">
|
||||
<NewProjectButton
|
||||
id="new-project-button-projects-table"
|
||||
showAddAffiliationWidget
|
||||
/>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
className="overflow-hidden flex-grow-1"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sidebar />
|
||||
<div className="project-list-main-react">
|
||||
{error ? <DashApiError /> : ''}
|
||||
<OLRow>
|
||||
<OLCol>
|
||||
<UserNotifications />
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<div className="project-list-header-row">
|
||||
<ProjectListTitle
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
selectedTagId={selectedTagId}
|
||||
className="text-truncate d-none d-md-block"
|
||||
/>
|
||||
<div className="project-tools">
|
||||
<div className="d-none d-md-block">
|
||||
{selectedProjects.length === 0 ? (
|
||||
<CurrentPlanWidget />
|
||||
) : (
|
||||
<ProjectTools />
|
||||
)}
|
||||
</div>
|
||||
<div className="d-md-none">
|
||||
<CurrentPlanWidget />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<OLRow className="d-none d-md-block">
|
||||
<OLCol lg={7}>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
/>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<div className="project-list-sidebar-survey-wrapper d-md-none">
|
||||
<SurveyWidget />
|
||||
</div>
|
||||
<div className="mt-1 d-md-none">
|
||||
<div
|
||||
role="toolbar"
|
||||
className="projects-toolbar"
|
||||
aria-label={t('projects')}
|
||||
>
|
||||
<ProjectsDropdown />
|
||||
<SortByDropdown />
|
||||
</div>
|
||||
</div>
|
||||
<OLRow className="row-spaced">
|
||||
<OLCol>
|
||||
<TableContainer bordered>
|
||||
{tableTopArea}
|
||||
<ProjectListTable />
|
||||
</TableContainer>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<OLRow className="row-spaced">
|
||||
<OLCol>
|
||||
<LoadMore />
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -16,13 +16,14 @@ import { TableContainer } from '@/features/ui/components/bootstrap-5/table'
|
||||
import DashApiError from '@/features/project-list/components/dash-api-error'
|
||||
import getMeta from '@/utils/meta'
|
||||
import DefaultNavbar from '@/features/ui/components/bootstrap-5/navbar/default-navbar'
|
||||
import FatFooter from '@/features/ui/components/bootstrap-5/footer/fat-footer'
|
||||
import Footer from '@/features/ui/components/bootstrap-5/footer/footer'
|
||||
import SidebarDsNav from '@/features/project-list/components/sidebar/sidebar-ds-nav'
|
||||
import SystemMessages from '@/shared/components/system-messages'
|
||||
import overleafLogo from '@/shared/svgs/overleaf-a-ds-solution-mallard.svg'
|
||||
|
||||
export function ProjectListDsNav() {
|
||||
const navbarProps = getMeta('ol-navbar')
|
||||
const footerProps = getMeta('ol-footer')
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
error,
|
||||
@@ -117,7 +118,7 @@ export function ProjectListDsNav() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FatFooter />
|
||||
<Footer {...footerProps} />
|
||||
</div>
|
||||
<div>
|
||||
<SystemMessages />
|
||||
|
||||
@@ -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,
|
||||
hasDsNav,
|
||||
} 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()
|
||||
@@ -87,15 +83,7 @@ function ProjectListPageContent() {
|
||||
<LoadingBranded loadProgress={loadProgress} label={t('loading')} />
|
||||
)
|
||||
|
||||
if (hasDsNav()) {
|
||||
return loadingComponent
|
||||
} else {
|
||||
return (
|
||||
<DefaultNavbarAndFooter>
|
||||
<div className="loading-container">{loadingComponent}</div>
|
||||
</DefaultNavbarAndFooter>
|
||||
)
|
||||
}
|
||||
return loadingComponent
|
||||
}
|
||||
|
||||
if (totalProjectsCount === 0) {
|
||||
@@ -104,19 +92,12 @@ function ProjectListPageContent() {
|
||||
<WelcomePageContent />
|
||||
</DefaultPageContentWrapper>
|
||||
)
|
||||
} else if (hasDsNav()) {
|
||||
return (
|
||||
<DsNavStyleProvider>
|
||||
<ProjectListDsNav />
|
||||
</DsNavStyleProvider>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<DefaultPageContentWrapper>
|
||||
<ProjectListDefault />
|
||||
</DefaultPageContentWrapper>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<DsNavStyleProvider>
|
||||
<ProjectListDsNav />
|
||||
</DsNavStyleProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default withErrorBoundary(ProjectListRoot, GenericErrorBoundaryFallback)
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
} from '../../context/project-list-context'
|
||||
import TagsList from './tags-list'
|
||||
import ProjectsFilterMenu from '../projects-filter-menu'
|
||||
import { hasDsNav } from '@/features/project-list/components/use-is-ds-nav'
|
||||
|
||||
type SidebarFilterProps = {
|
||||
filter: Filter
|
||||
@@ -38,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>
|
||||
)
|
||||
|
||||
@@ -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 { hasDsNav } from '@/features/project-list/components/use-is-ds-nav'
|
||||
|
||||
export default function TagsList() {
|
||||
const { t } = useTranslation()
|
||||
@@ -42,16 +40,11 @@ export default function TagsList() {
|
||||
aria-hidden="true"
|
||||
data-testid="organize-projects"
|
||||
>
|
||||
{hasDsNav() ? t('organize_tags') : t('organize_projects')}
|
||||
{t('organize_tags')}
|
||||
</li>
|
||||
<li className="tag">
|
||||
<button type="button" className="tag-name" onClick={openCreateTagModal}>
|
||||
{hasDsNav() ? (
|
||||
<Plus weight="bold" />
|
||||
) : (
|
||||
<MaterialIcon type="add" className="tag-list-icon" />
|
||||
)}
|
||||
|
||||
<Plus weight="bold" />
|
||||
<span className="name">{t('new_tag')}</span>
|
||||
</button>
|
||||
</li>
|
||||
@@ -73,11 +66,7 @@ export default function TagsList() {
|
||||
color: getTagColor(tag),
|
||||
}}
|
||||
>
|
||||
{hasDsNav() ? (
|
||||
<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}{' '}
|
||||
@@ -93,7 +82,7 @@ export default function TagsList() {
|
||||
id={`${tag._id}-dropdown-toggle`}
|
||||
data-testid="tag-dropdown-toggle"
|
||||
>
|
||||
{hasDsNav() && <DotsThreeVertical weight="bold" />}
|
||||
<DotsThreeVertical weight="bold" />
|
||||
</DropdownToggle>
|
||||
<DropdownMenu className="dropdown-menu-sm-width">
|
||||
<DropdownItem
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
||||
import getMeta from '../../../utils/meta'
|
||||
import { useCallback } from 'react'
|
||||
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 { useHideDsSurvey } from '@/features/project-list/components/use-is-ds-nav'
|
||||
|
||||
export function SurveyWidgetDsNav() {
|
||||
const { t } = useTranslation()
|
||||
@@ -14,7 +12,6 @@ export function SurveyWidgetDsNav() {
|
||||
`dismissed-${survey?.name}`,
|
||||
false
|
||||
)
|
||||
const hideDsSurvey = useHideDsSurvey()
|
||||
|
||||
const dismissSurvey = useCallback(() => {
|
||||
setDismissedSurvey(true)
|
||||
@@ -24,14 +21,8 @@ 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 (hideDsSurvey && survey?.name === 'ds-nav') {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classnames('user-notifications', `survey-${survey.name}`)}>
|
||||
<div className="user-notifications">
|
||||
<div className="notification-entry">
|
||||
<div role="alert" className="survey-notification">
|
||||
<div className="notification-body">
|
||||
|
||||
@@ -18,12 +18,6 @@ export default function SurveyWidget() {
|
||||
return null
|
||||
}
|
||||
|
||||
// Short-term hard-coded special case: hide the "DS nav" survey for users on
|
||||
// the default variant
|
||||
if (survey?.name === 'ds-nav') {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="user-notifications">
|
||||
<div className="notification-entry">
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
import { createContext, type FC, type ReactNode, useContext } from 'react'
|
||||
import { useSplitTestContext } from '@/shared/context/split-test-context'
|
||||
import getMeta from '@/utils/meta'
|
||||
|
||||
export const hasDsNav = () => getMeta('ol-ExposedSettings').isOverleaf
|
||||
|
||||
/**
|
||||
* This hook returns whether the user has the split-test assignment 'sidebar-navigation-ui-update'
|
||||
*/
|
||||
export const useHideDsSurvey = () => {
|
||||
const { splitTestVariants } = useSplitTestContext()
|
||||
return splitTestVariants['sidebar-navigation-ui-update'] === 'active'
|
||||
}
|
||||
|
||||
/**
|
||||
* This context wraps elements that should be styled according to the sidebar-navigation-ui-update redesign
|
||||
|
||||
@@ -1490,7 +1490,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",
|
||||
|
||||
Reference in New Issue
Block a user