Decouple RelinkDialog from NetworkStatusDialog

This commit is contained in:
Josh Perez 2020-04-16 15:20:52 -04:00 committed by GitHub
parent 0970c73310
commit 4dc7631851
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 37 deletions

View File

@ -37,6 +37,7 @@ export interface PropsType {
renderMainHeader: () => JSX.Element;
renderMessageSearchResult: (id: string) => JSX.Element;
renderNetworkStatus: () => JSX.Element;
renderRelinkDialog: () => JSX.Element;
renderUpdateDialog: () => JSX.Element;
}
@ -394,6 +395,7 @@ export class LeftPane extends React.Component<PropsType> {
renderExpiredBuildDialog,
renderMainHeader,
renderNetworkStatus,
renderRelinkDialog,
renderUpdateDialog,
showArchived,
} = this.props;
@ -408,6 +410,7 @@ export class LeftPane extends React.Component<PropsType> {
{renderExpiredBuildDialog()}
{renderNetworkStatus()}
{renderUpdateDialog()}
{renderRelinkDialog()}
{this.renderList()}
</div>
)}

View File

@ -16,9 +16,7 @@ const defaultProps = {
hasNetworkDialog: true,
i18n,
isOnline: true,
isRegistrationDone: true,
socketStatus: 0,
relinkDevice: action('relink-device'),
manualReconnect: action('manual-reconnect'),
withinConnectingGracePeriod: false,
};
@ -42,19 +40,6 @@ const permutations = [
socketStatus: 3,
},
},
{
title: 'Unlinked (online)',
props: {
isRegistrationDone: false,
},
},
{
title: 'Unlinked (offline)',
props: {
isOnline: false,
isRegistrationDone: false,
},
},
{
title: 'Offline',
props: {
@ -67,7 +52,6 @@ storiesOf('Components/NetworkStatus', module)
.add('Knobs Playground', () => {
const hasNetworkDialog = boolean('hasNetworkDialog', true);
const isOnline = boolean('isOnline', true);
const isRegistrationDone = boolean('isRegistrationDone', true);
const socketStatus = select(
'socketStatus',
{
@ -84,7 +68,6 @@ storiesOf('Components/NetworkStatus', module)
{...defaultProps}
hasNetworkDialog={hasNetworkDialog}
isOnline={isOnline}
isRegistrationDone={isRegistrationDone}
socketStatus={socketStatus}
/>
);

View File

@ -8,8 +8,6 @@ const FIVE_SECONDS = 5 * 1000;
export interface PropsType extends NetworkStateType {
hasNetworkDialog: boolean;
i18n: LocalizerType;
isRegistrationDone: boolean;
relinkDevice: () => void;
manualReconnect: () => void;
}
@ -39,9 +37,7 @@ export const NetworkStatus = ({
hasNetworkDialog,
i18n,
isOnline,
isRegistrationDone,
socketStatus,
relinkDevice,
manualReconnect,
}: PropsType): JSX.Element | null => {
if (!hasNetworkDialog) {
@ -76,17 +72,7 @@ export const NetworkStatus = ({
</div>
);
if (!isRegistrationDone) {
return renderDialog({
renderActionableButton: (): JSX.Element => (
<div className="module-left-pane-dialog__actions">
<button onClick={relinkDevice}>{i18n('relink')}</button>
</div>
),
subtext: i18n('unlinkedWarning'),
title: i18n('unlinked'),
});
} else if (isConnecting) {
if (isConnecting) {
return renderDialog({
subtext: i18n('connectingHangOn'),
title: i18n('connecting'),

View File

@ -0,0 +1,58 @@
import * as React from 'react';
import { RelinkDialog } from './RelinkDialog';
// @ts-ignore
import { setup as setupI18n } from '../../js/modules/i18n';
// @ts-ignore
import enMessages from '../../_locales/en/messages.json';
import { storiesOf } from '@storybook/react';
import { boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
hasNetworkDialog: false,
i18n,
isRegistrationDone: true,
relinkDevice: action('relink-device'),
};
const permutations = [
{
title: 'Unlinked (online)',
props: {
isRegistrationDone: false,
},
},
{
title: 'Unlinked (offline)',
props: {
hasNetworkDialog: true,
isRegistrationDone: false,
},
},
];
storiesOf('Components/RelinkDialog', module)
.add('Knobs Playground', () => {
const hasNetworkDialog = boolean('hasNetworkDialog', false);
const isRegistrationDone = boolean('isRegistrationDone', false);
return (
<RelinkDialog
{...defaultProps}
hasNetworkDialog={hasNetworkDialog}
isRegistrationDone={isRegistrationDone}
/>
);
})
.add('Iterations', () => {
return permutations.map(({ props, title }) => (
<>
<h3>{title}</h3>
<RelinkDialog {...defaultProps} {...props} />
</>
));
});

View File

@ -0,0 +1,33 @@
import React from 'react';
import { LocalizerType } from '../types/Util';
export interface PropsType {
hasNetworkDialog: boolean;
i18n: LocalizerType;
isRegistrationDone: boolean;
relinkDevice: () => void;
}
export const RelinkDialog = ({
hasNetworkDialog,
i18n,
isRegistrationDone,
relinkDevice,
}: PropsType): JSX.Element | null => {
if (hasNetworkDialog || isRegistrationDone) {
return null;
}
return (
<div className="module-left-pane-dialog module-left-pane-dialog--warning">
<div className="module-left-pane-dialog__message">
<h3>{i18n('unlinked')}</h3>
<span>{i18n('unlinkedWarning')}</span>
</div>
<div className="module-left-pane-dialog__actions">
<button onClick={relinkDevice}>{i18n('relink')}</button>
</div>
</div>
);
};

View File

@ -16,6 +16,7 @@ import { SmartExpiredBuildDialog } from './ExpiredBuildDialog';
import { SmartMainHeader } from './MainHeader';
import { SmartMessageSearchResult } from './MessageSearchResult';
import { SmartNetworkStatus } from './NetworkStatus';
import { SmartRelinkDialog } from './RelinkDialog';
import { SmartUpdateDialog } from './UpdateDialog';
// Workaround: A react component's required properties are filtering up through connect()
@ -25,6 +26,7 @@ const FilteredSmartMessageSearchResult = SmartMessageSearchResult as any;
const FilteredSmartNetworkStatus = SmartNetworkStatus as any;
const FilteredSmartUpdateDialog = SmartUpdateDialog as any;
const FilteredSmartExpiredBuildDialog = SmartExpiredBuildDialog as any;
const FilteredSmartRelinkDialog = SmartRelinkDialog as any;
function renderExpiredBuildDialog(): JSX.Element {
return <FilteredSmartExpiredBuildDialog />;
@ -35,12 +37,15 @@ function renderMainHeader(): JSX.Element {
function renderMessageSearchResult(id: string): JSX.Element {
return <FilteredSmartMessageSearchResult id={id} />;
}
function renderUpdateDialog(): JSX.Element {
return <FilteredSmartUpdateDialog />;
}
function renderNetworkStatus(): JSX.Element {
return <FilteredSmartNetworkStatus />;
}
function renderRelinkDialog(): JSX.Element {
return <FilteredSmartRelinkDialog />;
}
function renderUpdateDialog(): JSX.Element {
return <FilteredSmartUpdateDialog />;
}
const mapStateToProps = (state: StateType) => {
const showSearch = isSearching(state);
@ -59,6 +64,7 @@ const mapStateToProps = (state: StateType) => {
renderMainHeader,
renderMessageSearchResult,
renderNetworkStatus,
renderRelinkDialog,
renderUpdateDialog,
};
};

View File

@ -4,14 +4,12 @@ import { NetworkStatus } from '../../components/NetworkStatus';
import { StateType } from '../reducer';
import { getIntl } from '../selectors/user';
import { hasNetworkDialog } from '../selectors/network';
import { isDone } from '../../util/registration';
const mapStateToProps = (state: StateType) => {
return {
...state.network,
hasNetworkDialog: hasNetworkDialog(state),
i18n: getIntl(state),
isRegistrationDone: isDone(),
};
};

View File

@ -0,0 +1,19 @@
import { connect } from 'react-redux';
import { mapDispatchToProps } from '../actions';
import { RelinkDialog } from '../../components/RelinkDialog';
import { StateType } from '../reducer';
import { getIntl } from '../selectors/user';
import { hasNetworkDialog } from '../selectors/network';
import { isDone } from '../../util/registration';
const mapStateToProps = (state: StateType) => {
return {
hasNetworkDialog: hasNetworkDialog(state),
i18n: getIntl(state),
isRegistrationDone: isDone(),
};
};
const smart = connect(mapStateToProps, mapDispatchToProps);
export const SmartRelinkDialog = smart(RelinkDialog);