Decouple RelinkDialog from NetworkStatusDialog
This commit is contained in:
parent
0970c73310
commit
4dc7631851
8 changed files with 123 additions and 37 deletions
|
@ -37,6 +37,7 @@ export interface PropsType {
|
||||||
renderMainHeader: () => JSX.Element;
|
renderMainHeader: () => JSX.Element;
|
||||||
renderMessageSearchResult: (id: string) => JSX.Element;
|
renderMessageSearchResult: (id: string) => JSX.Element;
|
||||||
renderNetworkStatus: () => JSX.Element;
|
renderNetworkStatus: () => JSX.Element;
|
||||||
|
renderRelinkDialog: () => JSX.Element;
|
||||||
renderUpdateDialog: () => JSX.Element;
|
renderUpdateDialog: () => JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +395,7 @@ export class LeftPane extends React.Component<PropsType> {
|
||||||
renderExpiredBuildDialog,
|
renderExpiredBuildDialog,
|
||||||
renderMainHeader,
|
renderMainHeader,
|
||||||
renderNetworkStatus,
|
renderNetworkStatus,
|
||||||
|
renderRelinkDialog,
|
||||||
renderUpdateDialog,
|
renderUpdateDialog,
|
||||||
showArchived,
|
showArchived,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -408,6 +410,7 @@ export class LeftPane extends React.Component<PropsType> {
|
||||||
{renderExpiredBuildDialog()}
|
{renderExpiredBuildDialog()}
|
||||||
{renderNetworkStatus()}
|
{renderNetworkStatus()}
|
||||||
{renderUpdateDialog()}
|
{renderUpdateDialog()}
|
||||||
|
{renderRelinkDialog()}
|
||||||
{this.renderList()}
|
{this.renderList()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -16,9 +16,7 @@ const defaultProps = {
|
||||||
hasNetworkDialog: true,
|
hasNetworkDialog: true,
|
||||||
i18n,
|
i18n,
|
||||||
isOnline: true,
|
isOnline: true,
|
||||||
isRegistrationDone: true,
|
|
||||||
socketStatus: 0,
|
socketStatus: 0,
|
||||||
relinkDevice: action('relink-device'),
|
|
||||||
manualReconnect: action('manual-reconnect'),
|
manualReconnect: action('manual-reconnect'),
|
||||||
withinConnectingGracePeriod: false,
|
withinConnectingGracePeriod: false,
|
||||||
};
|
};
|
||||||
|
@ -42,19 +40,6 @@ const permutations = [
|
||||||
socketStatus: 3,
|
socketStatus: 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'Unlinked (online)',
|
|
||||||
props: {
|
|
||||||
isRegistrationDone: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Unlinked (offline)',
|
|
||||||
props: {
|
|
||||||
isOnline: false,
|
|
||||||
isRegistrationDone: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'Offline',
|
title: 'Offline',
|
||||||
props: {
|
props: {
|
||||||
|
@ -67,7 +52,6 @@ storiesOf('Components/NetworkStatus', module)
|
||||||
.add('Knobs Playground', () => {
|
.add('Knobs Playground', () => {
|
||||||
const hasNetworkDialog = boolean('hasNetworkDialog', true);
|
const hasNetworkDialog = boolean('hasNetworkDialog', true);
|
||||||
const isOnline = boolean('isOnline', true);
|
const isOnline = boolean('isOnline', true);
|
||||||
const isRegistrationDone = boolean('isRegistrationDone', true);
|
|
||||||
const socketStatus = select(
|
const socketStatus = select(
|
||||||
'socketStatus',
|
'socketStatus',
|
||||||
{
|
{
|
||||||
|
@ -84,7 +68,6 @@ storiesOf('Components/NetworkStatus', module)
|
||||||
{...defaultProps}
|
{...defaultProps}
|
||||||
hasNetworkDialog={hasNetworkDialog}
|
hasNetworkDialog={hasNetworkDialog}
|
||||||
isOnline={isOnline}
|
isOnline={isOnline}
|
||||||
isRegistrationDone={isRegistrationDone}
|
|
||||||
socketStatus={socketStatus}
|
socketStatus={socketStatus}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,8 +8,6 @@ const FIVE_SECONDS = 5 * 1000;
|
||||||
export interface PropsType extends NetworkStateType {
|
export interface PropsType extends NetworkStateType {
|
||||||
hasNetworkDialog: boolean;
|
hasNetworkDialog: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
isRegistrationDone: boolean;
|
|
||||||
relinkDevice: () => void;
|
|
||||||
manualReconnect: () => void;
|
manualReconnect: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +37,7 @@ export const NetworkStatus = ({
|
||||||
hasNetworkDialog,
|
hasNetworkDialog,
|
||||||
i18n,
|
i18n,
|
||||||
isOnline,
|
isOnline,
|
||||||
isRegistrationDone,
|
|
||||||
socketStatus,
|
socketStatus,
|
||||||
relinkDevice,
|
|
||||||
manualReconnect,
|
manualReconnect,
|
||||||
}: PropsType): JSX.Element | null => {
|
}: PropsType): JSX.Element | null => {
|
||||||
if (!hasNetworkDialog) {
|
if (!hasNetworkDialog) {
|
||||||
|
@ -76,17 +72,7 @@ export const NetworkStatus = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isRegistrationDone) {
|
if (isConnecting) {
|
||||||
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) {
|
|
||||||
return renderDialog({
|
return renderDialog({
|
||||||
subtext: i18n('connectingHangOn'),
|
subtext: i18n('connectingHangOn'),
|
||||||
title: i18n('connecting'),
|
title: i18n('connecting'),
|
||||||
|
|
58
ts/components/RelinkDialog.stories.tsx
Normal file
58
ts/components/RelinkDialog.stories.tsx
Normal 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} />
|
||||||
|
</>
|
||||||
|
));
|
||||||
|
});
|
33
ts/components/RelinkDialog.tsx
Normal file
33
ts/components/RelinkDialog.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ import { SmartExpiredBuildDialog } from './ExpiredBuildDialog';
|
||||||
import { SmartMainHeader } from './MainHeader';
|
import { SmartMainHeader } from './MainHeader';
|
||||||
import { SmartMessageSearchResult } from './MessageSearchResult';
|
import { SmartMessageSearchResult } from './MessageSearchResult';
|
||||||
import { SmartNetworkStatus } from './NetworkStatus';
|
import { SmartNetworkStatus } from './NetworkStatus';
|
||||||
|
import { SmartRelinkDialog } from './RelinkDialog';
|
||||||
import { SmartUpdateDialog } from './UpdateDialog';
|
import { SmartUpdateDialog } from './UpdateDialog';
|
||||||
|
|
||||||
// Workaround: A react component's required properties are filtering up through connect()
|
// 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 FilteredSmartNetworkStatus = SmartNetworkStatus as any;
|
||||||
const FilteredSmartUpdateDialog = SmartUpdateDialog as any;
|
const FilteredSmartUpdateDialog = SmartUpdateDialog as any;
|
||||||
const FilteredSmartExpiredBuildDialog = SmartExpiredBuildDialog as any;
|
const FilteredSmartExpiredBuildDialog = SmartExpiredBuildDialog as any;
|
||||||
|
const FilteredSmartRelinkDialog = SmartRelinkDialog as any;
|
||||||
|
|
||||||
function renderExpiredBuildDialog(): JSX.Element {
|
function renderExpiredBuildDialog(): JSX.Element {
|
||||||
return <FilteredSmartExpiredBuildDialog />;
|
return <FilteredSmartExpiredBuildDialog />;
|
||||||
|
@ -35,12 +37,15 @@ function renderMainHeader(): JSX.Element {
|
||||||
function renderMessageSearchResult(id: string): JSX.Element {
|
function renderMessageSearchResult(id: string): JSX.Element {
|
||||||
return <FilteredSmartMessageSearchResult id={id} />;
|
return <FilteredSmartMessageSearchResult id={id} />;
|
||||||
}
|
}
|
||||||
function renderUpdateDialog(): JSX.Element {
|
|
||||||
return <FilteredSmartUpdateDialog />;
|
|
||||||
}
|
|
||||||
function renderNetworkStatus(): JSX.Element {
|
function renderNetworkStatus(): JSX.Element {
|
||||||
return <FilteredSmartNetworkStatus />;
|
return <FilteredSmartNetworkStatus />;
|
||||||
}
|
}
|
||||||
|
function renderRelinkDialog(): JSX.Element {
|
||||||
|
return <FilteredSmartRelinkDialog />;
|
||||||
|
}
|
||||||
|
function renderUpdateDialog(): JSX.Element {
|
||||||
|
return <FilteredSmartUpdateDialog />;
|
||||||
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state: StateType) => {
|
const mapStateToProps = (state: StateType) => {
|
||||||
const showSearch = isSearching(state);
|
const showSearch = isSearching(state);
|
||||||
|
@ -59,6 +64,7 @@ const mapStateToProps = (state: StateType) => {
|
||||||
renderMainHeader,
|
renderMainHeader,
|
||||||
renderMessageSearchResult,
|
renderMessageSearchResult,
|
||||||
renderNetworkStatus,
|
renderNetworkStatus,
|
||||||
|
renderRelinkDialog,
|
||||||
renderUpdateDialog,
|
renderUpdateDialog,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,14 +4,12 @@ import { NetworkStatus } from '../../components/NetworkStatus';
|
||||||
import { StateType } from '../reducer';
|
import { StateType } from '../reducer';
|
||||||
import { getIntl } from '../selectors/user';
|
import { getIntl } from '../selectors/user';
|
||||||
import { hasNetworkDialog } from '../selectors/network';
|
import { hasNetworkDialog } from '../selectors/network';
|
||||||
import { isDone } from '../../util/registration';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: StateType) => {
|
const mapStateToProps = (state: StateType) => {
|
||||||
return {
|
return {
|
||||||
...state.network,
|
...state.network,
|
||||||
hasNetworkDialog: hasNetworkDialog(state),
|
hasNetworkDialog: hasNetworkDialog(state),
|
||||||
i18n: getIntl(state),
|
i18n: getIntl(state),
|
||||||
isRegistrationDone: isDone(),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
19
ts/state/smart/RelinkDialog.tsx
Normal file
19
ts/state/smart/RelinkDialog.tsx
Normal 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);
|
Loading…
Add table
Reference in a new issue