mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Add hybrid toolbar to migrated PDF preview (#5414)
GitOrigin-RevId: 6266028091229c819aee3c8d4bd3bff2e2417125
This commit is contained in:
parent
7f7e5ed749
commit
e26d47cb41
15 changed files with 364 additions and 43 deletions
|
@ -55,8 +55,8 @@
|
||||||
"conflicting_paths_found": "",
|
"conflicting_paths_found": "",
|
||||||
"connected_users": "",
|
"connected_users": "",
|
||||||
"contact_message_label": "",
|
"contact_message_label": "",
|
||||||
"continue_github_merge": "",
|
|
||||||
"contact_us": "",
|
"contact_us": "",
|
||||||
|
"continue_github_merge": "",
|
||||||
"copy": "",
|
"copy": "",
|
||||||
"copy_project": "",
|
"copy_project": "",
|
||||||
"copying": "",
|
"copying": "",
|
||||||
|
@ -179,9 +179,10 @@
|
||||||
"log_entry_maximum_entries_message": "",
|
"log_entry_maximum_entries_message": "",
|
||||||
"log_entry_maximum_entries_title": "",
|
"log_entry_maximum_entries_title": "",
|
||||||
"log_hint_extra_info": "",
|
"log_hint_extra_info": "",
|
||||||
|
"log_viewer_error": "",
|
||||||
|
"logs_and_output_files": "",
|
||||||
"logs_pane_info_message": "",
|
"logs_pane_info_message": "",
|
||||||
"logs_pane_info_message_popup": "",
|
"logs_pane_info_message_popup": "",
|
||||||
"log_viewer_error": "",
|
|
||||||
"main_file_not_found": "",
|
"main_file_not_found": "",
|
||||||
"make_private": "",
|
"make_private": "",
|
||||||
"manage_files_from_your_dropbox_folder": "",
|
"manage_files_from_your_dropbox_folder": "",
|
||||||
|
@ -257,7 +258,7 @@
|
||||||
"project_too_large": "",
|
"project_too_large": "",
|
||||||
"project_too_large_please_reduce": "",
|
"project_too_large_please_reduce": "",
|
||||||
"project_too_much_editable_text": "",
|
"project_too_much_editable_text": "",
|
||||||
"project_url" : "",
|
"project_url": "",
|
||||||
"public": "",
|
"public": "",
|
||||||
"pull_github_changes_into_sharelatex": "",
|
"pull_github_changes_into_sharelatex": "",
|
||||||
"push_sharelatex_changes_to_github": "",
|
"push_sharelatex_changes_to_github": "",
|
||||||
|
@ -269,6 +270,7 @@
|
||||||
"recent_commits_in_github": "",
|
"recent_commits_in_github": "",
|
||||||
"recompile": "",
|
"recompile": "",
|
||||||
"recompile_from_scratch": "",
|
"recompile_from_scratch": "",
|
||||||
|
"recompile_pdf": "",
|
||||||
"reconnect": "",
|
"reconnect": "",
|
||||||
"reference_error_relink_hint": "",
|
"reference_error_relink_hint": "",
|
||||||
"refresh": "",
|
"refresh": "",
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { Button, Dropdown, MenuItem } from 'react-bootstrap'
|
import {
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
MenuItem,
|
||||||
|
OverlayTrigger,
|
||||||
|
Tooltip,
|
||||||
|
} from 'react-bootstrap'
|
||||||
import Icon from '../../../shared/components/icon'
|
import Icon from '../../../shared/components/icon'
|
||||||
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
|
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
@ -6,6 +12,8 @@ import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
|
const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
|
||||||
|
|
||||||
function PdfCompileButton() {
|
function PdfCompileButton() {
|
||||||
const {
|
const {
|
||||||
autoCompile,
|
autoCompile,
|
||||||
|
@ -34,17 +42,28 @@ function PdfCompileButton() {
|
||||||
})}
|
})}
|
||||||
id="pdf-recompile-dropdown"
|
id="pdf-recompile-dropdown"
|
||||||
>
|
>
|
||||||
<Button
|
<OverlayTrigger
|
||||||
className="btn-recompile"
|
placement="bottom"
|
||||||
bsStyle="success"
|
delayShow={500}
|
||||||
onClick={compiling ? stopCompile : startCompile}
|
overlay={
|
||||||
aria-label={compileButtonLabel}
|
<Tooltip id="tooltip-logs-toggle" className="keyboard-tooltip">
|
||||||
|
{t('recompile_pdf')}{' '}
|
||||||
|
<span className="keyboard-shortcut">({modifierKey} + Enter)</span>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icon type="refresh" spin={compiling} />
|
<Button
|
||||||
<span className="toolbar-text toolbar-hide-medium toolbar-hide-small">
|
className="btn-recompile"
|
||||||
{compileButtonLabel}
|
bsStyle="success"
|
||||||
</span>
|
onClick={compiling ? stopCompile : startCompile}
|
||||||
</Button>
|
aria-label={compileButtonLabel}
|
||||||
|
>
|
||||||
|
<Icon type="refresh" spin={compiling} />
|
||||||
|
<span className="toolbar-hide-medium toolbar-hide-small btn-recompile-label">
|
||||||
|
{compileButtonLabel}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</OverlayTrigger>
|
||||||
|
|
||||||
<Dropdown.Toggle
|
<Dropdown.Toggle
|
||||||
aria-label={t('toggle_compile_options_menu')}
|
aria-label={t('toggle_compile_options_menu')}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { memo, useCallback } from 'react'
|
||||||
|
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
|
import { sendMBOnce } from '../../../infrastructure/event-tracking'
|
||||||
|
import { Button } from 'react-bootstrap'
|
||||||
|
import Icon from '../../../shared/components/icon'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
function PdfHybridCodeCheckButton() {
|
||||||
|
const { codeCheckFailed, error, setShowLogs } = usePdfPreviewContext()
|
||||||
|
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
setShowLogs(value => {
|
||||||
|
if (!value) {
|
||||||
|
sendMBOnce('ide-open-logs-once')
|
||||||
|
}
|
||||||
|
|
||||||
|
return !value
|
||||||
|
})
|
||||||
|
}, [setShowLogs])
|
||||||
|
|
||||||
|
if (!codeCheckFailed) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
bsSize="xsmall"
|
||||||
|
bsStyle="danger"
|
||||||
|
disabled={Boolean(error)}
|
||||||
|
className="btn-toggle-logs toolbar-item"
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<Icon type="exclamation-triangle" />
|
||||||
|
<span className="toolbar-text toolbar-hide-small">
|
||||||
|
{t('code_check_failed')}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfHybridCodeCheckButton)
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap'
|
||||||
|
import Icon from '../../../shared/components/icon'
|
||||||
|
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
|
import { memo } from 'react'
|
||||||
|
|
||||||
|
function PdfHybridDownloadButton() {
|
||||||
|
const { pdfDownloadUrl } = usePdfPreviewContext()
|
||||||
|
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayTrigger
|
||||||
|
placement="bottom"
|
||||||
|
overlay={
|
||||||
|
<Tooltip id="tooltip-logs-toggle">
|
||||||
|
{pdfDownloadUrl
|
||||||
|
? t('download_pdf')
|
||||||
|
: t('please_compile_pdf_before_download')}
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
bsStyle="link"
|
||||||
|
disabled={!pdfDownloadUrl}
|
||||||
|
download
|
||||||
|
href={pdfDownloadUrl || '#'}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<Icon type="download" modifier="fw" />
|
||||||
|
</Button>
|
||||||
|
</OverlayTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfHybridDownloadButton)
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { memo, useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Button, Label, OverlayTrigger, Tooltip } from 'react-bootstrap'
|
||||||
|
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
|
import { sendMBOnce } from '../../../infrastructure/event-tracking'
|
||||||
|
import Icon from '../../../shared/components/icon'
|
||||||
|
|
||||||
|
function PdfHybridLogsButton() {
|
||||||
|
const { error, logEntries, setShowLogs, showLogs } = usePdfPreviewContext()
|
||||||
|
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
setShowLogs(value => {
|
||||||
|
if (!value) {
|
||||||
|
sendMBOnce('ide-open-logs-once')
|
||||||
|
}
|
||||||
|
|
||||||
|
return !value
|
||||||
|
})
|
||||||
|
}, [setShowLogs])
|
||||||
|
|
||||||
|
const errorCount = Number(logEntries?.errors?.length)
|
||||||
|
const warningCount = Number(logEntries?.warnings?.length)
|
||||||
|
const totalCount = errorCount + warningCount
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayTrigger
|
||||||
|
placement="bottom"
|
||||||
|
overlay={
|
||||||
|
<Tooltip id="tooltip-logs-toggle">{t('logs_and_output_files')}</Tooltip>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
bsStyle="link"
|
||||||
|
disabled={Boolean(error)}
|
||||||
|
active={showLogs}
|
||||||
|
className="toolbar-item log-btn"
|
||||||
|
onClick={handleClick}
|
||||||
|
style={{ position: 'relative' }}
|
||||||
|
aria-label={showLogs ? t('view_pdf') : t('view_logs')}
|
||||||
|
>
|
||||||
|
<Icon type="file-text-o" modifier="fw" />
|
||||||
|
|
||||||
|
{!showLogs && totalCount > 0 && (
|
||||||
|
<Label bsStyle={errorCount === 0 ? 'warning' : 'danger'}>
|
||||||
|
{totalCount}
|
||||||
|
</Label>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</OverlayTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfHybridLogsButton)
|
|
@ -1,4 +1,3 @@
|
||||||
import Icon from '../../../shared/components/icon'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import PreviewLogsPaneEntry from '../../preview/components/preview-logs-pane-entry'
|
import PreviewLogsPaneEntry from '../../preview/components/preview-logs-pane-entry'
|
||||||
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
|
@ -11,7 +10,8 @@ import PdfDownloadFilesButton from './pdf-download-files-button'
|
||||||
import PdfLogsEntries from './pdf-logs-entries'
|
import PdfLogsEntries from './pdf-logs-entries'
|
||||||
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
import withErrorBoundary from '../../../infrastructure/error-boundary'
|
||||||
import ErrorBoundaryFallback from './error-boundary-fallback'
|
import ErrorBoundaryFallback from './error-boundary-fallback'
|
||||||
import { LogsPaneInfoNotice } from '../../preview/components/preview-logs-pane'
|
import PdfCodeCheckFailedNotice from '../../preview/components/pdf-code-check-failed-notice'
|
||||||
|
import PdfLogsPaneInfoNotice from '../../preview/components/pdf-logs-pane-info-notice'
|
||||||
|
|
||||||
function PdfLogsViewer() {
|
function PdfLogsViewer() {
|
||||||
const {
|
const {
|
||||||
|
@ -27,19 +27,9 @@ function PdfLogsViewer() {
|
||||||
return (
|
return (
|
||||||
<div className="logs-pane">
|
<div className="logs-pane">
|
||||||
<div className="logs-pane-content">
|
<div className="logs-pane-content">
|
||||||
<LogsPaneInfoNotice />
|
<PdfLogsPaneInfoNotice />
|
||||||
{codeCheckFailed && (
|
|
||||||
<div className="log-entry">
|
{codeCheckFailed && <PdfCodeCheckFailedNotice />}
|
||||||
<div className="log-entry-header log-entry-header-error">
|
|
||||||
<div className="log-entry-header-icon-container">
|
|
||||||
<Icon type="exclamation-triangle" modifier="fw" />
|
|
||||||
</div>
|
|
||||||
<h3 className="log-entry-header-title">
|
|
||||||
{t('code_check_failed_explanation')}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{error && <PdfPreviewError error={error} />}
|
{error && <PdfPreviewError error={error} />}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
import { ButtonToolbar } from 'react-bootstrap'
|
||||||
|
import PdfCompileButton from './pdf-compile-button'
|
||||||
|
import PdfExpandButton from './pdf-expand-button'
|
||||||
|
import PdfHybridLogsButton from './pdf-hybrid-logs-button'
|
||||||
|
import PdfHybridDownloadButton from './pdf-hybrid-download-button'
|
||||||
|
import PdfHybridCodeCheckButton from './pdf-hybrid-code-check-button'
|
||||||
|
|
||||||
|
function PdfPreviewHybridToolbar() {
|
||||||
|
return (
|
||||||
|
<ButtonToolbar className="toolbar toolbar-pdf toolbar-pdf-hybrid">
|
||||||
|
<div className="toolbar-pdf-left">
|
||||||
|
<PdfCompileButton />
|
||||||
|
<PdfHybridLogsButton />
|
||||||
|
<PdfHybridDownloadButton />
|
||||||
|
</div>
|
||||||
|
<div className="toolbar-pdf-right">
|
||||||
|
<PdfHybridCodeCheckButton />
|
||||||
|
<PdfExpandButton />
|
||||||
|
</div>
|
||||||
|
</ButtonToolbar>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfPreviewHybridToolbar)
|
|
@ -2,15 +2,20 @@ import { memo, Suspense } from 'react'
|
||||||
import PdfLogsViewer from './pdf-logs-viewer'
|
import PdfLogsViewer from './pdf-logs-viewer'
|
||||||
import PdfViewer from './pdf-viewer'
|
import PdfViewer from './pdf-viewer'
|
||||||
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
import { usePdfPreviewContext } from '../contexts/pdf-preview-context'
|
||||||
import PdfPreviewToolbar from './pdf-preview-toolbar'
|
|
||||||
import LoadingSpinner from '../../../shared/components/loading-spinner'
|
import LoadingSpinner from '../../../shared/components/loading-spinner'
|
||||||
|
import PdfHybridPreviewToolbar from './pdf-preview-hybrid-toolbar'
|
||||||
|
import PdfPreviewToolbar from './pdf-preview-toolbar'
|
||||||
|
|
||||||
|
const newPreviewToolbar = new URLSearchParams(window.location.search).has(
|
||||||
|
'new_preview_toolbar'
|
||||||
|
)
|
||||||
|
|
||||||
function PdfPreviewPane() {
|
function PdfPreviewPane() {
|
||||||
const { showLogs } = usePdfPreviewContext()
|
const { showLogs } = usePdfPreviewContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pdf full-size">
|
<div className="pdf full-size">
|
||||||
<PdfPreviewToolbar />
|
{newPreviewToolbar ? <PdfPreviewToolbar /> : <PdfHybridPreviewToolbar />}
|
||||||
<Suspense fallback={<LoadingPreview />}>
|
<Suspense fallback={<LoadingPreview />}>
|
||||||
<div className="pdf-viewer">
|
<div className="pdf-viewer">
|
||||||
<PdfViewer />
|
<PdfViewer />
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Icon from '../../../shared/components/icon'
|
||||||
|
|
||||||
|
function PdfCodeCheckFailedNotice() {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="log-entry">
|
||||||
|
<div className="log-entry-header log-entry-header-error">
|
||||||
|
<div className="log-entry-header-icon-container">
|
||||||
|
<Icon type="exclamation-triangle" modifier="fw" />
|
||||||
|
</div>
|
||||||
|
<h3 className="log-entry-header-title">
|
||||||
|
{t('code_check_failed_explanation')}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfCodeCheckFailedNotice)
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { memo } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import usePersistedState from '../../../shared/hooks/use-persisted-state'
|
||||||
|
|
||||||
|
function PdfLogsPaneInfoNotice() {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const [dismissed, setDismissed] = usePersistedState(
|
||||||
|
'logs_pane.dismissed_info_notice',
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
if (dismissed) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="log-entry">
|
||||||
|
<div className="log-entry-header log-entry-header-raw">
|
||||||
|
<div className="log-entry-header-icon-container">
|
||||||
|
<span className="info-badge" />
|
||||||
|
</div>
|
||||||
|
<h3 className="log-entry-header-title">
|
||||||
|
{t('logs_pane_info_message')}
|
||||||
|
</h3>
|
||||||
|
<a
|
||||||
|
href="https://forms.gle/zYByeRPcDtA6nDS19"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="log-entry-header-link log-entry-header-link-raw"
|
||||||
|
>
|
||||||
|
<span className="log-entry-header-link-location">
|
||||||
|
{t('give_feedback')}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
className="btn-inline-link log-entry-header-link"
|
||||||
|
type="button"
|
||||||
|
aria-label={t('dismiss')}
|
||||||
|
onClick={() => setDismissed(true)}
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(PdfLogsPaneInfoNotice)
|
|
@ -78,6 +78,16 @@ function PreviewLogEntryContent({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="log-entry-content">
|
<div className="log-entry-content">
|
||||||
|
{formattedContent ? (
|
||||||
|
<div className="log-entry-formatted-content">{formattedContent}</div>
|
||||||
|
) : null}
|
||||||
|
{extraInfoURL ? (
|
||||||
|
<div className="log-entry-content-link">
|
||||||
|
<a href={extraInfoURL} target="_blank" rel="noopener">
|
||||||
|
{t('log_hint_extra_info')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
{rawContent ? (
|
{rawContent ? (
|
||||||
<div className="log-entry-content-raw-container">
|
<div className="log-entry-content-raw-container">
|
||||||
<div {...expandableProps}>
|
<div {...expandableProps}>
|
||||||
|
@ -104,16 +114,6 @@ function PreviewLogEntryContent({
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{formattedContent ? (
|
|
||||||
<div className="log-entry-formatted-content">{formattedContent}</div>
|
|
||||||
) : null}
|
|
||||||
{extraInfoURL ? (
|
|
||||||
<div className="log-entry-content-link">
|
|
||||||
<a href={extraInfoURL} target="_blank" rel="noopener">
|
|
||||||
{t('log_hint_extra_info')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { buildFileList } from '../js/features/pdf-preview/util/file-list'
|
||||||
import PdfLogsViewer from '../js/features/pdf-preview/components/pdf-logs-viewer'
|
import PdfLogsViewer from '../js/features/pdf-preview/components/pdf-logs-viewer'
|
||||||
import examplePdf from './fixtures/storybook-example.pdf'
|
import examplePdf from './fixtures/storybook-example.pdf'
|
||||||
import PdfPreviewError from '../js/features/pdf-preview/components/pdf-preview-error'
|
import PdfPreviewError from '../js/features/pdf-preview/components/pdf-preview-error'
|
||||||
|
import PdfPreviewHybridToolbar from '../js/features/pdf-preview/components/pdf-preview-hybrid-toolbar'
|
||||||
|
|
||||||
setupContext()
|
setupContext()
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ export default {
|
||||||
component: PdfPreview,
|
component: PdfPreview,
|
||||||
subcomponents: {
|
subcomponents: {
|
||||||
PdfPreviewToolbar,
|
PdfPreviewToolbar,
|
||||||
|
PdfPreviewHybridToolbar,
|
||||||
PdfFileList,
|
PdfFileList,
|
||||||
PdfPreviewError,
|
PdfPreviewError,
|
||||||
},
|
},
|
||||||
|
@ -496,6 +498,22 @@ export const Toolbar = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const HybridToolbar = () => {
|
||||||
|
useFetchMock(fetchMock => {
|
||||||
|
mockCompile(fetchMock, 500)
|
||||||
|
mockBuildFile(fetchMock)
|
||||||
|
})
|
||||||
|
|
||||||
|
return withContextRoot(
|
||||||
|
<PdfPreviewProvider>
|
||||||
|
<div className="pdf">
|
||||||
|
<PdfPreviewHybridToolbar />
|
||||||
|
</div>
|
||||||
|
</PdfPreviewProvider>,
|
||||||
|
scope
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const FileList = () => {
|
export const FileList = () => {
|
||||||
const fileList = useMemo(() => {
|
const fileList = useMemo(() => {
|
||||||
return buildFileList(outputFiles)
|
return buildFileList(outputFiles)
|
||||||
|
|
|
@ -137,6 +137,7 @@
|
||||||
background-color: @ol-blue-gray-1;
|
background-color: @ol-blue-gray-1;
|
||||||
border-radius: @border-radius-base;
|
border-radius: @border-radius-base;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
margin-top: @margin-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-entry-content-raw {
|
.log-entry-content-raw {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
.toolbar-small-mixin;
|
.toolbar-small-mixin;
|
||||||
.toolbar-alt-mixin;
|
.toolbar-alt-mixin;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
|
margin-left: 0;
|
||||||
&.changes-to-autocompile {
|
&.changes-to-autocompile {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
#gradient > .striped(@color: rgba(255, 255, 255, 0.1), @angle: -45deg);
|
#gradient > .striped(@color: rgba(255, 255, 255, 0.1), @angle: -45deg);
|
||||||
|
@ -56,6 +57,61 @@
|
||||||
padding-left: @line-height-computed / 4;
|
padding-left: @line-height-computed / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar-pdf-hybrid {
|
||||||
|
.btn:not(.btn-recompile) {
|
||||||
|
display: inline-block;
|
||||||
|
color: @toolbar-btn-color;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 4px 2px;
|
||||||
|
line-height: 1;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
color: @toolbar-btn-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 0.15em 0.6em 0.2em;
|
||||||
|
font-size: 60%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
color: #fff;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 4px 2px;
|
||||||
|
line-height: 1;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.log-btn {
|
||||||
|
margin-right: 3px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: white;
|
||||||
|
background-color: @link-color;
|
||||||
|
box-shadow: @toolbar-icon-btn-hover-boxshadow;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.pdf {
|
.pdf {
|
||||||
background-color: @pdf-bg;
|
background-color: @pdf-bg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ describe('<PdfPreview/>', function () {
|
||||||
await screen.findByRole('button', { name: 'Recompile' })
|
await screen.findByRole('button', { name: 'Recompile' })
|
||||||
|
|
||||||
const logsButton = screen.getByRole('button', {
|
const logsButton = screen.getByRole('button', {
|
||||||
name: 'This project has an error',
|
name: 'View logs',
|
||||||
})
|
})
|
||||||
logsButton.click()
|
logsButton.click()
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ describe('<PdfPreview/>', function () {
|
||||||
|
|
||||||
// show the logs UI
|
// show the logs UI
|
||||||
const logsButton = screen.getByRole('button', {
|
const logsButton = screen.getByRole('button', {
|
||||||
name: 'This project has an error',
|
name: 'View logs',
|
||||||
})
|
})
|
||||||
logsButton.click()
|
logsButton.click()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue