Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Add input debouncing to improve responsiveness of UI with lots of end…
Browse files Browse the repository at this point in the history
…points
  • Loading branch information
domharrington committed Feb 21, 2019
1 parent 01e035e commit 1ae5a51
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 18 deletions.
13 changes: 11 additions & 2 deletions packages/api-explorer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/api-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"prop-types": "^15.5.10",
"react": "^16.4.2",
"react-copy-to-clipboard": "^5.0.1",
"react-debounce-input": "^3.2.0",
"react-json-view": "^1.19.1",
"react-jsonschema-form": "github:domharrington/react-jsonschema-form#dist-committed",
"react-waypoint": "^7.3.1",
Expand Down
28 changes: 26 additions & 2 deletions packages/api-explorer/src/SecurityInput.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const React = require('react');
const PropTypes = require('prop-types');
const DebounceInput = require('react-debounce-input');

const Oauth2 = require('./security-input-types/Oauth2');
const ApiKey = require('./security-input-types/ApiKey');
Expand All @@ -10,15 +11,35 @@ const types = {
apiKey: ApiKey,
};

class Input extends React.Component {
render() {
return (
<DebounceInput
{...this.props}
minLength={2}
debounceTimeout={process.env.NODE_ENV === 'test' ? 0 : 300}
/>
);
}
}

function SecurityInput(props) {
function change(value) {
return props.onChange({ [props.scheme._key]: value });
}

switch (props.scheme.type) {
case 'apiKey':
case 'oauth2': {
const Component = types[props.scheme.type];
return <Component {...props} apiKey={props.auth[props.scheme._key]} change={change} />;
return (
<Component
{...props}
apiKey={props.auth[props.scheme._key]}
change={change}
Input={Input}
/>
);
}
case 'http':
// TODO support other schemes? https://github.com/readmeio/api-explorer/issues/15
Expand All @@ -29,11 +50,14 @@ function SecurityInput(props) {
change={change}
user={props.auth[props.scheme._key].user}
pass={props.auth[props.scheme._key].pass}
Input={Input}
/>
);
}
if (props.scheme.scheme === 'bearer') {
return <Oauth2 {...props} apiKey={props.auth[props.scheme._key]} change={change} />;
return (
<Oauth2 {...props} apiKey={props.auth[props.scheme._key]} change={change} Input={Input} />
);
}
break;
default:
Expand Down
9 changes: 5 additions & 4 deletions packages/api-explorer/src/security-input-types/ApiKey.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
const React = require('react');
const PropTypes = require('prop-types');

function ApiKey({ apiKey, scheme, authInputRef, change }) {
function ApiKey({ apiKey, scheme, authInputRef, change, Input }) {
return (
<div className="row">
<div className="col-xs-5">
<label htmlFor="apiKey">{scheme.name}</label>
</div>
<div className="col-xs-7">
<input
ref={authInputRef}
<Input
inputRef={authInputRef}
type="text"
onChange={e => change(e.currentTarget.value)}
onChange={e => change(e.target.value)}
value={apiKey}
/>
</div>
Expand All @@ -26,6 +26,7 @@ ApiKey.propTypes = {
}).isRequired,
authInputRef: PropTypes.func,
change: PropTypes.func.isRequired,
Input: PropTypes.func.isRequired,
};

ApiKey.defaultProps = {
Expand Down
13 changes: 7 additions & 6 deletions packages/api-explorer/src/security-input-types/Basic.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const React = require('react');
const PropTypes = require('prop-types');

function Basic({ user, pass, change, authInputRef }) {
function Basic({ user, pass, change, authInputRef, Input }) {
function inputChange(name, value) {
change(Object.assign({ user, pass }, { [name]: value }));
}
Expand All @@ -10,19 +10,19 @@ function Basic({ user, pass, change, authInputRef }) {
<div className="row">
<div className="col-xs-6">
<label htmlFor="user">username</label>
<input
ref={authInputRef}
<Input
inputRef={authInputRef}
type="text"
onChange={e => inputChange(e.currentTarget.name, e.currentTarget.value)}
onChange={e => inputChange(e.target.name, e.target.value)}
name="user"
value={user}
/>
</div>
<div className="col-xs-6">
<label htmlFor="password">password</label>
<input
<Input
type="text"
onChange={e => inputChange(e.currentTarget.name, e.currentTarget.value)}
onChange={e => inputChange(e.target.name, e.target.value)}
name="pass"
value={pass}
/>
Expand All @@ -36,6 +36,7 @@ Basic.propTypes = {
authInputRef: PropTypes.func,
user: PropTypes.string,
pass: PropTypes.string,
Input: PropTypes.func.isRequired,
};

Basic.defaultProps = {
Expand Down
9 changes: 5 additions & 4 deletions packages/api-explorer/src/security-input-types/Oauth2.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const PropTypes = require('prop-types');

const oauthHref = require('../lib/oauth-href');

function Oauth2({ apiKey, authInputRef, oauth, change }) {
function Oauth2({ apiKey, authInputRef, oauth, change, Input }) {
if (!apiKey && oauth) {
return (
<section>
Expand Down Expand Up @@ -40,11 +40,11 @@ function Oauth2({ apiKey, authInputRef, oauth, change }) {
</div>
</div>
<div className="col-xs-6">
<input
ref={authInputRef}
<Input
inputRef={authInputRef}
disabled={oauth}
type="text"
onChange={e => change(e.currentTarget.value)}
onChange={e => change(e.target.value)}
name="apiKey"
value={apiKey}
/>
Expand All @@ -59,6 +59,7 @@ Oauth2.propTypes = {
oauth: PropTypes.bool.isRequired,
change: PropTypes.func.isRequired,
authInputRef: PropTypes.func,
Input: PropTypes.func.isRequired,
};

Oauth2.defaultProps = {
Expand Down

0 comments on commit 1ae5a51

Please sign in to comment.