Merge pull request #35457 from overleaf/mj-more-disabled-buttons

[web] Disable compilation buttons during network stall

GitOrigin-RevId: c94a77fea7171c6e9ff4fa9f30e9475474900845
This commit is contained in:
Mathias Jakobsen
2026-09-17 11:28:24 +00:00
committed by Copybot
parent f86334750e
commit 6f06df61a6
7 changed files with 56 additions and 13 deletions
@@ -9,7 +9,8 @@ const modifierKey = /Mac/i.test(navigator.platform) ? 'Cmd' : 'Ctrl'
function DetachCompileButton() {
const { t } = useTranslation()
const { compiling, startCompile, hasChanges } = useDetachCompileContext()
const { compiling, startCompile, hasChanges, isNetworkStalled } =
useDetachCompileContext()
const tooltipElement = (
<>
@@ -29,10 +30,11 @@ function DetachCompileButton() {
<OLButton
variant="primary"
onClick={() => startCompile()}
disabled={compiling}
disabled={compiling || isNetworkStalled}
className={classnames('detach-compile-button', {
'btn-striped-animated': hasChanges,
'detach-compile-button-disabled': compiling,
'detach-compile-button-disabled': compiling || isNetworkStalled,
'compile-button-network-stalled': isNetworkStalled,
})}
size="sm"
isLoading={compiling}
@@ -51,6 +51,7 @@ function PdfCompileButton() {
startCompile,
stopCompile,
recompileFromScratch,
isNetworkStalled,
} = useCompileContext()
const { enableStopOnFirstError, disableStopOnFirstError } =
useStopOnFirstError({ eventSource: 'dropdown' })
@@ -93,6 +94,7 @@ function PdfCompileButton() {
{
'detach-compile-button-animate': animateCompileDropdownArrow,
'btn-striped-animated': hasChanges,
'compile-button-network-stalled': isNetworkStalled,
},
'no-left-border',
'dropdown-button-toggle',
@@ -104,6 +106,7 @@ function PdfCompileButton() {
'compile-button',
{
'btn-striped-animated': hasChanges,
'compile-button-network-stalled': isNetworkStalled,
}
)
@@ -113,7 +116,7 @@ function PdfCompileButton() {
id: 'compile',
handler: () => startCompile(),
label: t('recompile'),
disabled: compiling,
disabled: compiling || isNetworkStalled,
},
{
id: 'stop-compile',
@@ -125,10 +128,17 @@ function PdfCompileButton() {
id: 'recompile-from-scratch',
handler: fromScratchWithEvent,
label: t('recompile_from_scratch'),
disabled: compiling,
disabled: compiling || isNetworkStalled,
},
],
[startCompile, t, compiling, stopCompile, fromScratchWithEvent]
[
startCompile,
t,
compiling,
stopCompile,
fromScratchWithEvent,
isNetworkStalled,
]
)
return (
@@ -144,7 +154,7 @@ function PdfCompileButton() {
>
<OLButton
variant="primary"
disabled={compiling}
disabled={compiling || isNetworkStalled}
isLoading={compiling}
onClick={() => startCompile()}
className={buttonClassName}
@@ -161,6 +171,7 @@ function PdfCompileButton() {
id="pdf-recompile-dropdown"
size="sm"
aria-label={t('toggle_compile_options_menu')}
disabled={isNetworkStalled}
className={dropdownToggleClassName}
/>
@@ -279,8 +290,8 @@ function PdfCompileButton() {
<OLDropdownItem
as="button"
onClick={fromScratchWithEvent}
disabled={compiling}
aria-disabled={compiling}
disabled={compiling || isNetworkStalled}
aria-disabled={compiling || isNetworkStalled}
>
{t('recompile_from_scratch')}
</OLDropdownItem>
@@ -34,16 +34,19 @@ export const startCompileKeypress = (
export default function useCompileTriggers(
startCompile: (...args: any[]) => Promise<void>,
setChangedAt: (...args: any[]) => void
setChangedAt: (...args: any[]) => void,
networkStalled: boolean
) {
const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
if (startCompileKeypress(event)) {
event.preventDefault()
startCompile()
if (!networkStalled) {
startCompile()
}
}
},
[startCompile]
[startCompile, networkStalled]
)
const handleStartCompile = useCallback(() => {
@@ -76,6 +76,7 @@ export const DetachCompileProvider: FC<React.PropsWithChildren> = ({
darkModePdf: _darkModePdf,
setDarkModePdf: _setDarkModePdf,
activeOverallTheme: _activeOverallTheme,
isNetworkStalled: _isNetworkStalled,
} = localCompileContext
const [animateCompileDropdownArrow] = useDetachStateWatcher(
@@ -410,7 +411,14 @@ export const DetachCompileProvider: FC<React.PropsWithChildren> = ({
'detached'
)
useCompileTriggers(startCompile, setChangedAt)
const [isNetworkStalled] = useDetachStateWatcher(
'isNetworkStalled',
_isNetworkStalled,
'detacher',
'detached'
)
useCompileTriggers(startCompile, setChangedAt, isNetworkStalled)
useLogEvents(setShowLogs)
const value = useMemo(
@@ -473,6 +481,7 @@ export const DetachCompileProvider: FC<React.PropsWithChildren> = ({
darkModePdf,
setDarkModePdf,
activeOverallTheme,
isNetworkStalled,
}),
[
animateCompileDropdownArrow,
@@ -531,6 +540,7 @@ export const DetachCompileProvider: FC<React.PropsWithChildren> = ({
darkModePdf,
setDarkModePdf,
activeOverallTheme,
isNetworkStalled,
]
)
@@ -60,6 +60,7 @@ import {
ActiveOverallTheme,
useActiveOverallTheme,
} from '../hooks/use-active-overall-theme'
import useIsNetworkStalled from '@/features/ide-react/hooks/use-is-network-stalled'
type PdfFile = Record<string, any>
@@ -132,6 +133,7 @@ export type CompileContext = {
darkModePdf: boolean | undefined
setDarkModePdf: (value: boolean) => void
activeOverallTheme: ActiveOverallTheme
isNetworkStalled: boolean
}
export const LocalCompileContext = createContext<CompileContext | undefined>(
@@ -156,6 +158,7 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
const { fileTreeData } = useFileTreeData()
const { findEntityByPath } = useFileTreePathContext()
const getRootDocInfo = useRootDoc()
const isNetworkStalled = useIsNetworkStalled()
// whether a compile is in progress
const [compiling, setCompiling] = useState(false)
@@ -822,6 +825,7 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
darkModePdf,
setDarkModePdf,
activeOverallTheme,
isNetworkStalled,
}),
[
animateCompileDropdownArrow,
@@ -879,6 +883,7 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
darkModePdf,
setDarkModePdf,
activeOverallTheme,
isNetworkStalled,
]
)
@@ -88,6 +88,17 @@
}
}
.compile-button,
.compile-dropdown-toggle,
.detach-compile-button {
&.compile-button-network-stalled {
background-color: var(--bg-disabled-themed) !important;
color: var(--content-disabled-themed) !important;
pointer-events: auto;
cursor: not-allowed;
}
}
.toolbar-pdf-left,
.toolbar-pdf-right,
.toolbar-pdf-controls {
@@ -753,6 +753,7 @@ const BASE_COMPILE_CONTEXT_MOCK = {
darkModePdf: false,
setDarkModePdf: () => {},
activeOverallTheme: 'light',
isNetworkStalled: false,
} as const
const makeDetachCompileProvider = (mockCompileOnLoad: boolean = false) => {