Merge pull request #2964 from matrix-org/travis/wk/simplify-phases

Refactor "Next" button into ServerConfig components
This commit is contained in:
Travis Ralston 2019-05-16 12:46:35 -06:00 committed by GitHub
commit 8c326bff9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 125 additions and 96 deletions

View file

@ -124,13 +124,7 @@ module.exports = React.createClass({
}); });
}, },
async onServerDetailsNextPhaseClick(ev) { async onServerDetailsNextPhaseClick() {
ev.stopPropagation();
// TODO: TravisR - Capture the user's input somehow else
if (this._serverConfigRef) {
// Just to make sure the user's input gets captured
await this._serverConfigRef.validateServer();
}
this.setState({ this.setState({
phase: PHASE_FORGOT, phase: PHASE_FORGOT,
}); });
@ -160,25 +154,19 @@ module.exports = React.createClass({
renderServerDetails() { renderServerDetails() {
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
if (SdkConfig.get()['disable_custom_urls']) { if (SdkConfig.get()['disable_custom_urls']) {
return null; return null;
} }
// TODO: TravisR - Pull out server discovery from ServerConfig to disable the next button? return <ServerConfig
return <div> serverConfig={this.props.serverConfig}
<ServerConfig onServerConfigChange={this.props.onServerConfigChange}
ref={r => this._serverConfigRef = r} delayTimeMs={0}
serverConfig={this.props.serverConfig} onAfterSubmit={this.onServerDetailsNextPhaseClick}
onServerConfigChange={this.props.onServerConfigChange} submitText={_t("Next")}
delayTimeMs={0} /> submitClass="mx_Login_submit"
<AccessibleButton className="mx_Login_submit" />;
onClick={this.onServerDetailsNextPhaseClick}
>
{_t("Next")}
</AccessibleButton>
</div>;
}, },
renderForgot() { renderForgot() {

View file

@ -20,11 +20,11 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { _t, _td } from '../../../languageHandler'; import {_t, _td} from '../../../languageHandler';
import sdk from '../../../index'; import sdk from '../../../index';
import Login from '../../../Login'; import Login from '../../../Login';
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; import {messageForResourceLimitError} from '../../../utils/ErrorUtils';
import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils"; import {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
// For validating phone numbers without country codes // For validating phone numbers without country codes
@ -283,13 +283,7 @@ module.exports = React.createClass({
this.props.onRegisterClick(); this.props.onRegisterClick();
}, },
async onServerDetailsNextPhaseClick(ev) { async onServerDetailsNextPhaseClick() {
ev.stopPropagation();
// TODO: TravisR - Capture the user's input somehow else
if (this._serverConfigRef) {
// Just to make sure the user's input gets captured
await this._serverConfigRef.validateServer();
}
this.setState({ this.setState({
phase: PHASE_LOGIN, phase: PHASE_LOGIN,
}); });
@ -421,7 +415,6 @@ module.exports = React.createClass({
renderServerComponent() { renderServerComponent() {
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
if (SdkConfig.get()['disable_custom_urls']) { if (SdkConfig.get()['disable_custom_urls']) {
return null; return null;
@ -431,26 +424,19 @@ module.exports = React.createClass({
return null; return null;
} }
const serverDetails = <ServerConfig const serverDetailsProps = {};
ref={r => this._serverConfigRef = r} if (PHASES_ENABLED) {
serverDetailsProps.onAfterSubmit = this.onServerDetailsNextPhaseClick;
serverDetailsProps.submitText = _t("Next");
serverDetailsProps.submitClass = "mx_Login_submit";
}
return <ServerConfig
serverConfig={this.props.serverConfig} serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange} onServerConfigChange={this.props.onServerConfigChange}
delayTimeMs={250} delayTimeMs={250}
{...serverDetailsProps}
/>; />;
let nextButton = null;
if (PHASES_ENABLED) {
// TODO: TravisR - Pull out server discovery from ServerConfig to disable the next button?
nextButton = <AccessibleButton className="mx_Login_submit"
onClick={this.onServerDetailsNextPhaseClick}>
{_t("Next")}
</AccessibleButton>;
}
return <div>
{serverDetails}
{nextButton}
</div>;
}, },
renderLoginComponentForStep() { renderLoginComponentForStep() {

View file

@ -286,13 +286,7 @@ module.exports = React.createClass({
}); });
}, },
async onServerDetailsNextPhaseClick(ev) { async onServerDetailsNextPhaseClick() {
ev.stopPropagation();
// TODO: TravisR - Capture the user's input somehow else
if (this._serverConfigRef) {
// Just to make sure the user's input gets captured
await this._serverConfigRef.validateServer();
}
this.setState({ this.setState({
phase: PHASE_REGISTRATION, phase: PHASE_REGISTRATION,
}); });
@ -337,7 +331,6 @@ module.exports = React.createClass({
const ServerTypeSelector = sdk.getComponent("auth.ServerTypeSelector"); const ServerTypeSelector = sdk.getComponent("auth.ServerTypeSelector");
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
const ModularServerConfig = sdk.getComponent("auth.ModularServerConfig"); const ModularServerConfig = sdk.getComponent("auth.ModularServerConfig");
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
if (SdkConfig.get()['disable_custom_urls']) { if (SdkConfig.get()['disable_custom_urls']) {
return null; return null;
@ -354,45 +347,41 @@ module.exports = React.createClass({
</div>; </div>;
} }
const serverDetailsProps = {};
if (PHASES_ENABLED) {
serverDetailsProps.onAfterSubmit = this.onServerDetailsNextPhaseClick;
serverDetailsProps.submitText = _t("Next");
serverDetailsProps.submitClass = "mx_Login_submit";
}
let serverDetails = null; let serverDetails = null;
switch (this.state.serverType) { switch (this.state.serverType) {
case ServerType.FREE: case ServerType.FREE:
break; break;
case ServerType.PREMIUM: case ServerType.PREMIUM:
serverDetails = <ModularServerConfig serverDetails = <ModularServerConfig
ref={r => this._serverConfigRef = r}
serverConfig={this.props.serverConfig} serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange} onServerConfigChange={this.props.onServerConfigChange}
delayTimeMs={250} delayTimeMs={250}
{...serverDetailsProps}
/>; />;
break; break;
case ServerType.ADVANCED: case ServerType.ADVANCED:
serverDetails = <ServerConfig serverDetails = <ServerConfig
ref={r => this._serverConfigRef = r}
serverConfig={this.props.serverConfig} serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange} onServerConfigChange={this.props.onServerConfigChange}
delayTimeMs={250} delayTimeMs={250}
{...serverDetailsProps}
/>; />;
break; break;
} }
let nextButton = null;
if (PHASES_ENABLED) {
// TODO: TravisR - Pull out server discovery from ServerConfig to disable the next button?
nextButton = <AccessibleButton className="mx_Login_submit"
onClick={this.onServerDetailsNextPhaseClick}
>
{_t("Next")}
</AccessibleButton>;
}
return <div> return <div>
<ServerTypeSelector <ServerTypeSelector
selected={this.state.serverType} selected={this.state.serverType}
onChange={this.onServerTypeChange} onChange={this.onServerTypeChange}
/> />
{serverDetails} {serverDetails}
{nextButton}
</div>; </div>;
}, },

View file

@ -41,6 +41,16 @@ export default class ModularServerConfig extends React.PureComponent {
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired, serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
delayTimeMs: PropTypes.number, // time to wait before invoking onChanged delayTimeMs: PropTypes.number, // time to wait before invoking onChanged
// Called after the component calls onServerConfigChange
onAfterSubmit: PropTypes.func,
// Optional text for the submit button. If falsey, no button will be shown.
submitText: PropTypes.string,
// Optional class for the submit button. Only applies if the submit button
// is to be rendered.
submitClass: PropTypes.string,
}; };
static defaultProps = { static defaultProps = {
@ -119,6 +129,16 @@ export default class ModularServerConfig extends React.PureComponent {
this.setState({ hsUrl }); this.setState({ hsUrl });
}; };
onSubmit = async (ev) => {
ev.preventDefault();
ev.stopPropagation();
await this.validateServer();
if (this.props.onAfterSubmit) {
this.props.onAfterSubmit();
}
};
_waitThenInvoke(existingTimeoutId, fn) { _waitThenInvoke(existingTimeoutId, fn) {
if (existingTimeoutId) { if (existingTimeoutId) {
clearTimeout(existingTimeoutId); clearTimeout(existingTimeoutId);
@ -128,6 +148,16 @@ export default class ModularServerConfig extends React.PureComponent {
render() { render() {
const Field = sdk.getComponent('elements.Field'); const Field = sdk.getComponent('elements.Field');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const submitButton = this.props.submitText
? <AccessibleButton
element="button"
type="submit"
className={this.props.submitClass}
onClick={this.onSubmit}
disabled={this.state.busy}>{this.props.submitText}</AccessibleButton>
: null;
return ( return (
<div className="mx_ServerConfig"> <div className="mx_ServerConfig">
@ -141,15 +171,18 @@ export default class ModularServerConfig extends React.PureComponent {
</a>, </a>,
}, },
)} )}
<div className="mx_ServerConfig_fields"> <form onSubmit={this.onSubmit} autoComplete={false} action={null}>
<Field id="mx_ServerConfig_hsUrl" <div className="mx_ServerConfig_fields">
label={_t("Server Name")} <Field id="mx_ServerConfig_hsUrl"
placeholder={this.props.serverConfig.hsUrl} label={_t("Server Name")}
value={this.state.hsUrl} placeholder={this.props.serverConfig.hsUrl}
onBlur={this.onHomeserverBlur} value={this.state.hsUrl}
onChange={this.onHomeserverChange} onBlur={this.onHomeserverBlur}
/> onChange={this.onHomeserverChange}
</div> />
</div>
{submitButton}
</form>
</div> </div>
); );
} }

View file

@ -30,12 +30,22 @@ import SdkConfig from "../../../SdkConfig";
export default class ServerConfig extends React.PureComponent { export default class ServerConfig extends React.PureComponent {
static propTypes = { static propTypes = {
onServerConfigChange: PropTypes.func, onServerConfigChange: PropTypes.func.isRequired,
// The current configuration that the user is expecting to change. // The current configuration that the user is expecting to change.
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired, serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
delayTimeMs: PropTypes.number, // time to wait before invoking onChanged delayTimeMs: PropTypes.number, // time to wait before invoking onChanged
// Called after the component calls onServerConfigChange
onAfterSubmit: PropTypes.func,
// Optional text for the submit button. If falsey, no button will be shown.
submitText: PropTypes.string,
// Optional class for the submit button. Only applies if the submit button
// is to be rendered.
submitClass: PropTypes.string,
}; };
static defaultProps = { static defaultProps = {
@ -124,6 +134,16 @@ export default class ServerConfig extends React.PureComponent {
this.setState({ isUrl }); this.setState({ isUrl });
}; };
onSubmit = async (ev) => {
ev.preventDefault();
ev.stopPropagation();
await this.validateServer();
if (this.props.onAfterSubmit) {
this.props.onAfterSubmit();
}
};
_waitThenInvoke(existingTimeoutId, fn) { _waitThenInvoke(existingTimeoutId, fn) {
if (existingTimeoutId) { if (existingTimeoutId) {
clearTimeout(existingTimeoutId); clearTimeout(existingTimeoutId);
@ -138,11 +158,21 @@ export default class ServerConfig extends React.PureComponent {
render() { render() {
const Field = sdk.getComponent('elements.Field'); const Field = sdk.getComponent('elements.Field');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const errorText = this.state.errorText const errorText = this.state.errorText
? <span className='mx_ServerConfig_error'>{this.state.errorText}</span> ? <span className='mx_ServerConfig_error'>{this.state.errorText}</span>
: null; : null;
const submitButton = this.props.submitText
? <AccessibleButton
element="button"
type="submit"
className={this.props.submitClass}
onClick={this.onSubmit}
disabled={this.state.busy}>{this.props.submitText}</AccessibleButton>
: null;
return ( return (
<div className="mx_ServerConfig"> <div className="mx_ServerConfig">
<h3>{_t("Other servers")}</h3> <h3>{_t("Other servers")}</h3>
@ -152,24 +182,27 @@ export default class ServerConfig extends React.PureComponent {
</a>, </a>,
})} })}
{errorText} {errorText}
<div className="mx_ServerConfig_fields"> <form onSubmit={this.onSubmit} autoComplete={false} action={null}>
<Field id="mx_ServerConfig_hsUrl" <div className="mx_ServerConfig_fields">
label={_t("Homeserver URL")} <Field id="mx_ServerConfig_hsUrl"
placeholder={this.props.serverConfig.hsUrl} label={_t("Homeserver URL")}
value={this.state.hsUrl} placeholder={this.props.serverConfig.hsUrl}
onBlur={this.onHomeserverBlur} value={this.state.hsUrl}
onChange={this.onHomeserverChange} onBlur={this.onHomeserverBlur}
disabled={this.state.busy} onChange={this.onHomeserverChange}
/> disabled={this.state.busy}
<Field id="mx_ServerConfig_isUrl" />
label={_t("Identity Server URL")} <Field id="mx_ServerConfig_isUrl"
placeholder={this.props.serverConfig.isUrl} label={_t("Identity Server URL")}
value={this.state.isUrl} placeholder={this.props.serverConfig.isUrl}
onBlur={this.onIdentityServerBlur} value={this.state.isUrl}
onChange={this.onIdentityServerChange} onBlur={this.onIdentityServerBlur}
disabled={this.state.busy} onChange={this.onIdentityServerChange}
/> disabled={this.state.busy}
</div> />
</div>
{submitButton}
</form>
</div> </div>
); );
} }