From 1e1a8c0bb30b7b93876a6ae06b2fe2d32dd8e0c8 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Mon, 15 Jul 2024 10:12:58 +0100 Subject: [PATCH] Add translated messages for more connection error states (#19392) GitOrigin-RevId: 981de624f3964ebe3ff1f0c751fcef9158864d5e --- .../web/app/views/project/editor/meta.pug | 4 +++ .../ide-react/components/loading-error.tsx | 26 +++++++++++++++ .../features/ide-react/components/loading.tsx | 23 ++++--------- .../connection/types/connection-state.ts | 2 +- services/web/frontend/js/utils/meta.ts | 3 ++ .../stories/loading/loading-error.stories.tsx | 33 +++++++++++++++++++ .../stories/loading/loading.stories.tsx | 23 +++++++++++++ services/web/locales/en.json | 2 ++ 8 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 services/web/frontend/js/features/ide-react/components/loading-error.tsx create mode 100644 services/web/frontend/stories/loading/loading-error.stories.tsx create mode 100644 services/web/frontend/stories/loading/loading.stories.tsx diff --git a/services/web/app/views/project/editor/meta.pug b/services/web/app/views/project/editor/meta.pug index e639a57a48..37d7a06461 100644 --- a/services/web/app/views/project/editor/meta.pug +++ b/services/web/app/views/project/editor/meta.pug @@ -37,8 +37,12 @@ meta(name="ol-hasTrackChangesFeature", data-type="boolean" content=hasTrackChang meta(name="ol-inactiveTutorials", data-type="json" content=user.inactiveTutorials) meta(name="ol-projectTags" data-type="json" content=projectTags) meta(name="ol-linkSharingWarning" data-type="boolean" content=linkSharingWarning) + +// translations for the loading page, before i18n has loaded in the client meta(name="ol-loadingText", data-type="string" content=translate("loading")) +meta(name="ol-translationIoNotLoaded", data-type="string" content=translate("could_not_connect_to_websocket_server")) meta(name="ol-translationLoadErrorMessage", data-type="string" content=translate("could_not_load_translations")) +meta(name="ol-translationUnableToJoin", data-type="string" content=translate("could_not_connect_to_collaboration_server")) if (settings.overleaf != null) meta(name="ol-overallThemes" data-type="json" content=overallThemes) diff --git a/services/web/frontend/js/features/ide-react/components/loading-error.tsx b/services/web/frontend/js/features/ide-react/components/loading-error.tsx new file mode 100644 index 0000000000..2e73e7dd56 --- /dev/null +++ b/services/web/frontend/js/features/ide-react/components/loading-error.tsx @@ -0,0 +1,26 @@ +import { FC } from 'react' +import { ConnectionError } from '@/features/ide-react/connection/types/connection-state' +import getMeta from '@/utils/meta' + +// NOTE: i18n translations might not be loaded in the client at this point, +// so these translations have to be loaded from meta tags +export const LoadingError: FC<{ + connectionStateError: ConnectionError | '' + i18nError?: Error +}> = ({ connectionStateError, i18nError }) => { + if (connectionStateError) { + switch (connectionStateError) { + case 'io-not-loaded': + return <>{getMeta('ol-translationIoNotLoaded')} + + case 'unable-to-join': + return <>{getMeta('ol-translationUnableToJoin')} + } + } + + if (i18nError) { + return <>{getMeta('ol-translationLoadErrorMessage')} + } + + return null +} diff --git a/services/web/frontend/js/features/ide-react/components/loading.tsx b/services/web/frontend/js/features/ide-react/components/loading.tsx index 0d6e6815e2..cddab30c0e 100644 --- a/services/web/frontend/js/features/ide-react/components/loading.tsx +++ b/services/web/frontend/js/features/ide-react/components/loading.tsx @@ -4,6 +4,7 @@ import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' import getMeta from '@/utils/meta' import { useConnectionContext } from '../context/connection-context' import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context' +import { LoadingError } from './loading-error' type Part = 'initial' | 'render' | 'connection' | 'translations' | 'project' @@ -54,21 +55,6 @@ export const Loading: FC<{ } }, [projectJoined]) - const getLoadingScreenError = (): string => { - if (connectionState.error) { - // NOTE: translations not ready yet - return connectionState.error === 'io-not-loaded' - ? 'Could not connect to websocket server :(' - : connectionState.error - } - - if (i18n.error) { - return getMeta('ol-translationLoadErrorMessage') - } - - return '' - } - // Use loading text from the server, because i18n will not be ready initially const label = getMeta('ol-loadingText') @@ -82,7 +68,12 @@ export const Loading: FC<{ hasError={hasError} /> {hasError && ( -

{getLoadingScreenError()}

+

+ +

)} ) diff --git a/services/web/frontend/js/features/ide-react/connection/types/connection-state.ts b/services/web/frontend/js/features/ide-react/connection/types/connection-state.ts index 6b0f4f45d0..e95bd13442 100644 --- a/services/web/frontend/js/features/ide-react/connection/types/connection-state.ts +++ b/services/web/frontend/js/features/ide-react/connection/types/connection-state.ts @@ -1,4 +1,5 @@ export type ConnectionError = + | 'io-not-loaded' | 'maintenance' | 'not-logged-in' | 'out-of-sync' @@ -7,7 +8,6 @@ export type ConnectionError = | 'rate-limited' | 'unable-to-connect' | 'unable-to-join' - | 'io-not-loaded' export type ConnectionState = { readyState: WebSocket['CONNECTING'] | WebSocket['OPEN'] | WebSocket['CLOSED'] diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index 87c802c8b4..188cc876de 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -191,6 +191,9 @@ export interface Meta { 'ol-teamInvites': TeamInvite[] 'ol-thirdPartyIds': ThirdPartyIds 'ol-translationLoadErrorMessage': string + 'ol-translationIoNotLoaded': string + 'ol-translationUnableToJoin': string + 'ol-translationMaintenance': string 'ol-useShareJsHash': boolean 'ol-user': User 'ol-userAffiliations': Affiliation[] diff --git a/services/web/frontend/stories/loading/loading-error.stories.tsx b/services/web/frontend/stories/loading/loading-error.stories.tsx new file mode 100644 index 0000000000..753f4e0207 --- /dev/null +++ b/services/web/frontend/stories/loading/loading-error.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { LoadingError } from '@/features/ide-react/components/loading-error' + +const meta: Meta = { + title: 'Loading Page / Loading Error', + component: LoadingError, +} + +export default meta + +type Story = StoryObj + +export const IoNotLoaded: Story = { + render: () => { + window.metaAttributesCache.set( + 'ol-translationIoNotLoaded', + 'Could not connect to the WebSocket server' + ) + + return + }, +} + +export const UnableToJoin: Story = { + render: () => { + window.metaAttributesCache.set( + 'ol-translationUnableToJoin', + 'Could not connect to the collaboration server' + ) + + return + }, +} diff --git a/services/web/frontend/stories/loading/loading.stories.tsx b/services/web/frontend/stories/loading/loading.stories.tsx new file mode 100644 index 0000000000..944342a082 --- /dev/null +++ b/services/web/frontend/stories/loading/loading.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { Loading } from '@/features/ide-react/components/loading' +import { EditorProviders } from '../../../test/frontend/helpers/editor-providers' + +const meta: Meta = { + title: 'Loading Page / Loading', + component: Loading, + argTypes: { + setLoaded: { action: 'setLoaded' }, + }, +} + +export default meta + +type Story = StoryObj + +export const LoadingPage: Story = { + render: args => ( + + + + ), +} diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 7667c51bfc..6a9af6d826 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -349,6 +349,8 @@ "copy_project": "Copy Project", "copy_response": "Copy response", "copying": "Copying", + "could_not_connect_to_collaboration_server": "Could not connect to collaboration server", + "could_not_connect_to_websocket_server": "Could not connect to WebSocket server", "could_not_load_translations": "Could not load translations", "country": "Country", "country_flag": "__country__ country flag",