mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-04 22:59:01 +02:00
Merge pull request #32655 from overleaf/mj-preview-tabs-setting
[web] Add setting for temporary tab behaviour GitOrigin-RevId: efef9e1db55d4498daadf13efad7fe12578cec21
This commit is contained in:
committed by
Copybot
parent
77952e5d21
commit
2d9fc99274
@@ -38,6 +38,7 @@ async function buildUserSettings(req, res, user) {
|
||||
autoPairDelimiters: user.ace.autoPairDelimiters,
|
||||
pdfViewer: user.ace.pdfViewer,
|
||||
syntaxValidation: user.ace.syntaxValidation,
|
||||
previewTabs: user.ace.previewTabs ?? false,
|
||||
fontFamily: user.ace.fontFamily || 'lucida',
|
||||
lineHeight: user.ace.lineHeight || 'normal',
|
||||
overallTheme: await getOverallTheme(req, res, user),
|
||||
|
||||
@@ -406,6 +406,9 @@ async function updateUserSettings(req, res, next) {
|
||||
if (body.syntaxValidation != null) {
|
||||
user.ace.syntaxValidation = body.syntaxValidation
|
||||
}
|
||||
if (body.previewTabs != null) {
|
||||
user.ace.previewTabs = Boolean(body.previewTabs)
|
||||
}
|
||||
if (body.fontFamily != null) {
|
||||
user.ace.fontFamily = body.fontFamily
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ export const UserSchema = new Schema(
|
||||
spellCheckLanguage: { type: String, default: 'en' },
|
||||
pdfViewer: { type: String, default: 'pdfjs' },
|
||||
syntaxValidation: { type: Boolean },
|
||||
previewTabs: { type: Boolean, default: false },
|
||||
fontFamily: { type: String },
|
||||
lineHeight: { type: String },
|
||||
mathPreview: { type: Boolean, default: true },
|
||||
|
||||
@@ -1390,6 +1390,7 @@
|
||||
"premium_feature": "",
|
||||
"premium_plan_label": "",
|
||||
"presentation_mode": "",
|
||||
"preview_editor_tabs": "",
|
||||
"previous_page": "",
|
||||
"price": "",
|
||||
"primarily_work_study_question": "",
|
||||
@@ -1880,6 +1881,7 @@
|
||||
"syntax_checks": "",
|
||||
"syntax_validation": "",
|
||||
"table": "",
|
||||
"tabs_open_in_preview_mode_until_you_interact_with_them": "",
|
||||
"tag_color": "",
|
||||
"tag_name_cannot_exceed_characters": "",
|
||||
"tag_name_is_already_used": "",
|
||||
|
||||
+7
@@ -19,6 +19,7 @@ type ProjectSettingsSetterContextValue = {
|
||||
setSyntaxValidation: (
|
||||
syntaxValidation: UserSettings['syntaxValidation']
|
||||
) => void
|
||||
setPreviewTabs: (previewTabs: UserSettings['previewTabs']) => void
|
||||
setMode: (mode: UserSettings['mode']) => void
|
||||
setEditorTheme: (editorTheme: UserSettings['editorTheme']) => void
|
||||
setEditorLightTheme: (
|
||||
@@ -67,6 +68,8 @@ export const ProjectSettingsProvider: FC<React.PropsWithChildren> = ({
|
||||
setAutoPairDelimiters,
|
||||
syntaxValidation,
|
||||
setSyntaxValidation,
|
||||
previewTabs,
|
||||
setPreviewTabs,
|
||||
editorTheme,
|
||||
setEditorTheme,
|
||||
editorLightTheme,
|
||||
@@ -117,6 +120,8 @@ export const ProjectSettingsProvider: FC<React.PropsWithChildren> = ({
|
||||
setAutoPairDelimiters,
|
||||
syntaxValidation,
|
||||
setSyntaxValidation,
|
||||
previewTabs,
|
||||
setPreviewTabs,
|
||||
editorTheme,
|
||||
setEditorTheme,
|
||||
editorLightTheme,
|
||||
@@ -163,6 +168,8 @@ export const ProjectSettingsProvider: FC<React.PropsWithChildren> = ({
|
||||
setAutoPairDelimiters,
|
||||
syntaxValidation,
|
||||
setSyntaxValidation,
|
||||
previewTabs,
|
||||
setPreviewTabs,
|
||||
editorTheme,
|
||||
setEditorTheme,
|
||||
editorLightTheme,
|
||||
|
||||
@@ -13,6 +13,7 @@ export default function useUserWideSettings() {
|
||||
autoComplete,
|
||||
autoPairDelimiters,
|
||||
syntaxValidation,
|
||||
previewTabs,
|
||||
editorTheme,
|
||||
editorLightTheme,
|
||||
editorDarkTheme,
|
||||
@@ -51,6 +52,13 @@ export default function useUserWideSettings() {
|
||||
[saveUserSettings]
|
||||
)
|
||||
|
||||
const setPreviewTabs = useCallback(
|
||||
(previewTabs: UserSettings['previewTabs']) => {
|
||||
saveUserSettings('previewTabs', previewTabs)
|
||||
},
|
||||
[saveUserSettings]
|
||||
)
|
||||
|
||||
const setEditorTheme = useCallback(
|
||||
(editorTheme: UserSettings['editorTheme']) => {
|
||||
saveUserSettings('editorTheme', editorTheme)
|
||||
@@ -156,6 +164,8 @@ export default function useUserWideSettings() {
|
||||
setAutoPairDelimiters,
|
||||
syntaxValidation,
|
||||
setSyntaxValidation,
|
||||
previewTabs,
|
||||
setPreviewTabs,
|
||||
editorTheme,
|
||||
setEditorTheme,
|
||||
editorLightTheme,
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useEditorManagerContext } from './editor-manager-context'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import { disambiguatePaths } from '../util/disambiguate-paths'
|
||||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { useUserSettingsContext } from '@/shared/context/user-settings-context'
|
||||
|
||||
type PersistedTabInfo = { id: string; lifetime: Lifetime }
|
||||
|
||||
@@ -43,6 +44,8 @@ export const TabsProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const { openEntity } = useFileTreeOpenContext()
|
||||
const { openDocWithId, openFileWithId } = useEditorManagerContext()
|
||||
const tabsEnabled = isSplitTestEnabled('editor-tabs')
|
||||
const { userSettings } = useUserSettingsContext()
|
||||
const { previewTabs } = userSettings
|
||||
|
||||
const [openTabs, setOpenTabs] = usePersistedState<PersistedTabInfo[]>(
|
||||
`open-tabs:${projectId}`,
|
||||
@@ -183,10 +186,13 @@ export const TabsProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
}
|
||||
return [
|
||||
...current.filter(tab => tab.lifetime !== 'temporary'),
|
||||
{ id: openEntity.entity._id, lifetime: 'temporary' },
|
||||
{
|
||||
id: openEntity.entity._id,
|
||||
lifetime: previewTabs ? 'temporary' : 'permanent',
|
||||
},
|
||||
]
|
||||
})
|
||||
}, [openEntity, setOpenTabs, tabsEnabled])
|
||||
}, [openEntity, previewTabs, setOpenTabs, tabsEnabled])
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ tabs, openTab, closeTab, moveTab, makeTabPermanent }),
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
|
||||
import ToggleSetting from '../toggle-setting'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function PreviewTabsSetting() {
|
||||
const { previewTabs, setPreviewTabs } = useProjectSettingsContext()
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<ToggleSetting
|
||||
id="previewTabs"
|
||||
label={t('preview_editor_tabs')}
|
||||
description={t('tabs_open_in_preview_mode_until_you_interact_with_them')}
|
||||
checked={previewTabs}
|
||||
onChange={setPreviewTabs}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ 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'
|
||||
import CodeCheckSetting from '@/features/settings/components/editor-settings/code-check-setting'
|
||||
import PreviewTabsSetting from '@/features/settings/components/editor-settings/preview-tabs-setting'
|
||||
import KeybindingSetting from '@/features/settings/components/editor-settings/keybinding-setting'
|
||||
import PDFViewerSetting from '@/features/settings/components/editor-settings/pdf-viewer-setting'
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
@@ -90,6 +91,7 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
|
||||
const { leftMenuShown, setLeftMenuShown } = useLayoutContext()
|
||||
|
||||
const hasEmailNotifications = useFeatureFlag('email-notifications')
|
||||
const hasEditorTabs = useFeatureFlag('editor-tabs')
|
||||
|
||||
const allSettingsTabs: SettingsEntry[] = useMemo(
|
||||
() => [
|
||||
@@ -113,6 +115,11 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
|
||||
key: 'syntaxValidation',
|
||||
component: <CodeCheckSetting />,
|
||||
},
|
||||
{
|
||||
key: 'previewTabs',
|
||||
component: <PreviewTabsSetting />,
|
||||
hidden: !hasEditorTabs,
|
||||
},
|
||||
{
|
||||
key: 'mode',
|
||||
component: <KeybindingSetting />,
|
||||
@@ -264,7 +271,7 @@ export const SettingsModalProvider: FC<React.PropsWithChildren> = ({
|
||||
hidden: !isOverleaf,
|
||||
},
|
||||
],
|
||||
[t, overallTheme, hasEmailNotifications, isOverleaf]
|
||||
[t, overallTheme, hasEmailNotifications, isOverleaf, hasEditorTabs]
|
||||
)
|
||||
|
||||
const settingsTabs = useMemo(
|
||||
|
||||
@@ -19,6 +19,7 @@ export const defaultSettings: UserSettings = {
|
||||
autoComplete: true,
|
||||
autoPairDelimiters: true,
|
||||
syntaxValidation: false,
|
||||
previewTabs: false,
|
||||
editorTheme: 'textmate',
|
||||
editorDarkTheme: 'overleaf_dark',
|
||||
editorLightTheme: 'textmate',
|
||||
|
||||
@@ -1800,6 +1800,7 @@
|
||||
"premium_plan_label": "You’re using <b>Overleaf Premium</b>",
|
||||
"presentation": "Presentation",
|
||||
"presentation_mode": "Presentation mode",
|
||||
"preview_editor_tabs": "Preview editor tabs",
|
||||
"previous_page": "Previous page",
|
||||
"price": "Price",
|
||||
"pricing": "Pricing",
|
||||
@@ -2389,6 +2390,7 @@
|
||||
"syntax_validation": "Code check",
|
||||
"table": "Table",
|
||||
"table_generator": "Table Generator",
|
||||
"tabs_open_in_preview_mode_until_you_interact_with_them": "Tabs open in preview mode until you interact with them",
|
||||
"tag_color": "Tag color",
|
||||
"tag_name_cannot_exceed_characters": "Tag name cannot exceed __maxLength__ characters",
|
||||
"tag_name_is_already_used": "Tag \"__tagName__\" already exists",
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { screen, render } from '@testing-library/react'
|
||||
import { expect } from 'chai'
|
||||
import fetchMock from 'fetch-mock'
|
||||
import { EditorProviders } from '../../../helpers/editor-providers'
|
||||
import { SettingsModalProvider } from '@/features/settings/context/settings-modal-context'
|
||||
import PreviewTabsSetting from '@/features/settings/components/editor-settings/preview-tabs-setting'
|
||||
|
||||
describe('<PreviewTabsSetting />', function () {
|
||||
afterEach(function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
})
|
||||
|
||||
it('can toggle', async function () {
|
||||
render(
|
||||
<EditorProviders>
|
||||
<SettingsModalProvider>
|
||||
<PreviewTabsSetting />
|
||||
</SettingsModalProvider>
|
||||
</EditorProviders>
|
||||
)
|
||||
|
||||
const saveSettingsMock = fetchMock.post(
|
||||
`express:/user/settings`,
|
||||
{
|
||||
status: 200,
|
||||
},
|
||||
{ delay: 0 }
|
||||
)
|
||||
|
||||
const toggle = screen.getByLabelText('Preview editor tabs')
|
||||
const startingCheckedValue = (toggle as HTMLInputElement).checked
|
||||
|
||||
// Toggle the checkbox
|
||||
toggle.click()
|
||||
expect((toggle as HTMLInputElement).checked).to.equal(!startingCheckedValue)
|
||||
expect(
|
||||
saveSettingsMock.callHistory.called(`/user/settings`, {
|
||||
body: { previewTabs: !startingCheckedValue },
|
||||
})
|
||||
).to.be.true
|
||||
|
||||
// Toggle back to original value
|
||||
toggle.click()
|
||||
expect((toggle as HTMLInputElement).checked).to.equal(startingCheckedValue)
|
||||
expect(
|
||||
saveSettingsMock.callHistory.called(`/user/settings`, {
|
||||
body: { previewTabs: startingCheckedValue },
|
||||
})
|
||||
).to.be.true
|
||||
})
|
||||
})
|
||||
@@ -162,6 +162,7 @@ function selectEntity(
|
||||
document.dispatchEvent(
|
||||
new CustomEvent('test:selectEntity', { detail: entity })
|
||||
)
|
||||
cy.findByRole('tab', { name: new RegExp(entity.entity.name) }).should('exist')
|
||||
}
|
||||
|
||||
function selectDoc(id: string, path?: string[]) {
|
||||
@@ -178,12 +179,13 @@ function enableEditorTabs() {
|
||||
}
|
||||
|
||||
describe('File Tabs', function () {
|
||||
function mountTabs(options?: { rootFolder?: any }) {
|
||||
function mountTabs(options?: { rootFolder?: any; userSettings?: any }) {
|
||||
const rootFolder = options?.rootFolder ?? defaultRootFolder
|
||||
cy.mount(
|
||||
<EditorProviders
|
||||
rootFolder={rootFolder as any}
|
||||
rootDocId={DOC_IDS.main}
|
||||
userSettings={options?.userSettings}
|
||||
providers={{
|
||||
EditorManagerProvider: makeEditorManagerProvider(),
|
||||
}}
|
||||
@@ -285,6 +287,10 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
describe('Temporary tabs', function () {
|
||||
beforeEach(function () {
|
||||
mountTabs({ userSettings: { previewTabs: true } })
|
||||
})
|
||||
|
||||
it('opens a newly selected file as a temporary tab', function () {
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
// The first tab is temporary until a keypress
|
||||
@@ -346,17 +352,25 @@ describe('File Tabs', function () {
|
||||
'tab-temporary'
|
||||
)
|
||||
})
|
||||
|
||||
it('opens a new tab as permanent when previewTabs is disabled', function () {
|
||||
mountTabs({ userSettings: { previewTabs: false } })
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
|
||||
cy.findByRole('tab', { name: /main\.tex/ }).should(
|
||||
'not.have.class',
|
||||
'tab-temporary'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Closing tabs', function () {
|
||||
it('closes a tab via the close button', function () {
|
||||
// Open main (permanent)
|
||||
// Open main
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open intro (permanent)
|
||||
// Open intro
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').should('have.length', 2)
|
||||
|
||||
@@ -384,15 +398,10 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('switches to an adjacent tab when closing the currently active tab', function () {
|
||||
// Open three permanent tabs
|
||||
// Open three tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.appendix))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').should('have.length', 3)
|
||||
|
||||
@@ -408,12 +417,9 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('closes a tab on middle-click', function () {
|
||||
// Open two permanent tabs
|
||||
// Open two tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').should('have.length', 2)
|
||||
|
||||
@@ -428,12 +434,9 @@ describe('File Tabs', function () {
|
||||
|
||||
describe('Tab interaction', function () {
|
||||
it('calls openDocWithId when clicking a non-selected doc tab', function () {
|
||||
// Open two permanent tabs
|
||||
// Open two tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Click main tab
|
||||
cy.findByRole('tab', { name: /main\.tex/ }).click()
|
||||
@@ -450,15 +453,13 @@ describe('File Tabs', function () {
|
||||
|
||||
mountTabs({ rootFolder })
|
||||
|
||||
// Open main doc (permanent)
|
||||
// Open main doc
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open fileRef (permanent)
|
||||
// Open fileRef
|
||||
cy.then(() =>
|
||||
selectEntity(makeFileRefEntity(DOC_IDS.bibFile, 'refs.bib'))
|
||||
)
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Switch back to main so refs.bib is no longer selected
|
||||
cy.findByRole('tab', { name: /main\.tex/ }).click()
|
||||
@@ -472,15 +473,10 @@ describe('File Tabs', function () {
|
||||
|
||||
describe('Drag and drop', function () {
|
||||
it('reorders tabs by dragging to the right of another tab', function () {
|
||||
// Open three permanent tabs
|
||||
// Open three tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.appendix))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').should('have.length', 3)
|
||||
|
||||
@@ -516,15 +512,10 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('reorders tabs by dragging to the left of another tab', function () {
|
||||
// Open three permanent tabs
|
||||
// Open three tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.appendix))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Verify initial order
|
||||
cy.findAllByRole('tab').eq(0).should('contain.text', 'main.tex')
|
||||
@@ -558,12 +549,9 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('shows a drop indicator when dragging over a tab', function () {
|
||||
// Open two permanent tabs
|
||||
// Open two tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
const dataTransfer = new DataTransfer()
|
||||
dataTransfer.setData(TAB_TRANSFER_TYPE, DOC_IDS.intro)
|
||||
@@ -596,15 +584,10 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('drops onto the tablist to move a tab to the end', function () {
|
||||
// Open three permanent tabs
|
||||
// Open three tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.appendix))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').eq(0).should('contain.text', 'main.tex')
|
||||
|
||||
@@ -624,12 +607,9 @@ describe('File Tabs', function () {
|
||||
})
|
||||
|
||||
it('does nothing when dropping a tab on itself', function () {
|
||||
// Open two permanent tabs
|
||||
// Open two tabs
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.then(() => selectDoc(DOC_IDS.intro))
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').eq(0).should('contain.text', 'main.tex')
|
||||
cy.findAllByRole('tab').eq(1).should('contain.text', 'intro.tex')
|
||||
@@ -686,19 +666,16 @@ describe('File Tabs', function () {
|
||||
|
||||
// Open main.tex (unique name, no disambiguation needed)
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open intro.tex from chapter-a
|
||||
cy.then(() =>
|
||||
selectDoc(DOC_IDS.introA, ['root-folder-id', FOLDER_IDS.chapterA])
|
||||
)
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open intro.tex from chapter-b
|
||||
cy.then(() =>
|
||||
selectDoc(DOC_IDS.introB, ['root-folder-id', FOLDER_IDS.chapterB])
|
||||
)
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findAllByRole('tab').should('have.length', 3)
|
||||
|
||||
@@ -721,7 +698,6 @@ describe('File Tabs', function () {
|
||||
cy.then(() =>
|
||||
selectDoc(DOC_IDS.introA, ['root-folder-id', FOLDER_IDS.chapterA])
|
||||
)
|
||||
cy.get('body').type('a')
|
||||
|
||||
// With only one intro.tex open, no disambiguation is needed
|
||||
cy.findByRole('tab', { name: /intro\.tex/ }).should('exist')
|
||||
@@ -744,13 +720,11 @@ describe('File Tabs', function () {
|
||||
|
||||
// Open main doc
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open a fileRef
|
||||
cy.then(() =>
|
||||
selectEntity(makeFileRefEntity(DOC_IDS.bibFile, 'refs.bib'))
|
||||
)
|
||||
cy.get('body').type('a')
|
||||
|
||||
cy.findByRole('tab', { name: /main\.tex/ }).should('exist')
|
||||
cy.findByRole('tab', { name: /refs\.bib/ }).should('exist')
|
||||
@@ -769,9 +743,8 @@ describe('File Tabs', function () {
|
||||
const rootFolder = makeRootFolder(manyDocs)
|
||||
mountTabs({ rootFolder })
|
||||
|
||||
// Open main and make it permanent
|
||||
// Open main
|
||||
cy.then(() => selectDoc(DOC_IDS.main))
|
||||
cy.get('body').type('a')
|
||||
|
||||
// Open all chapter tabs first so they push main.tex out of view
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
|
||||
@@ -15,6 +15,7 @@ export type UserSettings = {
|
||||
autoComplete: boolean
|
||||
autoPairDelimiters: boolean
|
||||
syntaxValidation: boolean
|
||||
previewTabs: boolean
|
||||
editorTheme: string
|
||||
editorLightTheme: string
|
||||
editorDarkTheme: string
|
||||
|
||||
Reference in New Issue
Block a user