Merge pull request #3330 from overleaf/jel-toolbar-btns

Hide toolbar text and show tooltip when out of space

GitOrigin-RevId: 5a73b69e7d92695c4f8691a747307908550e3790
This commit is contained in:
Jessica Lawshe
2020-11-10 03:04:35 +00:00
committed by Copybot
parent da8663fd0f
commit 21ffe27bdd
10 changed files with 593 additions and 172 deletions
@@ -19,17 +19,36 @@ describe('<PreviewDownloadButton />', function() {
}
}
it('should disable the button and dropdown toggle when compiling', function() {
const isCompiling = true
const outputFiles = undefined
function renderPreviewDownloadButton(
isCompiling,
outputFiles,
pdfDownloadUrl,
showText
) {
if (isCompiling === undefined) isCompiling = false
if (showText === undefined) showText = true
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={undefined}
outputFiles={outputFiles || []}
pdfDownloadUrl={pdfDownloadUrl}
showText={showText}
/>
)
expect(screen.getByText('Download PDF').getAttribute('disabled')).to.exist
}
it('should disable the button and dropdown toggle when compiling', function() {
const isCompiling = true
const outputFiles = undefined
renderPreviewDownloadButton(isCompiling, outputFiles)
expect(
screen
.getByText('Download PDF')
.closest('a')
.getAttribute('disabled')
).to.exist
const buttons = screen.getAllByRole('button')
expect(buttons.length).to.equal(1) // the dropdown toggle
expect(buttons[0].getAttribute('disabled')).to.exist
@@ -40,41 +59,35 @@ describe('<PreviewDownloadButton />', function() {
it('should disable the PDF button when there is no PDF', function() {
const isCompiling = false
const outputFiles = []
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={undefined}
/>
)
expect(screen.getByText('Download PDF').getAttribute('disabled')).to.exist
renderPreviewDownloadButton(isCompiling, outputFiles)
expect(
screen
.getByText('Download PDF')
.closest('a')
.getAttribute('disabled')
).to.exist
})
it('should enable the PDF button when there is a main PDF', function() {
const isCompiling = false
const outputFiles = []
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
expect(screen.getByText('Download PDF').getAttribute('href')).to.equal(
pdfDownloadUrl
)
expect(screen.getByText('Download PDF').getAttribute('disabled')).to.not
.exist
renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
expect(
screen
.getByText('Download PDF')
.closest('a')
.getAttribute('href')
).to.equal(pdfDownloadUrl)
expect(
screen
.getByText('Download PDF')
.closest('a')
.getAttribute('disabled')
).to.not.exist
})
it('should enable the dropdown when not compiling', function() {
const isCompiling = false
const outputFiles = []
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
const buttons = screen.getAllByRole('button')
expect(buttons[0]).to.exist
expect(buttons[0].getAttribute('disabled')).to.not.exist
@@ -93,13 +106,7 @@ describe('<PreviewDownloadButton />', function() {
makeFile('output.blg')
]
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
const menuItems = screen.getAllByRole('menuitem')
expect(menuItems.length).to.equal(outputFiles.length - 1) // main PDF is listed separately
@@ -138,13 +145,9 @@ describe('<PreviewDownloadButton />', function() {
const pdfFile = makeFile('output.pdf', true)
const bblFile = makeFile('output.bbl')
const outputFiles = [Object.assign({}, { ...bblFile }), bblFile, pdfFile]
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
const bblMenuItems = screen.getAllByText((content, element) => {
return (
content !== '' && element.textContent === 'Download output.bbl file'
@@ -157,16 +160,23 @@ describe('<PreviewDownloadButton />', function() {
const pdfFile = makeFile('output.pdf', true)
const pdfAltFile = makeFile('alt.pdf')
const outputFiles = [pdfFile, pdfAltFile]
render(
<PreviewDownloadButton
isCompiling={isCompiling}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
screen.getAllByRole('menuitem', { name: 'Download alt.pdf file' })
})
it('should show the button text when prop showText=true', function() {
const isCompiling = false
const showText = true
renderPreviewDownloadButton(isCompiling, [], pdfDownloadUrl, showText)
expect(screen.getByText('Download PDF').getAttribute('style')).to.be.null
})
it('should not show the button text when prop showText=false', function() {
const isCompiling = false
const showText = false
renderPreviewDownloadButton(isCompiling, [], pdfDownloadUrl, showText)
expect(screen.getByText('Download PDF').getAttribute('style')).to.equal(
'position: absolute; right: -100vw;'
)
})
describe('list divider and header', function() {
it('should display when there are top files and other files', function() {
const outputFiles = [
@@ -176,13 +186,7 @@ describe('<PreviewDownloadButton />', function() {
makeFile('output.log')
]
render(
<PreviewDownloadButton
isCompiling={false}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
screen.getByText('Other output files')
screen.getByRole('separator')
@@ -194,13 +198,7 @@ describe('<PreviewDownloadButton />', function() {
makeFile('output.gls')
]
render(
<PreviewDownloadButton
isCompiling={false}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
expect(screen.queryByText('Other output files')).to.not.exist
expect(screen.queryByRole('separator')).to.not.exist
@@ -208,13 +206,7 @@ describe('<PreviewDownloadButton />', function() {
it('should not display when there are other files and no top files', function() {
const outputFiles = [makeFile('output.log')]
render(
<PreviewDownloadButton
isCompiling={false}
outputFiles={outputFiles}
pdfDownloadUrl={pdfDownloadUrl}
/>
)
renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
expect(screen.queryByText('Other output files')).to.not.exist
expect(screen.queryByRole('separator')).to.not.exist
@@ -1,9 +1,27 @@
import React from 'react'
import { expect } from 'chai'
import { screen, render } from '@testing-library/react'
import PreviewLogsToggleButton from '../../../../../frontend/js/features/preview/components/preview-logs-toggle-button'
describe('<PreviewLogsToggleButton />', function() {
function renderPreviewLogsToggleButton(
logsState,
onToggleLogs,
showLogs,
showText
) {
if (showText === undefined) showText = true
render(
<PreviewLogsToggleButton
logsState={logsState}
onToggle={onToggleLogs}
showLogs={showLogs}
showText={showText}
/>
)
}
describe('basic toggle functionality', function() {
const logsState = {
nErrors: 0,
@@ -13,24 +31,12 @@ describe('<PreviewLogsToggleButton />', function() {
const onToggleLogs = () => {}
it('should render a view logs button when previewing the PDF', function() {
const showLogs = false
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText('View logs')
})
it('should render a view PDF button when viewing logs', function() {
const showLogs = true
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText('View PDF')
})
})
@@ -43,13 +49,7 @@ describe('<PreviewLogsToggleButton />', function() {
nWarnings: 0,
nLogEntries: 0
}
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText('View logs')
})
@@ -59,13 +59,7 @@ describe('<PreviewLogsToggleButton />', function() {
nWarnings: 0,
nLogEntries: 0
}
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText(`Your project has errors (${logsState.nErrors})`)
})
@@ -75,13 +69,7 @@ describe('<PreviewLogsToggleButton />', function() {
nWarnings: 1,
nLogEntries: 0
}
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText(`Your project has errors (${logsState.nErrors})`)
})
@@ -91,13 +79,7 @@ describe('<PreviewLogsToggleButton />', function() {
nWarnings: 1,
nLogEntries: 0
}
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText(`View warnings (${logsState.nWarnings})`)
})
@@ -107,14 +89,30 @@ describe('<PreviewLogsToggleButton />', function() {
nWarnings: 0,
nLogEntries: 0
}
render(
<PreviewLogsToggleButton
logsState={logsState}
showLogs={showLogs}
onToggle={onToggleLogs}
/>
)
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs)
screen.getByText('Your project has errors (9+)')
})
it('should show the button text when prop showText=true', function() {
const logsState = {
nErrors: 0,
nWarnings: 0,
nLogEntries: 0
}
const showText = true
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs, showText)
expect(screen.getByText('View logs').getAttribute('style')).to.be.null
})
it('should not show the button text when prop showText=false', function() {
const logsState = {
nErrors: 0,
nWarnings: 0,
nLogEntries: 0
}
const showText = false
renderPreviewLogsToggleButton(logsState, onToggleLogs, showLogs, showText)
expect(screen.getByText('View logs').getAttribute('style')).to.equal(
'position: absolute; right: -100vw;'
)
})
})
})
@@ -95,10 +95,24 @@ describe('<PreviewRecompileButton />', function() {
})
})
function renderPreviewRecompileButton(compilerState = {}) {
it('should show the button text when prop showText=true', function() {
const showText = true
renderPreviewRecompileButton({}, showText)
expect(screen.getByText('Recompile').getAttribute('style')).to.be.null
})
it('should not show the button text when prop showText=false', function() {
const showText = false
renderPreviewRecompileButton({}, showText)
expect(screen.getByText('Recompile').getAttribute('style')).to.equal(
'position: absolute; right: -100vw;'
)
})
function renderPreviewRecompileButton(compilerState = {}, showText) {
if (!compilerState.logEntries) {
compilerState.logEntries = {}
}
if (showText === undefined) showText = true
render(
<PreviewRecompileButton
compilerState={{
@@ -115,6 +129,7 @@ describe('<PreviewRecompileButton />', function() {
onSetDraftMode={() => {}}
onSetSyntaxCheck={() => {}}
onClearCache={onClearCache}
showText={showText}
/>
)
}
@@ -0,0 +1,66 @@
import React from 'react'
import sinon from 'sinon'
import { expect } from 'chai'
import { screen, render } from '@testing-library/react'
import PreviewToolbar from '../../../../../frontend/js/features/preview/components/preview-toolbar'
describe('<PreviewToolbar />', function() {
const onClearCache = sinon.stub()
const onRecompile = sinon.stub()
const onRunSyntaxCheckNow = sinon.stub()
const onSetAutoCompile = sinon.stub()
const onSetDraftMode = sinon.stub()
const onSetSyntaxCheck = sinon.stub()
const onToggleLogs = sinon.stub()
function renderPreviewToolbar(compilerState = {}, logState = {}, showLogs) {
render(
<PreviewToolbar
compilerState={{
isAutoCompileOn: true,
isClearingCache: false,
isCompiling: false,
isDraftModeOn: false,
isSyntaxCheckOn: false,
logEntries: {},
...compilerState
}}
logsState={{ nErrors: 0, nWarnings: 0, nLogEntries: 0, ...logState }}
onClearCache={onClearCache}
onRecompile={onRecompile}
onRunSyntaxCheckNow={onRunSyntaxCheckNow}
onSetAutoCompile={onSetAutoCompile}
onSetDraftMode={onSetDraftMode}
onSetSyntaxCheck={onSetSyntaxCheck}
onToggleLogs={onToggleLogs}
outputFiles={[]}
pdfDownloadUrl="/download-pdf-url"
showLogs={showLogs || false}
/>
)
}
it('renders the toolbar', function() {
renderPreviewToolbar()
screen.getByText('Recompile')
screen.getByText('Download PDF')
screen.getByText('View logs')
})
it('all toolbar items have "toolbar-item" class and text has "toolbar-text"', function() {
renderPreviewToolbar()
const toolbar = screen.getByTestId('toolbar-preview')
for (const toolbarSection of toolbar.children) {
for (const toolbarItem of toolbarSection.children) {
expect(toolbarItem.className).to.contain('toolbar-item')
for (const parts of toolbarItem.children) {
for (const part of parts.children) {
if (part.nodeName !== 'LI' && part.textContent) {
expect(part.className).to.contain('toolbar-text')
}
}
}
}
}
})
})