import React, { PureComponent } from "react" import PropTypes from "prop-types" import { helpers } from "swagger-client" import { Iterable, fromJS } from "immutable" const { opId } = helpers export default class OperationContainer extends PureComponent { constructor(props, context) { super(props, context) this.state = { tryItOutEnabled: false, executeInProgress: false } } static propTypes = { op: PropTypes.instanceOf(Iterable).isRequired, tag: PropTypes.string.isRequired, path: PropTypes.string.isRequired, method: PropTypes.string.isRequired, operationId: PropTypes.string.isRequired, showSummary: PropTypes.bool.isRequired, isShown: PropTypes.bool.isRequired, isShownKey: PropTypes.instanceOf(Iterable).isRequired, jumpToKey: PropTypes.string.isRequired, allowTryItOut: PropTypes.bool, displayOperationId: PropTypes.bool, displayRequestDuration: PropTypes.bool, response: PropTypes.instanceOf(Iterable), request: PropTypes.instanceOf(Iterable), isDeepLinkingEnabled: PropTypes.bool.isRequired, getComponent: PropTypes.func.isRequired, authActions: PropTypes.object, authSelectors: PropTypes.object, specActions: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired, layoutActions: PropTypes.object.isRequired, layoutSelectors: PropTypes.object.isRequired, fn: PropTypes.object.isRequired, getConfigs: PropTypes.func.isRequired } static defaultProps = { showSummary: true, response: null, allowTryItOut: true, displayOperationId: false, displayRequestDuration: false } mapStateToProps(nextState, props) { const { op, layoutSelectors, getConfigs } = props const { docExpansion, deepLinking, displayOperationId, displayRequestDuration } = getConfigs() const showSummary = layoutSelectors.showSummary() const operationId = op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id") const isShownKey = fromJS(["operations", props.tag, operationId]) const isDeepLinkingEnabled = deepLinking && deepLinking !== "false" return { operationId, isDeepLinkingEnabled, isShownKey, showSummary, displayOperationId, displayRequestDuration, isShown: layoutSelectors.isShown(isShownKey, docExpansion === "full" ), jumpToKey: `paths.${props.path}.${props.method}`, allowTryItOut: props.specSelectors.allowTryItOutFor(props.path, props.method), response: props.specSelectors.responseFor(props.path, props.method), request: props.specSelectors.requestFor(props.path, props.method) } } componentWillReceiveProps(nextProps) { const defaultContentType = "application/json" let { specActions, path, method, op } = nextProps let operation = op.get("operation") let producesValue = operation.get("produces_value") let produces = operation.get("produces") let consumes = operation.get("consumes") let consumesValue = operation.get("consumes_value") if(nextProps.response !== this.props.response) { this.setState({ executeInProgress: false }) } if (producesValue === undefined) { producesValue = produces && produces.size ? produces.first() : defaultContentType specActions.changeProducesValue([path, method], producesValue) } if (consumesValue === undefined) { consumesValue = consumes && consumes.size ? consumes.first() : defaultContentType specActions.changeConsumesValue([path, method], consumesValue) } } shouldComponentUpdate(nextProps, nextState) { const render = this.state.tryItOutEnabled !== nextState.tryItOutEnabled || this.state.executeInProgress !== nextState.executeInProgress || this.props.op !== nextProps.op || this.props.tag !== nextProps.tag || this.props.path !== nextProps.path || this.props.method !== nextProps.method || this.props.operationId !== nextProps.operationId || this.props.showSummary !== nextProps.showSummary || this.props.isShown !== nextProps.isShown || this.props.jumpToKey !== nextProps.jumpToKey || this.props.allowTryItOut !== nextProps.allowTryItOut || this.props.displayOperationId !== nextProps.displayOperationId || this.props.displayRequestDuration !== nextProps.displayRequestDuration || this.props.response !== nextProps.response || this.props.request !== nextProps.request || this.props.isDeepLinkingEnabled !== nextProps.isDeepLinkingEnabled return render } toggleShown =() => { let { layoutActions, isShownKey, isShown } = this.props layoutActions.show(isShownKey, !isShown) } onTryoutClick =() => { this.setState({tryItOutEnabled: !this.state.tryItOutEnabled}) } onCancelClick =() => { let { specActions, path, method } = this.props this.setState({tryItOutEnabled: !this.state.tryItOutEnabled}) specActions.clearValidateParams([path, method]) } onExecute = () => { this.setState({ executeInProgress: true }) } render() { let { op, tag, path, method, operationId, showSummary, isShown, isShownKey, jumpToKey, allowTryItOut, response, request, displayOperationId, displayRequestDuration, isDeepLinkingEnabled, specSelectors, specActions, getComponent, getConfigs, layoutSelectors, layoutActions, authActions, authSelectors, fn } = this.props const Operation = getComponent( "operation" ) const operationProps = fromJS({ op, tag, path, method, operationId, showSummary, isShown, isShownKey, jumpToKey, allowTryItOut, request, displayOperationId, displayRequestDuration, isDeepLinkingEnabled, executeInProgress: this.state.executeInProgress, tryItOutEnabled: this.state.tryItOutEnabled }) return ( ) } }