From 7049a5960c2b96d4f6528f1dffcc134ba591262f Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Sun, 25 Jun 2017 09:16:35 -0600 Subject: [PATCH 1/2] #3135 - Add request duration to response details --- src/core/components/live-response.jsx | 18 +++++++++++++++++- src/core/plugins/spec/actions.js | 8 +++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/core/components/live-response.jsx b/src/core/components/live-response.jsx index 550208fa..7c6f1384 100644 --- a/src/core/components/live-response.jsx +++ b/src/core/components/live-response.jsx @@ -8,11 +8,23 @@ const Headers = ( { headers } )=>{
{headers}
) } - Headers.propTypes = { headers: PropTypes.array.isRequired } +const Duration = ( { duration } ) => { + return ( +
+
Request duration
+
{duration} ms
+
+ ) +} +Duration.propTypes = { + duration: PropTypes.number.isRequired +} + + export default class LiveResponse extends React.Component { static propTypes = { response: PropTypes.object.isRequired, @@ -27,6 +39,7 @@ export default class LiveResponse extends React.Component { const headers = response.get("headers").toJS() const notDocumented = response.get("notDocumented") const isError = response.get("error") + const duration = response.get("duration") const body = isError ? response.get("response").get("text") : response.get("text") @@ -80,6 +93,9 @@ export default class LiveResponse extends React.Component { { hasHeaders ? : null } + { + duration ? : null + } diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index d531630a..9424891e 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -207,8 +207,14 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => { specActions.setRequest(req.pathName, req.method, parsedRequest) + // track duration of request + const startTime = Date.now() + return fn.execute(req) - .then( res => specActions.setResponse(req.pathName, req.method, res)) + .then( res => { + res.duration = Date.now() - startTime + specActions.setResponse(req.pathName, req.method, res) + } ) .catch( err => specActions.setResponse(req.pathName, req.method, { error: true, err: serializeError(err) } ) ) } From 0c6f5e8d329ff0ac4ab77661709c88c448b8a652 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Mon, 26 Jun 2017 21:13:17 -0600 Subject: [PATCH 2/2] Add displayRequestDuration configuration option. --- README.md | 1 + src/core/components/live-response.jsx | 7 ++++--- src/core/components/operation.jsx | 5 ++++- src/core/components/operations.jsx | 3 ++- src/core/components/responses.jsx | 9 ++++++--- src/core/index.js | 3 ++- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index eff32bc7..538b6e0b 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ parameterMacro | MUST be a function. Function to set default value to parameters modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'. displayOperationId | Controls the display of operationId in operations list. The default is `false`. +displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`. ### Plugins diff --git a/src/core/components/live-response.jsx b/src/core/components/live-response.jsx index 7c6f1384..ab039043 100644 --- a/src/core/components/live-response.jsx +++ b/src/core/components/live-response.jsx @@ -28,11 +28,12 @@ Duration.propTypes = { export default class LiveResponse extends React.Component { static propTypes = { response: PropTypes.object.isRequired, - getComponent: PropTypes.func.isRequired + getComponent: PropTypes.func.isRequired, + displayRequestDuration: PropTypes.bool.isRequired } render() { - const { request, response, getComponent } = this.props + const { request, response, getComponent, displayRequestDuration } = this.props const status = response.get("status") const url = response.get("url") @@ -94,7 +95,7 @@ export default class LiveResponse extends React.Component { hasHeaders ? : null } { - duration ? : null + displayRequestDuration && duration ? : null } diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx index 31f52cda..704b729e 100644 --- a/src/core/components/operation.jsx +++ b/src/core/components/operation.jsx @@ -17,6 +17,7 @@ export default class Operation extends PureComponent { allowTryItOut: PropTypes.bool, displayOperationId: PropTypes.bool, + displayRequestDuration: PropTypes.bool, response: PropTypes.object, request: PropTypes.object, @@ -37,6 +38,7 @@ export default class Operation extends PureComponent { response: null, allowTryItOut: true, displayOperationId: false, + displayRequestDuration: false } constructor(props, context) { @@ -107,7 +109,7 @@ export default class Operation extends PureComponent { request, allowTryItOut, displayOperationId, - + displayRequestDuration, fn, getComponent, specActions, @@ -250,6 +252,7 @@ export default class Operation extends PureComponent { produces={ produces } producesValue={ operation.get("produces_value") } pathMethod={ [path, method] } + displayRequestDuration={ displayRequestDuration } fn={fn} /> } diff --git a/src/core/components/operations.jsx b/src/core/components/operations.jsx index 16c8a86e..7eb7b4e7 100644 --- a/src/core/components/operations.jsx +++ b/src/core/components/operations.jsx @@ -32,7 +32,7 @@ export default class Operations extends React.Component { const Collapse = getComponent("Collapse") let showSummary = layoutSelectors.showSummary() - let { docExpansion, displayOperationId } = getConfigs() + let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs() return (
@@ -87,6 +87,7 @@ export default class Operations extends React.Component { allowTryItOut={allowTryItOut} displayOperationId={displayOperationId} + displayRequestDuration={displayRequestDuration} specActions={ specActions } specSelectors={ specSelectors } diff --git a/src/core/components/responses.jsx b/src/core/components/responses.jsx index 8bbe4f0f..1da9fb69 100644 --- a/src/core/components/responses.jsx +++ b/src/core/components/responses.jsx @@ -14,19 +14,21 @@ export default class Responses extends React.Component { specSelectors: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired, pathMethod: PropTypes.array.isRequired, + displayRequestDuration: PropTypes.bool.isRequired, fn: PropTypes.object.isRequired } static defaultProps = { request: null, tryItOutResponse: null, - produces: fromJS(["application/json"]) + produces: fromJS(["application/json"]), + displayRequestDuration: false } onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val) render() { - let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue } = this.props + let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue, displayRequestDuration } = this.props let defaultCode = defaultStatusCode( responses ) const ContentType = getComponent( "contentType" ) @@ -53,7 +55,8 @@ export default class Responses extends React.Component { :
+ getComponent={ getComponent } + displayRequestDuration={ displayRequestDuration } />

Responses

diff --git a/src/core/index.js b/src/core/index.js index 461a67cd..228ff838 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -8,7 +8,7 @@ import { parseSeach, filterConfigs } from "core/utils" const CONFIGS = [ "url", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion", "apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl", - "showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" ] + "showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"] // eslint-disable-next-line no-undef const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo @@ -29,6 +29,7 @@ module.exports = function SwaggerUI(opts) { configs: {}, custom: {}, displayOperationId: false, + displayRequestDuration: false, // Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance. // Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.