[MM-63224] Add incompatible server screen (#3348)

* [MM-63224] Add incompatible server screen

* Fixed issue where init isn't called on no server case

* Amend check
This commit is contained in:
Devin Binnie
2025-02-21 10:17:49 -05:00
committed by GitHub
parent 2cf4aaaa02
commit 6fa5508588
17 changed files with 286 additions and 68 deletions

View File

@@ -0,0 +1,90 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {FormattedMessage} from 'react-intl';
import ErrorView from './ErrorView';
type Props = {
darkMode: boolean;
appName?: string;
url?: string;
errorInfo?: string;
handleLink: () => void;
};
export default function ConnectionErrorView({darkMode, appName, url, handleLink, errorInfo}: Props) {
const header = (
<FormattedMessage
id='renderer.components.errorView.cannotConnectToThisServer'
defaultMessage="Couldn't connect to this server"
/>
);
const subHeader = (
<>
<FormattedMessage
id='renderer.components.errorView.havingTroubleConnecting'
defaultMessage={'We\'re having trouble connecting to this {appName} server. We\'ll keep trying to establish a connection.'}
values={{
appName,
}}
/>
<br/>
<FormattedMessage
id='renderer.components.errorView.refreshThenVerify'
defaultMessage="If refreshing this page (Ctrl+R or Command+R) doesn't help, please check the following:"
/>
</>
);
const bullets = (
<>
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.computerIsConnected'
defaultMessage='Ensure your computer is connected to the internet.'
/>
</li>
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.urlIsCorrect.appNameIsCorrect'
defaultMessage='Verify that the URL <link>{url}</link> is correct.'
values={{
appName,
url,
link: (msg: React.ReactNode) => (
<a
onClick={handleLink}
href='#'
>
{msg}
</a>
),
}}
/>
</li>
</>
);
const contactAdmin = (
<FormattedMessage
id='renderer.components.errorView.contactAdmin'
defaultMessage='If the issue persists, please contact your admin'
/>
);
return (
<ErrorView
darkMode={darkMode}
header={header}
subHeader={subHeader}
bullets={bullets}
contactAdmin={contactAdmin}
handleLink={handleLink}
errorInfo={errorInfo}
url={url}
/>
);
}

View File

@@ -12,72 +12,47 @@ import AlertImage from './Images/alert';
import 'renderer/css/components/ErrorView.scss';
type Props = {
type ErrorViewProps = {
darkMode: boolean;
header: React.ReactNode;
subHeader: React.ReactNode;
bullets: React.ReactNode;
contactAdmin: React.ReactNode;
errorInfo?: string;
url?: string;
appName?: string;
handleLink: () => void;
};
export default function ErrorView(props: Props) {
export default function ErrorView({
darkMode,
header,
subHeader,
bullets,
contactAdmin,
errorInfo,
url,
handleLink,
}: ErrorViewProps) {
return (
<div className={classNames('ErrorView', {darkMode: props.darkMode})}>
<div className={classNames('ErrorView', {darkMode})}>
<AlertImage/>
<span className='ErrorView-header'>
<FormattedMessage
id='renderer.components.errorView.cannotConnectToThisServer'
defaultMessage="Couldn't connect to this server"
/>
{header}
</span>
<span>
<FormattedMessage
id='renderer.components.errorView.havingTroubleConnecting'
defaultMessage={'We\'re having trouble connecting to this {appName} server. We\'ll keep trying to establish a connection.'}
values={{
appName: props.appName,
}}
/>
<br/>
<FormattedMessage
id='renderer.components.errorView.refreshThenVerify'
defaultMessage="If refreshing this page (Ctrl+R or Command+R) doesn't help, please check the following:"
/>
{subHeader}
</span>
<ul className='ErrorView-bullets'>
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.computerIsConnected'
defaultMessage='Ensure your computer is connected to the internet.'
/>
</li>
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.urlIsCorrect.appNameIsCorrect'
defaultMessage='Verify that the URL <link>{url}</link> is correct.'
values={{
appName: props.appName,
url: props.url,
link: (msg: React.ReactNode) => (
<a
onClick={props.handleLink}
href='#'
>
{msg}
</a>
),
}}
/>
</li>
{bullets}
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.webContentsView.canReachFromBrowserWindow'
defaultMessage='Try opening <link>{url}</link> in a browser window.'
values={{
url: props.url,
url,
link: (msg: React.ReactNode) => (
<a
onClick={props.handleLink}
onClick={handleLink}
href='#'
>
{msg}
@@ -88,13 +63,10 @@ export default function ErrorView(props: Props) {
</li>
</ul>
<span>
<FormattedMessage
id='renderer.components.errorView.contactAdmin'
defaultMessage='If the issue persists, please contact your admin'
/>
{contactAdmin}
</span>
<span className='ErrorView-techInfo'>
{props.errorInfo}
{errorInfo}
</span>
</div>
);

View File

@@ -0,0 +1,80 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {FormattedMessage} from 'react-intl';
import ErrorView from './ErrorView';
type Props = {
darkMode: boolean;
appName?: string;
url?: string;
handleLink: () => void;
handleUpgradeLink: () => void;
};
export default function IncompatibleErrorView({darkMode, appName, url, handleLink, handleUpgradeLink}: Props) {
const header = (
<FormattedMessage
id='renderer.components.errorView.incompatibleServerVersion'
defaultMessage='Incompatible server version'
/>
);
const subHeader = (
<>
<FormattedMessage
id='renderer.components.errorView.serverVersionIsIncompatible'
defaultMessage={'The {appName} Server you are accessing is incompatible with this version of the {appName} Desktop App. To connect to this server, please try the following:'}
values={{
appName,
}}
/>
</>
);
const bullets = (
<>
<li>
<FormattedMessage
id='renderer.components.errorView.troubleshooting.downgradeApp'
defaultMessage='<link>Downgrade your {appName} Desktop App</link> to version v5.10 or earlier.'
values={{
appName,
link: (msg: React.ReactNode) => (
<a
href='#'
onClick={handleUpgradeLink}
>
{msg}
</a>
),
}}
/>
</li>
</>
);
const contactAdmin = (
<FormattedMessage
id='renderer.components.errorView.contactAdminUpgrade'
defaultMessage='If the issue persists, contact your {appName} Administrator or IT department to upgrade this {appName} Server.'
values={{
appName,
}}
/>
);
return (
<ErrorView
darkMode={darkMode}
header={header}
subHeader={subHeader}
bullets={bullets}
contactAdmin={contactAdmin}
handleLink={handleLink}
url={url}
/>
);
}

View File

@@ -11,9 +11,10 @@ import {injectIntl} from 'react-intl';
import type {UniqueView, UniqueServer} from 'types/config';
import type {DownloadedItems} from 'types/downloads';
import ConnectionErrorView from './ConnectionErrorView';
import DeveloperModeIndicator from './DeveloperModeIndicator';
import DownloadsDropdownButton from './DownloadsDropdown/DownloadsDropdownButton';
import ErrorView from './ErrorView';
import IncompatibleErrorView from './IncompatibleErrorView';
import ServerDropdownButton from './ServerDropdownButton';
import TabBar from './TabBar';
@@ -28,6 +29,7 @@ enum Status {
RETRY = -1,
FAILED = 0,
NOSERVERS = -2,
INCOMPATIBLE = -3,
}
type Props = {
@@ -61,7 +63,7 @@ type TabViewStatus = {
status: Status;
extra?: {
url: string;
error: string;
error?: string;
};
}
@@ -186,6 +188,17 @@ class MainPage extends React.PureComponent<Props, State> {
this.updateTabStatus(viewId, statusValue);
});
window.desktop.onLoadIncompatibleServer((viewId, loadUrl) => {
console.error(`${viewId}: tried to load incompatible server`);
const statusValue = {
status: Status.INCOMPATIBLE,
extra: {
url: loadUrl,
},
};
this.updateTabStatus(viewId, statusValue);
});
// can't switch tabs sequentially for some reason...
window.desktop.onSetActiveView(this.setActiveView);
@@ -507,7 +520,7 @@ class MainPage extends React.PureComponent<Props, State> {
switch (tabStatus.status) {
case Status.FAILED:
component = (
<ErrorView
<ConnectionErrorView
darkMode={this.props.darkMode}
errorInfo={tabStatus.extra?.error}
url={tabStatus.extra ? tabStatus.extra.url : ''}
@@ -515,6 +528,16 @@ class MainPage extends React.PureComponent<Props, State> {
handleLink={this.openServerExternally}
/>);
break;
case Status.INCOMPATIBLE:
component = (
<IncompatibleErrorView
darkMode={this.props.darkMode}
url={tabStatus.extra ? tabStatus.extra.url : ''}
appName={this.props.appName}
handleLink={this.openServerExternally}
handleUpgradeLink={() => window.desktop.openServerUpgradeLink()}
/>);
break;
case Status.LOADING:
case Status.RETRY:
case Status.DONE: