mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #36649 from overleaf/dp-cleanup-library-feature-flag
Remove the overleaf-library feature flag GitOrigin-RevId: ebeabd43c9e44dbc2344b4e8e7e5b9095fcc86e0
This commit is contained in:
@@ -639,7 +639,6 @@ const _ProjectController = {
|
||||
'export-markdown',
|
||||
'export-html',
|
||||
'command-palette',
|
||||
'overleaf-library',
|
||||
'focus-mode',
|
||||
'markdown-visual',
|
||||
'ai-disabled-collaborators',
|
||||
|
||||
@@ -574,7 +574,6 @@ async function projectListPage(req, res, next) {
|
||||
const splitTests = [
|
||||
// Split tests that will be made available to the frontend
|
||||
'import-docx',
|
||||
'overleaf-library',
|
||||
'import-markdown',
|
||||
'themed-modals',
|
||||
'shared-workspace',
|
||||
|
||||
@@ -1031,6 +1031,7 @@ module.exports = {
|
||||
createFileModes: [],
|
||||
devToolbar: [],
|
||||
dsNavLibraryLink: [],
|
||||
trashPageTabs: [],
|
||||
adminUserLibrary: [],
|
||||
gitBridge: [],
|
||||
publishModalDropdownButton: [],
|
||||
|
||||
@@ -741,7 +741,6 @@
|
||||
"file_tree": "",
|
||||
"files_cannot_include_invalid_characters": "",
|
||||
"files_selected": "",
|
||||
"filter_projects": "",
|
||||
"find": "",
|
||||
"find_out_how_to_get_the_most_out_of_your_new_subscription": "",
|
||||
"find_out_more": "",
|
||||
@@ -1846,7 +1845,6 @@
|
||||
"search_match_case": "",
|
||||
"search_members": "",
|
||||
"search_next": "",
|
||||
"search_only_the_bib_files_in_your_project_only_by_citekeys": "",
|
||||
"search_previous": "",
|
||||
"search_project": "",
|
||||
"search_projects": "",
|
||||
|
||||
+2
-4
@@ -4,12 +4,10 @@ import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { FreePlanSubscription } from '../../../../../../types/project/dashboard/subscription'
|
||||
import * as eventTracking from '../../../../infrastructure/event-tracking'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
|
||||
type FreePlanProps = Pick<FreePlanSubscription, 'featuresPageURL'>
|
||||
|
||||
function FreePlan({ featuresPageURL }: FreePlanProps) {
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
const { t } = useTranslation()
|
||||
const currentPlanLabel = (
|
||||
<Trans
|
||||
@@ -45,8 +43,8 @@ function FreePlan({ featuresPageURL }: FreePlanProps) {
|
||||
</OLTooltip>{' '}
|
||||
<span className="d-none d-md-inline-block">
|
||||
<OLButton
|
||||
variant={isLibraryEnabled ? 'premium' : 'primary'}
|
||||
size={isLibraryEnabled ? 'sm' : undefined}
|
||||
variant="premium"
|
||||
size="sm"
|
||||
href="/user/subscription/plans"
|
||||
onClick={handleClick}
|
||||
>
|
||||
|
||||
+22
-56
@@ -9,13 +9,11 @@ import {
|
||||
import {
|
||||
OLDropdown,
|
||||
OLDropdownDivider,
|
||||
OLDropdownHeader,
|
||||
OLDropdownItem,
|
||||
OLDropdownMenu,
|
||||
OLDropdownToggle,
|
||||
} from '@/shared/components/ol/ol-dropdown-menu'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import ProjectsFilterMenu from '../projects-filter-menu'
|
||||
import TagsList from '../tags-list'
|
||||
import { ActivePage } from '../../util/navigation-state'
|
||||
@@ -78,7 +76,6 @@ function NavigationDropdown({
|
||||
)
|
||||
const [view, setView] = useState<'top' | 'tags' | 'trash'>('top')
|
||||
const { filter, selectedTagId, tags } = useProjectListContext()
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
const projectsTrashActive =
|
||||
activePage === 'projects' &&
|
||||
selectedTagId === undefined &&
|
||||
@@ -126,7 +123,7 @@ function NavigationDropdown({
|
||||
filter="all"
|
||||
text={t('all_projects')}
|
||||
activePage={activePage}
|
||||
leadingIcon={isLibraryEnabled && <Folder size={20} />}
|
||||
leadingIcon={<Folder size={20} />}
|
||||
/>
|
||||
</li>
|
||||
<li role="none">
|
||||
@@ -134,7 +131,7 @@ function NavigationDropdown({
|
||||
filter="owned"
|
||||
text={t('your_projects')}
|
||||
activePage={activePage}
|
||||
leadingIcon={isLibraryEnabled && <OLDropdownItem.EmptyLeadingIcon />}
|
||||
leadingIcon={<OLDropdownItem.EmptyLeadingIcon />}
|
||||
/>
|
||||
</li>
|
||||
<li role="none">
|
||||
@@ -142,7 +139,7 @@ function NavigationDropdown({
|
||||
filter="shared"
|
||||
text={t('shared_with_you')}
|
||||
activePage={activePage}
|
||||
leadingIcon={isLibraryEnabled && <OLDropdownItem.EmptyLeadingIcon />}
|
||||
leadingIcon={<OLDropdownItem.EmptyLeadingIcon />}
|
||||
/>
|
||||
</li>
|
||||
<li role="none">
|
||||
@@ -150,71 +147,40 @@ function NavigationDropdown({
|
||||
filter="archived"
|
||||
text={t('archived_projects')}
|
||||
activePage={activePage}
|
||||
leadingIcon={isLibraryEnabled && <OLDropdownItem.EmptyLeadingIcon />}
|
||||
leadingIcon={<OLDropdownItem.EmptyLeadingIcon />}
|
||||
/>
|
||||
</li>
|
||||
{!isLibraryEnabled && (
|
||||
<li role="none">
|
||||
<Item
|
||||
filter="trashed"
|
||||
text={t('trashed_projects')}
|
||||
activePage={activePage}
|
||||
/>
|
||||
</li>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
const submenuItems = (
|
||||
<>
|
||||
{filterItems}
|
||||
<OLDropdownHeader className="text-uppercase">
|
||||
{t('tags')}:
|
||||
</OLDropdownHeader>
|
||||
<TagsList />
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<OLDropdown
|
||||
onToggle={
|
||||
isLibraryEnabled
|
||||
? show => {
|
||||
if (show) {
|
||||
if (selectedTagId !== undefined) {
|
||||
setView('tags')
|
||||
} else if (isTrashActive) {
|
||||
setView('trash')
|
||||
} else {
|
||||
setView('top')
|
||||
}
|
||||
} else {
|
||||
setView('top')
|
||||
}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onToggle={show => {
|
||||
if (show) {
|
||||
if (selectedTagId !== undefined) {
|
||||
setView('tags')
|
||||
} else if (isTrashActive) {
|
||||
setView('trash')
|
||||
} else {
|
||||
setView('top')
|
||||
}
|
||||
} else {
|
||||
setView('top')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<OLDropdownToggle
|
||||
id="projects-types-dropdown-toggle-btn"
|
||||
className="ps-0 mb-0 btn-transparent h3"
|
||||
size="lg"
|
||||
aria-label={
|
||||
isLibraryEnabled ? t('navigation_menu') : t('filter_projects')
|
||||
}
|
||||
aria-label={t('navigation_menu')}
|
||||
>
|
||||
<span className="text-truncate" aria-hidden>
|
||||
{title}
|
||||
</span>
|
||||
</OLDropdownToggle>
|
||||
<OLDropdownMenu
|
||||
flip={false}
|
||||
className={
|
||||
isLibraryEnabled ? 'projects-dropdown-menu-library' : undefined
|
||||
}
|
||||
>
|
||||
{!isLibraryEnabled && submenuItems}
|
||||
{isLibraryEnabled && view === 'top' && (
|
||||
<OLDropdownMenu flip={false} className="projects-dropdown-menu-library">
|
||||
{view === 'top' && (
|
||||
<>
|
||||
{filterItems}
|
||||
<li role="none">
|
||||
@@ -257,7 +223,7 @@ function NavigationDropdown({
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
{isLibraryEnabled && view === 'tags' && (
|
||||
{view === 'tags' && (
|
||||
<>
|
||||
<li role="none">
|
||||
<OLDropdownItem
|
||||
@@ -276,7 +242,7 @@ function NavigationDropdown({
|
||||
<TagsList />
|
||||
</>
|
||||
)}
|
||||
{isLibraryEnabled && view === 'trash' && (
|
||||
{view === 'trash' && (
|
||||
<>
|
||||
<li role="none">
|
||||
<OLDropdownItem
|
||||
|
||||
@@ -22,7 +22,6 @@ import { useSendProjectListMB } from '@/features/project-list/components/project
|
||||
import type { PortalTemplate } from '../../../../../types/portal-template'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
import { useProjectListContext } from '@/features/project-list/context/project-list-context'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { NestableDropdownContextProvider } from '@/shared/context/nestable-dropdown-context'
|
||||
import { NestedMenuBarDropdown } from '@/shared/components/menu-bar/menu-bar-dropdown'
|
||||
|
||||
@@ -72,11 +71,9 @@ function NewProjectButton({
|
||||
useFeatureFlag('import-markdown') &&
|
||||
getMeta('ol-ExposedSettings').enablePandocConversions
|
||||
const { selectedTagId, tags } = useProjectListContext()
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
const initialTags =
|
||||
isLibraryEnabled && selectedTagId
|
||||
? tags.filter(tag => tag._id === selectedTagId)
|
||||
: []
|
||||
const initialTags = selectedTagId
|
||||
? tags.filter(tag => tag._id === selectedTagId)
|
||||
: []
|
||||
const sendTrackingEvent = useCallback(
|
||||
({
|
||||
dropdownMenu,
|
||||
|
||||
@@ -26,7 +26,6 @@ import overleafLogoDark from '@/shared/svgs/overleaf-a-ds-solution-mallard-dark.
|
||||
import CookieBanner from '@/shared/components/cookie-banner'
|
||||
import NoProjects from '@/features/project-list/components/no-projects'
|
||||
import { useActiveOverallTheme } from '@/shared/hooks/use-active-overall-theme'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
|
||||
export function ProjectListDsNav() {
|
||||
@@ -44,48 +43,28 @@ export function ProjectListDsNav() {
|
||||
currentFilterProjectsCount,
|
||||
} = useProjectListContext()
|
||||
const activeOverallTheme = useActiveOverallTheme()
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
const isSharedWorkspaceEnabled = useFeatureFlag('shared-workspace')
|
||||
|
||||
const selectedTag = tags.find(tag => tag._id === selectedTagId)
|
||||
const showTrashHeader = isLibraryEnabled && filter === 'trashed'
|
||||
const showTrashHeader = filter === 'trashed'
|
||||
const showNewProjectButton =
|
||||
!isLibraryEnabled ||
|
||||
(filter !== 'shared' && filter !== 'archived' && filter !== 'trashed')
|
||||
filter !== 'shared' && filter !== 'archived' && filter !== 'trashed'
|
||||
|
||||
const tableTopArea = (
|
||||
<div className="pt-2 pb-3 d-md-none d-flex gap-2">
|
||||
{isLibraryEnabled ? (
|
||||
<>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
className="overflow-hidden flex-grow-1"
|
||||
/>
|
||||
{showNewProjectButton && (
|
||||
<NewProjectButton
|
||||
id="new-project-button-projects-table"
|
||||
showAddAffiliationWidget
|
||||
align="end"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<NewProjectButton
|
||||
id="new-project-button-projects-table"
|
||||
showAddAffiliationWidget
|
||||
/>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
className="overflow-hidden flex-grow-1"
|
||||
/>
|
||||
</>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
className="overflow-hidden flex-grow-1"
|
||||
/>
|
||||
{showNewProjectButton && (
|
||||
<NewProjectButton
|
||||
id="new-project-button-projects-table"
|
||||
showAddAffiliationWidget
|
||||
align="end"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
@@ -93,7 +72,6 @@ export function ProjectListDsNav() {
|
||||
return (
|
||||
<div
|
||||
className={classNames('project-ds-nav-page', 'website-redesign', {
|
||||
'library-enabled': isLibraryEnabled,
|
||||
'ds-nav-hides-top-navbar': showTrashHeader,
|
||||
})}
|
||||
>
|
||||
@@ -159,7 +137,7 @@ export function ProjectListDsNav() {
|
||||
) : (
|
||||
<div className="project-ds-nav-project-list">
|
||||
<OLRow className="d-none d-md-flex align-items-center">
|
||||
<OLCol md={isLibraryEnabled ? 8 : undefined} lg={7}>
|
||||
<OLCol md={8} lg={7}>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
@@ -167,7 +145,7 @@ export function ProjectListDsNav() {
|
||||
selectedTag={selectedTag}
|
||||
/>
|
||||
</OLCol>
|
||||
{isLibraryEnabled && showNewProjectButton && (
|
||||
{showNewProjectButton && (
|
||||
<OLCol className="ms-auto" xs="auto">
|
||||
<NewProjectButton
|
||||
id="new-project-button-projects-table"
|
||||
|
||||
+20
-35
@@ -2,14 +2,12 @@ import { JSXElementConstructor } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import classnames from 'classnames'
|
||||
import { Trash } from '@phosphor-icons/react'
|
||||
import NewProjectButton from '../new-project-button'
|
||||
import SidebarFilters from './sidebar-filters'
|
||||
import AddAffiliation, { useAddAffiliation } from '../add-affiliation'
|
||||
import { usePersistedResize } from '@/shared/hooks/use-resize'
|
||||
import { useScrolled } from '@/features/project-list/components/sidebar/use-scroll'
|
||||
import { SurveyWidgetDsNav } from '@/features/project-list/components/survey-widget-ds-nav'
|
||||
import { SidebarLowerSection } from '@/shared/components/sidebar/sidebar-lower-section'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { DsNavOverleafLogo } from '@/shared/components/sidebar/ds-nav-overleaf-logo'
|
||||
import { useProjectListContext } from '@/features/project-list/context/project-list-context'
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
@@ -29,7 +27,6 @@ function SidebarDsNav({
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const { show: showAddAffiliationWidget } = useAddAffiliation()
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
const { filter, selectedTagId, selectFilter } = useProjectListContext()
|
||||
const isTrashActive =
|
||||
activePage === 'library'
|
||||
@@ -43,7 +40,7 @@ function SidebarDsNav({
|
||||
const { mousePos, getHandleProps, getTargetProps } = usePersistedResize({
|
||||
name: 'project-sidebar',
|
||||
})
|
||||
const { containerRef, scrolledUp, scrolledDown } = useScrolled()
|
||||
const { containerRef, scrolledUp } = useScrolled()
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -54,19 +51,11 @@ function SidebarDsNav({
|
||||
},
|
||||
})}
|
||||
>
|
||||
{isLibraryEnabled && (activePage === 'library' || isTrashActive) && (
|
||||
<DsNavOverleafLogo />
|
||||
)}
|
||||
{(activePage === 'library' || isTrashActive) && <DsNavOverleafLogo />}
|
||||
<nav
|
||||
className="flex-grow flex-shrink"
|
||||
aria-label={t('project_categories_tags')}
|
||||
>
|
||||
{!isLibraryEnabled && (
|
||||
<NewProjectButton
|
||||
id="new-project-button-sidebar"
|
||||
className={scrolledDown ? 'show-shadow' : undefined}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className="project-list-sidebar-scroll"
|
||||
ref={containerRef}
|
||||
@@ -84,29 +73,25 @@ function SidebarDsNav({
|
||||
)}
|
||||
>
|
||||
<SidebarLowerSection showThemeToggle>
|
||||
{isLibraryEnabled && (
|
||||
<>
|
||||
{DsNavLibraryLink && (
|
||||
<DsNavLibraryLink
|
||||
active={activePage === 'library' && !trashActive}
|
||||
inLibrary={activePage === 'library'}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className={classnames('ds-nav-page-switcher-item', {
|
||||
active: isTrashActive,
|
||||
})}
|
||||
aria-current={isTrashActive ? 'page' : undefined}
|
||||
onClick={() => selectFilter('trashed')}
|
||||
>
|
||||
<Trash size={20} />
|
||||
<span className="ds-nav-page-switcher-item-label">
|
||||
{t('trash')}
|
||||
</span>
|
||||
</button>
|
||||
</>
|
||||
{DsNavLibraryLink && (
|
||||
<DsNavLibraryLink
|
||||
active={activePage === 'library' && !trashActive}
|
||||
inLibrary={activePage === 'library'}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className={classnames('ds-nav-page-switcher-item', {
|
||||
active: isTrashActive,
|
||||
})}
|
||||
aria-current={isTrashActive ? 'page' : undefined}
|
||||
onClick={() => selectFilter('trashed')}
|
||||
>
|
||||
<Trash size={20} />
|
||||
<span className="ds-nav-page-switcher-item-label">
|
||||
{t('trash')}
|
||||
</span>
|
||||
</button>
|
||||
<div className="project-list-sidebar-survey-wrapper">
|
||||
<SurveyWidgetDsNav />
|
||||
</div>
|
||||
|
||||
+2
-11
@@ -6,7 +6,6 @@ import {
|
||||
} from '../../context/project-list-context'
|
||||
import TagsList from './tags-list'
|
||||
import ProjectsFilterMenu from '../projects-filter-menu'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { Folder } from '@phosphor-icons/react'
|
||||
import { ActivePage } from '../../util/navigation-state'
|
||||
|
||||
@@ -51,14 +50,13 @@ export default function SidebarFilters({
|
||||
activePage: ActivePage
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const isLibraryEnabled = isSplitTestEnabled('overleaf-library')
|
||||
return (
|
||||
<ul className="list-unstyled project-list-filters">
|
||||
<SidebarFilter
|
||||
activePage={activePage}
|
||||
filter="all"
|
||||
text={isLibraryEnabled ? t('projects') : t('all_projects')}
|
||||
icon={isLibraryEnabled && <Folder size={20} />}
|
||||
text={t('projects')}
|
||||
icon={<Folder size={20} />}
|
||||
/>
|
||||
<SidebarFilter
|
||||
activePage={activePage}
|
||||
@@ -75,13 +73,6 @@ export default function SidebarFilters({
|
||||
filter="archived"
|
||||
text={t('archived_projects')}
|
||||
/>
|
||||
{!isLibraryEnabled && (
|
||||
<SidebarFilter
|
||||
activePage={activePage}
|
||||
filter="trashed"
|
||||
text={t('trashed_projects')}
|
||||
/>
|
||||
)}
|
||||
<li aria-hidden="true">
|
||||
<hr />
|
||||
</li>
|
||||
|
||||
+18
-2
@@ -1,16 +1,32 @@
|
||||
import { TFunction } from 'i18next'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import classnames from 'classnames'
|
||||
import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
|
||||
|
||||
export type TrashTab = 'projects' | 'references'
|
||||
|
||||
export type TrashPageTab = { key: TrashTab; label: string; href: string }
|
||||
|
||||
type TrashPageTabModule = {
|
||||
import: { default: (t: TFunction) => TrashPageTab }
|
||||
path: string
|
||||
}
|
||||
|
||||
const trashPageTabModules: TrashPageTabModule[] =
|
||||
importOverleafModules('trashPageTabs')
|
||||
|
||||
function TrashPageTabs({ activeTab }: { activeTab: TrashTab }) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const tabs: { key: TrashTab; label: string; href: string }[] = [
|
||||
const tabs: TrashPageTab[] = [
|
||||
{ key: 'projects', label: t('projects'), href: '/project/trashed' },
|
||||
{ key: 'references', label: t('references'), href: '/library/trashed' },
|
||||
...trashPageTabModules.map(({ import: getTab }) => getTab.default(t)),
|
||||
]
|
||||
|
||||
if (tabs.length < 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className="trash-page-tabs" aria-label={t('trash')}>
|
||||
{tabs.map(tab => {
|
||||
|
||||
@@ -53,7 +53,8 @@ body {
|
||||
.navbar-header .navbar-logo {
|
||||
@include media-breakpoint-up(md) {
|
||||
position: relative;
|
||||
top: var(--spacing-05);
|
||||
top: calc(var(--spacing-05) * 2);
|
||||
left: var(--spacing-05);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,61 +106,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
&.library-enabled {
|
||||
.navbar-default .navbar-header .navbar-logo {
|
||||
@include media-breakpoint-up(md) {
|
||||
top: calc(var(--spacing-05) * 2);
|
||||
left: var(--spacing-05);
|
||||
}
|
||||
}
|
||||
|
||||
.project-list-wrapper .project-list-sidebar-wrapper-react {
|
||||
padding-top: calc(var(--spacing-08) - 1px);
|
||||
|
||||
.project-list-sidebar-scroll {
|
||||
padding-top: 0;
|
||||
padding-right: var(--spacing-05);
|
||||
}
|
||||
|
||||
ul.project-list-filters {
|
||||
margin-top: var(--spacing-05);
|
||||
|
||||
.sidebar-filter-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: calc(var(--spacing-05) + 20px + var(--spacing-05));
|
||||
}
|
||||
|
||||
.sidebar-filter-button-with-icon {
|
||||
// Only the items with an icon are 44px tall: 20px of content between
|
||||
// 12px paddings. The rest of the filters stay at 40px.
|
||||
line-height: var(--line-height-02);
|
||||
padding: var(--spacing-05);
|
||||
|
||||
// Without this the icon is an inline box sitting on the text
|
||||
// baseline, which leaves descender space below it and stops
|
||||
// align-items from centring it against the label.
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-right: var(--spacing-05);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
padding-left: calc(var(--spacing-06) + 20px + var(--spacing-05));
|
||||
}
|
||||
|
||||
> li.tag button.tag-name {
|
||||
padding-left: calc(var(--spacing-06) + 20px + var(--spacing-05));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ds-nav-hides-top-navbar {
|
||||
// The sidebar shows the logo and account/help menus from md upwards, so
|
||||
// the top navbar is only needed on mobile.
|
||||
@@ -210,7 +156,7 @@ body {
|
||||
max-width: 320px;
|
||||
min-width: 200px;
|
||||
margin-top: var(--spacing-03);
|
||||
padding: var(--spacing-08) 0 0 0;
|
||||
padding: calc(var(--spacing-08) - 1px) 0 0;
|
||||
|
||||
.new-project-dropdown {
|
||||
padding: 0 var(--spacing-08) var(--spacing-05) var(--spacing-05);
|
||||
@@ -240,8 +186,44 @@ body {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
margin: 0 var(--spacing-02) 0 0;
|
||||
padding: var(--spacing-05) var(--spacing-07) var(--spacing-05)
|
||||
var(--spacing-05);
|
||||
padding: 0 var(--spacing-05) var(--spacing-05);
|
||||
}
|
||||
|
||||
ul.project-list-filters {
|
||||
margin-top: var(--spacing-05);
|
||||
|
||||
.sidebar-filter-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: calc(var(--spacing-05) + 20px + var(--spacing-05));
|
||||
}
|
||||
|
||||
.sidebar-filter-button-with-icon {
|
||||
// Only the items with an icon are 44px tall: 20px of content between
|
||||
// 12px paddings. The rest of the filters stay at 40px.
|
||||
line-height: var(--line-height-02);
|
||||
padding: var(--spacing-05);
|
||||
|
||||
// Without this the icon is an inline box sitting on the text
|
||||
// baseline, which leaves descender space below it and stops
|
||||
// align-items from centring it against the label.
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
margin-right: var(--spacing-05);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
padding-left: calc(var(--spacing-06) + 20px + var(--spacing-05));
|
||||
}
|
||||
|
||||
> li.tag button.tag-name {
|
||||
padding-left: calc(var(--spacing-06) + 20px + var(--spacing-05));
|
||||
}
|
||||
}
|
||||
|
||||
.ds-nav-page-switcher-logo {
|
||||
|
||||
@@ -579,7 +579,6 @@
|
||||
"file_too_large": "For stor fil",
|
||||
"files_cannot_include_invalid_characters": "Filnavnet er tomt, eller indeholder ugyldige karakterer",
|
||||
"files_selected": "filer valgt.",
|
||||
"filter_projects": "Filtrer projekter",
|
||||
"filters": "Filtre",
|
||||
"find_out_more": "Find ud af mere",
|
||||
"find_out_more_about_institution_login": "Få mere at vide om institutionel indlogning",
|
||||
@@ -1613,7 +1612,6 @@
|
||||
"search_in_your_projects": "Søg i dine projekter",
|
||||
"search_match_case": "Match store/små bogstaver",
|
||||
"search_next": "næste",
|
||||
"search_only_the_bib_files_in_your_project_only_by_citekeys": "Søg udelukkende .bib filerne i dit projekt, kun efter citeringsnøgle.",
|
||||
"search_previous": "forrige",
|
||||
"search_projects": "Søg efter projekter",
|
||||
"search_references": "Søg i .bib filerne fra dette projekt",
|
||||
|
||||
@@ -559,7 +559,6 @@
|
||||
"file_too_large": "Datei zu groß",
|
||||
"files_cannot_include_invalid_characters": "Der Dateiname ist leer oder enthält ungültige Zeichen",
|
||||
"files_selected": "Dateien ausgewählt.",
|
||||
"filter_projects": "Projekte filtern",
|
||||
"filters": "Filter",
|
||||
"find_out_more": "Finde mehr heraus",
|
||||
"find_out_more_about_institution_login": "Erfahre mehr über den institutionellen Login",
|
||||
|
||||
@@ -962,7 +962,6 @@
|
||||
"file_tree": "File tree",
|
||||
"files_cannot_include_invalid_characters": "File name is empty or contains invalid characters",
|
||||
"files_selected": "files selected.",
|
||||
"filter_projects": "Filter projects",
|
||||
"filters": "Filters",
|
||||
"find": "Find",
|
||||
"find_out_how_to_get_the_most_out_of_your_new_subscription": "Find out how to get the most out of your new subscription by checking out <0>Overleaf’s AI features</0>.",
|
||||
@@ -2467,7 +2466,6 @@
|
||||
"search_match_case": "Match case",
|
||||
"search_members": "Search members",
|
||||
"search_next": "next",
|
||||
"search_only_the_bib_files_in_your_project_only_by_citekeys": "Search only the .bib files in your project, only by citekeys.",
|
||||
"search_previous": "previous",
|
||||
"search_project": "Search project",
|
||||
"search_projects": "Search projects",
|
||||
|
||||
@@ -673,7 +673,6 @@
|
||||
"file_tree": "文件树",
|
||||
"files_cannot_include_invalid_characters": "文件名为空或包含无效字符",
|
||||
"files_selected": "个文件被选中。",
|
||||
"filter_projects": "过滤项目",
|
||||
"filters": "筛选器",
|
||||
"find": "查找",
|
||||
"find_out_more": "了解更多",
|
||||
@@ -1824,7 +1823,6 @@
|
||||
"search_in_your_projects": "在您的项目中搜索",
|
||||
"search_match_case": "区分大小写",
|
||||
"search_next": "下一个",
|
||||
"search_only_the_bib_files_in_your_project_only_by_citekeys": "仅通过 citekeys 搜索项目中的 .bib 文件。",
|
||||
"search_previous": "上一个",
|
||||
"search_project": "搜索项目",
|
||||
"search_projects": "搜索项目",
|
||||
|
||||
+22
-11
@@ -33,6 +33,19 @@ const {
|
||||
|
||||
const userId = owner.id
|
||||
|
||||
// The sidebar's trash page switcher and the per-row trash action buttons share
|
||||
// the accessible name "Trash", so pick the one outside the project table.
|
||||
function getSidebarTrashButton() {
|
||||
const table = screen.getByRole('table')
|
||||
return screen
|
||||
.getAllByRole('button', { name: 'Trash' })
|
||||
.filter(button => !table.contains(button))[0]
|
||||
}
|
||||
|
||||
function getSidebarProjectsFilterButton() {
|
||||
return screen.getAllByRole('button', { name: 'Projects' })[0]
|
||||
}
|
||||
|
||||
describe('<ProjectListRoot />', function () {
|
||||
this.timeout('10s')
|
||||
|
||||
@@ -308,8 +321,7 @@ describe('<ProjectListRoot />', function () {
|
||||
|
||||
describe('trashed projects', function () {
|
||||
beforeEach(function () {
|
||||
const filterButton = screen.getAllByText('Trashed projects')[0]
|
||||
fireEvent.click(filterButton)
|
||||
fireEvent.click(getSidebarTrashButton())
|
||||
|
||||
allCheckboxes = screen.getAllByRole<HTMLInputElement>('checkbox')
|
||||
// + 1 because of select all
|
||||
@@ -326,15 +338,14 @@ describe('<ProjectListRoot />', function () {
|
||||
})
|
||||
|
||||
it('shows the download, archive, and restore buttons in top toolbar', function () {
|
||||
expect(screen.queryByLabelText('Trash')).to.be.null
|
||||
expect(within(actionsToolbar).queryByLabelText('Trash')).to.be.null
|
||||
within(actionsToolbar).queryByLabelText('Download')
|
||||
within(actionsToolbar).queryByLabelText('Archive')
|
||||
within(actionsToolbar).getByText('Restore') // no icon for this button
|
||||
})
|
||||
|
||||
it('clears selected projects when filter changed', function () {
|
||||
const filterButton = screen.getAllByText('All projects')[0]
|
||||
fireEvent.click(filterButton)
|
||||
fireEvent.click(getSidebarProjectsFilterButton())
|
||||
|
||||
const allCheckboxes =
|
||||
screen.getAllByRole<HTMLInputElement>('checkbox')
|
||||
@@ -641,7 +652,10 @@ describe('<ProjectListRoot />', function () {
|
||||
expect(screen.queryByText(p.name)).to.be.null
|
||||
})
|
||||
|
||||
const trashBtns = screen.getAllByRole('button', { name: 'Trash' })
|
||||
const trashBtns = within(screen.getByRole('table')).getAllByRole(
|
||||
'button',
|
||||
{ name: 'Trash' }
|
||||
)
|
||||
for (const [index, trashBtn] of trashBtns.entries()) {
|
||||
fireEvent.click(trashBtn)
|
||||
fireEvent.click(
|
||||
@@ -829,9 +843,7 @@ describe('<ProjectListRoot />', function () {
|
||||
assertToolbarButtonsExists()
|
||||
|
||||
// select trashed projects
|
||||
const [trashedProjectsButton] =
|
||||
screen.getAllByText(/trashed projects/i)
|
||||
fireEvent.click(trashedProjectsButton)
|
||||
fireEvent.click(getSidebarTrashButton())
|
||||
fireEvent.click(tag)
|
||||
|
||||
allCheckboxes = screen.getAllByRole('checkbox')
|
||||
@@ -843,8 +855,7 @@ describe('<ProjectListRoot />', function () {
|
||||
|
||||
describe('"More" dropdown', function () {
|
||||
beforeEach(async function () {
|
||||
const filterButton = screen.getAllByText('All projects')[0]
|
||||
fireEvent.click(filterButton)
|
||||
fireEvent.click(getSidebarProjectsFilterButton())
|
||||
allCheckboxes = screen.getAllByRole<HTMLInputElement>('checkbox')
|
||||
})
|
||||
|
||||
|
||||
-3
@@ -41,9 +41,6 @@ describe('<SidebarDsNav />', function () {
|
||||
global.localStorage.clear()
|
||||
window.metaAttributesCache.set('ol-tags', [])
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', { isOverleaf: true })
|
||||
window.metaAttributesCache.set('ol-splitTestVariants', {
|
||||
'overleaf-library': 'enabled',
|
||||
})
|
||||
window.metaAttributesCache.set('ol-inactiveTutorials', [
|
||||
'library-new-badge',
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user