mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
[web] add disconnected state to offline indicator (#35378)
GitOrigin-RevId: 692dc16cee738a8b05353717044a4063c3dd8e8a
This commit is contained in:
+36
-8
@@ -1,6 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||
|
||||
export function OfflineIndicatorContent() {
|
||||
const { t } = useTranslation()
|
||||
@@ -18,22 +19,49 @@ export function OfflineIndicatorContent() {
|
||||
)
|
||||
}
|
||||
|
||||
export function DisconnectedIndicatorContent() {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className="ide-redesign-toolbar-offline-indicator">
|
||||
<MaterialIcon type="wifi_off" />
|
||||
<span>{t('disconnected')}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function OfflineIndicatorVisual({ outOfSync }: { outOfSync: boolean }) {
|
||||
if (outOfSync) {
|
||||
return <DisconnectedIndicatorContent />
|
||||
}
|
||||
return <OfflineIndicatorContent />
|
||||
}
|
||||
|
||||
function OfflineIndicatorStatus({ outOfSync }: { outOfSync: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
if (outOfSync) {
|
||||
return <span>{t('disconnected')}</span>
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<span>{t('you_re_offline')}</span>
|
||||
<span>{t('changes_saved_in_browser_sync_when_online')}</span>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function OfflineIndicator({
|
||||
isOffline,
|
||||
}: {
|
||||
isOffline: boolean
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const { outOfSync } = useIdeReactContext()
|
||||
// The live region div below must stay mounted at all times so screen
|
||||
// readers announce its contents when the offline state changes.
|
||||
return (
|
||||
<>
|
||||
{isOffline && <OfflineIndicatorContent />}
|
||||
{isOffline && <OfflineIndicatorVisual outOfSync={outOfSync} />}
|
||||
<div className="visually-hidden" role="status">
|
||||
{isOffline && (
|
||||
<>
|
||||
<span>{t('you_re_offline')}</span>
|
||||
<span>{t('changes_saved_in_browser_sync_when_online')}</span>
|
||||
</>
|
||||
)}
|
||||
{isOffline && <OfflineIndicatorStatus outOfSync={outOfSync} />}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
+51
-3
@@ -1,19 +1,47 @@
|
||||
import OfflineIndicator from '@/features/ide-react/components/toolbar/offline-indicator'
|
||||
import { IdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||
|
||||
const mount = ({
|
||||
isOffline = false,
|
||||
outOfSync = false,
|
||||
}: {
|
||||
isOffline?: boolean
|
||||
outOfSync?: boolean
|
||||
} = {}) => {
|
||||
cy.mount(
|
||||
<IdeReactContext.Provider
|
||||
value={{
|
||||
projectId: '',
|
||||
eventEmitter: {} as any,
|
||||
startedFreeTrial: false,
|
||||
setStartedFreeTrial: () => {},
|
||||
reportError: () => {},
|
||||
projectJoined: true,
|
||||
permissionsLevel: 'readAndWrite',
|
||||
setPermissionsLevel: () => {},
|
||||
outOfSync,
|
||||
setOutOfSync: () => {},
|
||||
}}
|
||||
>
|
||||
<OfflineIndicator isOffline={isOffline} />
|
||||
</IdeReactContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
describe('<OfflineIndicator />', function () {
|
||||
it('renders an empty live region when online', function () {
|
||||
cy.mount(<OfflineIndicator isOffline={false} />)
|
||||
mount({ isOffline: false })
|
||||
cy.findByText('You’re offline').should('not.exist')
|
||||
cy.findByRole('status').should('be.empty')
|
||||
})
|
||||
|
||||
it('shows the offline indicator when offline', function () {
|
||||
cy.mount(<OfflineIndicator isOffline />)
|
||||
mount({ isOffline: true })
|
||||
cy.findAllByText('You’re offline').first().should('be.visible')
|
||||
})
|
||||
|
||||
it('announces the offline status to screen readers via a live region', function () {
|
||||
cy.mount(<OfflineIndicator isOffline />)
|
||||
mount({ isOffline: true })
|
||||
cy.findByRole('status').within(() => {
|
||||
cy.findByText('You’re offline').should('exist')
|
||||
cy.findByText(
|
||||
@@ -21,4 +49,24 @@ describe('<OfflineIndicator />', function () {
|
||||
).should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
it('shows "Disconnected" without a tooltip when out of sync', function () {
|
||||
mount({ isOffline: true, outOfSync: true })
|
||||
cy.findAllByText('Disconnected')
|
||||
.first()
|
||||
.should('be.visible')
|
||||
.trigger('mouseover')
|
||||
cy.get('#tooltip-offline-indicator-tooltip').should('not.exist')
|
||||
cy.findByText('You’re offline').should('not.exist')
|
||||
})
|
||||
|
||||
it('announces "Disconnected" to screen readers when out of sync', function () {
|
||||
mount({ isOffline: true, outOfSync: true })
|
||||
cy.findByRole('status').within(() => {
|
||||
cy.findByText('Disconnected').should('exist')
|
||||
cy.findByText(
|
||||
'Your changes are saved in the browser. We’ll sync your work when you’re back online.'
|
||||
).should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user