Merge branch 'master' into clickfix

This commit is contained in:
Robert Barnwell
2017-05-22 09:57:19 -07:00
committed by GitHub
105 changed files with 1634 additions and 976 deletions

View File

@@ -64,11 +64,10 @@ export default class ApiKeyAuth extends React.Component {
</Row>
<Row>
<label>Value:</label>
<Col>
{
value || <Input type="text" onChange={ this.onChange }/>
}
</Col>
{
value ? <code> ****** </code>
: <Col><Input type="text" onChange={ this.onChange }/></Col>
}
</Row>
{
errors.valueSeq().map( (error, key) => {

View File

@@ -6,7 +6,7 @@ export default class AuthorizeBtn extends React.Component {
}
onClick =() => {
let { authActions, authSelectors, errActions} = this.props
let { authActions, authSelectors } = this.props
let definitions = authSelectors.definitionsToAuthorize()
authActions.showDefinitions(definitions)

View File

@@ -16,6 +16,10 @@ export default class AuthorizeOperationBtn extends React.Component {
let isAuthorized = authSelectors.isAuthorized(security)
if(isAuthorized === null) {
return null
}
return (
<button className={isAuthorized ? "authorization__btn locked" : "authorization__btn unlocked"} onClick={ this.onClick }>
<svg width="20" height="20">

View File

@@ -42,14 +42,12 @@ export default class Auths extends React.Component {
}
render() {
let { definitions, getComponent, authSelectors, errSelectors, specSelectors } = this.props
let { definitions, getComponent, authSelectors, errSelectors } = this.props
const ApiKeyAuth = getComponent("apiKeyAuth")
const BasicAuth = getComponent("basicAuth")
const Oauth2 = getComponent("oauth2", true)
const Button = getComponent("Button")
const JumpToPath = getComponent("JumpToPath", true)
let specStr = specSelectors.specStr()
let authorized = authSelectors.authorized()
let authorizedAuth = definitions.filter( (definition, key) => {

View File

@@ -63,19 +63,23 @@ export default class BasicAuth extends React.Component {
source={ schema.get("description") } />
</Row>
<Row>
<Col tablet={2} desktop={2}>username:</Col>
<Col tablet={10} desktop={10}>
{
username || <Input type="text" required="required" name="username" onChange={ this.onChange }/>
}
</Col>
<label>Username:</label>
{
username ? <code> { username } </code>
: <Col><Input type="text" required="required" name="username" onChange={ this.onChange }/></Col>
}
</Row>
<Row>
<label>Password:</label>
{
username ? <code> ****** </code>
: <Col><Input required="required"
autoComplete="new-password"
name="password"
type="password"
onChange={ this.onChange }/></Col>
}
</Row>
{
!username && <Row>
<Col tablet={2} desktop={2}>password:</Col>
<Col tablet={10} desktop={10}><Input required="required" autoComplete="new-password" name="password" type="password" onChange={ this.onChange }/></Col>
</Row>
}
{
errors.valueSeq().map( (error, key) => {
return <AuthError error={ error }

View File

@@ -10,25 +10,27 @@ export default class Oauth2 extends React.Component {
static propTypes = {
name: PropTypes.string,
authorized: PropTypes.object,
configs: PropTypes.object,
getComponent: PropTypes.func.isRequired,
schema: PropTypes.object.isRequired,
authSelectors: PropTypes.object.isRequired,
authActions: PropTypes.object.isRequired,
errSelectors: PropTypes.object.isRequired,
errActions: PropTypes.object.isRequired
errActions: PropTypes.object.isRequired,
getConfigs: PropTypes.any
}
constructor(props, context) {
super(props, context)
let { name, schema, authorized } = this.props
let { name, schema, authorized, authSelectors } = this.props
let auth = authorized && authorized.get(name)
let authConfigs = authSelectors.getConfigs() || {}
let username = auth && auth.get("username") || ""
let clientId = auth && auth.get("clientId") || ""
let clientSecret = auth && auth.get("clientSecret") || ""
let passwordType = auth && auth.get("passwordType") || "none"
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
let passwordType = auth && auth.get("passwordType") || "basic"
this.state = {
appName: authConfigs.appName,
name: name,
schema: schema,
scopes: [],
@@ -41,11 +43,12 @@ export default class Oauth2 extends React.Component {
}
authorize =() => {
let { authActions, errActions, getConfigs } = this.props
let { authActions, errActions, getConfigs, authSelectors } = this.props
let configs = getConfigs()
let authConfigs = authSelectors.getConfigs()
errActions.clear({authId: name,type: "auth", source: "auth"})
oauth2Authorize(this.state, authActions, errActions, configs)
oauth2Authorize({auth: this.state, authActions, errActions, configs, authConfigs })
}
onScopeChange =(e) => {
@@ -98,6 +101,7 @@ export default class Oauth2 extends React.Component {
return (
<div>
<h4>OAuth2.0 <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
<Markdown options={{html: true, typographer: true, linkify: true, linkTarget: "_blank"}}
source={ schema.get("description") } />
@@ -108,82 +112,92 @@ export default class Oauth2 extends React.Component {
<p className="flow">Flow: <code>{ schema.get("flow") }</code></p>
{
flow === PASSWORD && ( !isAuthorized || isAuthorized && this.state.username) && <Row>
<Col tablet={2} desktop={2}>username:</Col>
<Col tablet={10} desktop={10}>
flow !== PASSWORD ? null
: <Row>
<Row>
<label htmlFor="oauth_username">username:</label>
{
isAuthorized ? <code> { this.state.username } </code>
: <Col tablet={10} desktop={10}>
<input id="oauth_username" type="text" data-name="username" onChange={ this.onInputChange }/>
</Col>
}
</Row>
{
isAuthorized ? <span>{ this.state.username }</span>
: <input type="text" data-name="username" onChange={ this.onInputChange }/>
}
</Col>
</Row>
<Row>
<label htmlFor="oauth_password">password:</label>
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="oauth_password" type="password" data-name="password" onChange={ this.onInputChange }/>
</Col>
}
</Row>
<Row>
<label htmlFor="password_type">type:</label>
{
isAuthorized ? <code> { this.state.passwordType } </code>
: <Col tablet={10} desktop={10}>
<select id="password_type" data-name="passwordType" onChange={ this.onInputChange }>
<option value="basic">Basic auth</option>
<option value="request-body">Request body</option>
<option value="query">Query parameters</option>
</select>
</Col>
}
</Row>
</Row>
}
{
flow === PASSWORD && !isAuthorized && <Row>
<Col tablet={2} desktop={2}>password:</Col>
<Col tablet={10} desktop={10}>
<input type="password" data-name="password" onChange={ this.onInputChange }/>
</Col>
</Row>
}
{
flow === PASSWORD && <Row>
<Col tablet={2} desktop={2}>type:</Col>
<Col tablet={10} desktop={10}>
{
isAuthorized ? <span>{ this.state.passwordType }</span>
: <select data-name="passwordType" onChange={ this.onInputChange }>
<option value="none">None or other</option>
<option value="basic">Basic auth</option>
<option value="request">Request body</option>
</select>
}
</Col>
</Row>
}
{
( flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) &&
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) &&
( !isAuthorized || isAuthorized && this.state.clientId) && <Row>
<label htmlFor="client_id">client_id:</label>
<Col tablet={10} desktop={10}>
{
isAuthorized ? <span>{ this.state.clientId }</span>
: <input id="client_id" type="text" required={ flow === PASSWORD } data-name="clientId"
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="client_id"
type="text"
required={ flow === PASSWORD }
value={ this.state.clientId }
data-name="clientId"
onChange={ this.onInputChange }/>
}
</Col>
</Col>
}
</Row>
}
{
( flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) && <Row>
( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) && <Row>
<label htmlFor="client_secret">client_secret:</label>
<Col tablet={10} desktop={10}>
{
isAuthorized ? <span>{ this.state.clientSecret }</span>
: <input id="client_secret" type="text" data-name="clientSecret"
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="client_secret"
value={ this.state.clientSecret }
type="text"
data-name="clientSecret"
onChange={ this.onInputChange }/>
}
</Col>
</Col>
}
</Row>
}
{
!isAuthorized && flow !== PASSWORD && scopes && scopes.size ? <div className="scopes">
!isAuthorized && scopes && scopes.size ? <div className="scopes">
<h2>Scopes:</h2>
{ scopes.map((description, name) => {
return (
<Row key={ name }>
<div className="checkbox">
<Input data-value={ name }
id={`${name}-checkbox`}
id={`${name}-checkbox-${this.state.name}`}
disabled={ isAuthorized }
type="checkbox"
onChange={ this.onScopeChange }/>
<label htmlFor={`${name}-checkbox`}>
<label htmlFor={`${name}-checkbox-${this.state.name}`}>
<span className="item"></span>
<div className="text">
<p className="name">{name}</p>
@@ -205,7 +219,7 @@ export default class Oauth2 extends React.Component {
} )
}
<div className="auth-btn-wrapper">
{ isValid && flow !== APPLICATION &&
{ isValid &&
( isAuthorized ? <Button className="btn modal-btn auth authorize" onClick={ this.logout }>Logout</Button>
: <Button className="btn modal-btn auth authorize" onClick={ this.authorize }>Authorize</Button>
)

View File

@@ -1,6 +1,6 @@
import React, { PropTypes } from "react"
import ImPropTypes from "react-immutable-proptypes"
import { fromJS } from 'immutable'
import { fromJS } from "immutable"
const noop = ()=>{}

View File

@@ -19,7 +19,7 @@ export default class Curl extends React.Component {
<div>
<h4>Curl</h4>
<div className="copy-paste">
<textarea onFocus={this.handleFocus} className="curl" style={{ whiteSpace: "normal" }} defaultValue={curl}></textarea>
<textarea onFocus={this.handleFocus} className="curl" style={{ whiteSpace: "normal" }} value={curl}></textarea>
</div>
</div>
)

View File

@@ -1,19 +1,22 @@
import React, { PropTypes } from "react"
import Im, { List } from "immutable"
import { List } from "immutable"
import Collapse from "react-collapse"
import sortBy from "lodash/sortBy"
export default class Errors extends React.Component {
static propTypes = {
jumpToLine: PropTypes.func,
editorActions: PropTypes.object,
errSelectors: PropTypes.object.isRequired,
layoutSelectors: PropTypes.object.isRequired,
layoutActions: PropTypes.object.isRequired
}
render() {
let { jumpToLine, errSelectors, layoutSelectors, layoutActions } = this.props
let { editorActions, errSelectors, layoutSelectors, layoutActions } = this.props
if(editorActions && editorActions.jumpToLine) {
var jumpToLine = editorActions.jumpToLine
}
let errors = errSelectors.allErrors()
@@ -38,10 +41,11 @@ export default class Errors extends React.Component {
<Collapse isOpened={ isVisible } animated >
<div className="errors">
{ sortedJSErrors.map((err, i) => {
if(err.get("type") === "thrown") {
let type = err.get("type")
if(type === "thrown" || type === "auth") {
return <ThrownErrorItem key={ i } error={ err.get("error") || err } jumpToLine={jumpToLine} />
}
if(err.get("type") === "spec") {
if(type === "spec") {
return <SpecErrorItem key={ i } error={ err } jumpToLine={jumpToLine} />
}
}) }
@@ -69,7 +73,7 @@ const ThrownErrorItem = ( { error, jumpToLine } ) => {
{ error.get("message") }
</span>
<div>
{ errorLine ? <a onClick={jumpToLine.bind(null, errorLine)}>Jump to line { errorLine }</a> : null }
{ errorLine && jumpToLine ? <a onClick={jumpToLine.bind(null, errorLine)}>Jump to line { errorLine }</a> : null }
</div>
</div>
}
@@ -78,13 +82,25 @@ const ThrownErrorItem = ( { error, jumpToLine } ) => {
}
const SpecErrorItem = ( { error, jumpToLine } ) => {
let locationMessage = null
if(error.get("path")) {
if(List.isList(error.get("path"))) {
locationMessage = <small>at { error.get("path").join(".") }</small>
} else {
locationMessage = <small>at { error.get("path") }</small>
}
} else if(error.get("line") && !jumpToLine) {
locationMessage = <small>on line { error.get("line") }</small>
}
return (
<div className="error-wrapper">
{ !error ? null :
<div>
<h4>{ toTitleCase(error.get("source")) + " " + error.get("level") }{ error.get("path") ? <small> at {List.isList(error.get("path")) ? error.get("path").join(".") : error.get("path")}</small>: null }</h4>
<h4>{ toTitleCase(error.get("source")) + " " + error.get("level") }&nbsp;{ locationMessage }</h4>
<span style={{ whiteSpace: "pre-line"}}>{ error.get("message") }</span>
<div>
<div style={{ "text-decoration": "underline", "cursor": "pointer" }}>
{ jumpToLine ? (
<a onClick={jumpToLine.bind(null, error.get("line"))}>Jump to line { error.get("line") }</a>
) : null }
@@ -107,6 +123,10 @@ ThrownErrorItem.propTypes = {
jumpToLine: PropTypes.func
}
ThrownErrorItem.defaultProps = {
jumpToLine: null
}
SpecErrorItem.propTypes = {
error: PropTypes.object.isRequired,
jumpToLine: PropTypes.func

View File

@@ -1,5 +1,4 @@
import React, { Component, PropTypes } from "react"
import { fromJS } from "immutable"
export default class Execute extends Component {
@@ -29,9 +28,6 @@ export default class Execute extends Component {
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue([this.props.path, this.props.method], val)
render(){
let { getComponent, operation, specActions, path, method } = this.props
const ContentType = getComponent( "contentType" )
return (
<button className="btn execute opblock-control__btn" onClick={ this.onClick }>
Execute

View File

@@ -58,7 +58,7 @@ class License extends React.Component {
return (
<div>
{
url ? <a href={ url }>{ name }</a>
url ? <a target="_blank" href={ url }>{ name }</a>
: <span>{ name }</span>
}
</div>
@@ -95,7 +95,7 @@ export default class Info extends React.Component {
{ version && <small><pre className="version"> { version } </pre></small> }
</h2>
{ host || basePath ? <Path host={ host } basePath={ basePath } /> : null }
{ url && <a href={ url }><span className="url"> { url } </span></a> }
{ url && <a target="_blank" href={ url }><span className="url"> { url } </span></a> }
</hgroup>
<div className="description">
@@ -104,7 +104,7 @@ export default class Info extends React.Component {
{
termsOfService && <div>
<a href={ termsOfService }>Terms of service</a>
<a target="_blank" href={ termsOfService }>Terms of service</a>
</div>
}

View File

@@ -2,8 +2,6 @@ import React, { PropTypes } from "react"
import OriCollapse from "react-collapse"
import _Markdown from "react-remarkable"
const noop = () => {}
function xclass(...args) {
return args.filter(a => !!a).join(" ").trim()
}
@@ -18,7 +16,7 @@ export class Container extends React.Component {
if(fullscreen)
return <section {...rest}/>
let containerClass = "container" + (full ? "-full" : "")
let containerClass = "swagger-container" + (full ? "-full" : "")
return (
<section {...rest} className={xclass(rest.className, containerClass)}/>
)
@@ -44,12 +42,14 @@ export class Col extends React.Component {
const {
hide,
keepContents,
mobile, /* we don't want these in the final component, since React now complains. So we extract them */
/* we don't want these in the `rest` object that passes to the final component,
since React now complains. So we extract them */
/* eslint-disable no-unused-vars */
mobile,
tablet,
desktop,
large,
/* eslint-enable no-unused-vars */
...rest
} = this.props
@@ -127,7 +127,7 @@ export const Input = (props) => <input {...props} />
export class Select extends React.Component {
static propTypes = {
allowedValues: PropTypes.object,
allowedValues: PropTypes.array,
value: PropTypes.any,
onChange: PropTypes.func,
multiple: PropTypes.bool,

View File

@@ -0,0 +1,80 @@
import React, { PropTypes } from "react"
export default class BaseLayout extends React.Component {
static propTypes = {
errSelectors: PropTypes.object.isRequired,
errActions: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired,
specSelectors: PropTypes.object.isRequired,
layoutSelectors: PropTypes.object.isRequired,
layoutActions: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired
}
render() {
let { specSelectors, specActions, getComponent } = this.props
let info = specSelectors.info()
let url = specSelectors.url()
let basePath = specSelectors.basePath()
let host = specSelectors.host()
let securityDefinitions = specSelectors.securityDefinitions()
let externalDocs = specSelectors.externalDocs()
let schemes = specSelectors.schemes()
let Info = getComponent("info")
let Operations = getComponent("operations", true)
let Models = getComponent("models", true)
let AuthorizeBtn = getComponent("authorizeBtn", true)
let Row = getComponent("Row")
let Col = getComponent("Col")
let Errors = getComponent("errors", true)
const Schemes = getComponent("schemes")
const isSpecEmpty = !specSelectors.specStr()
if(isSpecEmpty) {
return <h4>No spec provided.</h4>
}
return (
<div className='swagger-ui'>
<div>
<Errors/>
<Row className="information-container">
<Col mobile={12}>
{ info.count() ? (
<Info info={ info } url={ url } host={ host } basePath={ basePath } externalDocs={externalDocs} getComponent={getComponent}/>
) : null }
</Col>
</Row>
{ schemes && schemes.size || securityDefinitions ? (
<div className="scheme-container">
<Col className="schemes wrapper" mobile={12}>
{ schemes && schemes.size ? (
<Schemes schemes={ schemes } specActions={ specActions } />
) : null }
{ securityDefinitions ? (
<AuthorizeBtn />
) : null }
</Col>
</div>
) : null }
<Row>
<Col mobile={12} desktop={12} >
<Operations/>
</Col>
</Row>
<Row>
<Col mobile={12} desktop={12} >
<Models/>
</Col>
</Row>
</div>
</div>
)
}
}

View File

@@ -1,10 +1,11 @@
import React, { Component, PropTypes } from "react"
import ImPropTypes from "react-immutable-proptypes"
import isObject from "lodash/isObject"
import { List } from "immutable"
const braceOpen = "{"
const braceClose = "}"
const propStyle = { color: "#999", fontStyle: "italic" }
const EnumModel = ({ value }) => {
let collapsedContent = <span>Array [ { value.count() } ]</span>
return <span className="prop-enum">
@@ -128,10 +129,8 @@ class Primitive extends Component {
let format = schema.get("format")
let xml = schema.get("xml")
let enumArray = schema.get("enum")
let description = schema.get("description")
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "$$ref"].indexOf(key) === -1 )
let style = required ? { fontWeight: "bold" } : {}
let propStyle = { color: "#999", fontStyle: "italic" }
return <span className="prop">
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
@@ -169,12 +168,23 @@ class ArrayModel extends Component {
render(){
let { required, schema, depth, expandDepth } = this.props
let items = schema.get("items")
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
return <span>
return <span className="model">
<span className="model-title">
<span className="model-title__text">{ schema.get("title") }</span>
</span>
<Collapse collapsed={ depth > expandDepth } collapsedContent="[...]">
[
<span><Model { ...this.props } schema={ items } required={ false }/></span>
]
{
properties.size ? <span>
{ properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={propStyle}>
<br />{ `${key}:`}{ String(v) }</span>)
}<br /></span>
: null
}
</Collapse>
{ required && <span style={{ color: "red" }}>*</span>}
</span>
@@ -251,9 +261,6 @@ export default class ModelComponent extends Component {
}
render(){
let { name, schema } = this.props
let title = schema.get("title") || name
return <div className="model-box">
<Model { ...this.props } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
</div>

View File

@@ -4,13 +4,15 @@ import React, { Component, PropTypes } from "react"
export default class Models extends Component {
static propTypes = {
getComponent: PropTypes.func,
specSelectors: PropTypes.object
specSelectors: PropTypes.object,
layoutSelectors: PropTypes.object,
layoutActions: PropTypes.object
}
render(){
let { specSelectors, getComponent, layoutSelectors, layoutActions } = this.props
let definitions = specSelectors.definitions()
let showModels = layoutSelectors.isShown('models', true)
let showModels = layoutSelectors.isShown("models", true)
const Model = getComponent("model")
const Collapse = getComponent("Collapse")
@@ -18,7 +20,7 @@ export default class Models extends Component {
if (!definitions.size) return null
return <section className={ showModels ? "models is-open" : "models"}>
<h4 onClick={() => layoutActions.show('models', !showModels)}>
<h4 onClick={() => layoutActions.show("models", !showModels)}>
<span>Models</span>
<svg width="20" height="20">
<use xlinkHref="#large-arrow" />

View File

@@ -1,13 +1,19 @@
import React from "react"
import React, { PropTypes } from "react"
export default class OnlineValidatorBadge extends React.Component {
static propTypes = {
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired
}
constructor(props, context) {
super(props, context)
let { specSelectors, getConfigs } = props
let { validatorUrl } = getConfigs()
this.state = {
url: specSelectors.url(),
validatorUrl: validatorUrl
validatorUrl: validatorUrl === undefined ? "https://online.swagger.io/validator" : validatorUrl
}
}
@@ -17,7 +23,7 @@ export default class OnlineValidatorBadge extends React.Component {
this.setState({
url: specSelectors.url(),
validatorUrl: validatorUrl
validatorUrl: validatorUrl === undefined ? "https://online.swagger.io/validator" : validatorUrl
})
}
@@ -27,14 +33,72 @@ export default class OnlineValidatorBadge extends React.Component {
if ( typeof spec === "object" && Object.keys(spec).length) return null
if (!this.state.url) {
if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf("localhost") >= 0
|| this.state.url.indexOf("127.0.0.1") >= 0) {
return null
}
return (<span style={{ float: "right"}}>
return (<span style={{ float: "right"}}>
<a target="_blank" href={`${ this.state.validatorUrl }/debug?url=${ this.state.url }`}>
<img alt="Online validator badge" src={`${ this.state.validatorUrl }?url=${ this.state.url }`} />
<ValidatorImage src={`${ this.state.validatorUrl }?url=${ this.state.url }`} alt="Online validator badge"/>
</a>
</span>)
}
}
class ValidatorImage extends React.Component {
static propTypes = {
src: PropTypes.string,
alt: PropTypes.string
}
constructor(props) {
super(props)
this.state = {
loaded: false,
error: false
}
}
componentDidMount() {
const img = new Image()
img.onload = () => {
this.setState({
loaded: true
})
}
img.onerror = () => {
this.setState({
error: true
})
}
img.src = this.props.src
}
componentWillReceiveProps(nextProps) {
if (nextProps.src !== this.props.src) {
const img = new Image()
img.onload = () => {
this.setState({
loaded: true
})
}
img.onerror = () => {
this.setState({
error: true
})
}
img.src = nextProps.src
}
}
render() {
if (this.state.error) {
return <img alt={"Error"} />
} else if (!this.state.loaded) {
return <img alt= {"Loading..."} />
}
return <img src={this.props.src} alt={this.props.alt} />
}
}

View File

@@ -1,5 +1,4 @@
import React, { PropTypes } from "react"
import { Map, fromJS } from "immutable"
import shallowCompare from "react-addons-shallow-compare"
import { getList } from "core/utils"
import * as CustomPropTypes from "core/proptypes"
@@ -112,9 +111,7 @@ export default class Operation extends React.Component {
specActions,
specSelectors,
authActions,
authSelectors,
layoutSelectors,
layoutActions,
authSelectors
} = this.props
let summary = operation.get("summary")
@@ -205,11 +202,12 @@ export default class Operation extends React.Component {
pathMethod={ [path, method] }
/>
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <Schemes schemes={ schemes }
path={ path }
method={ method }
specActions={ specActions }/>
: null
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <div className="opblock-schemes">
<Schemes schemes={ schemes }
path={ path }
method={ method }
specActions={ specActions }/>
</div> : null
}
<div className={(!tryItOutEnabled || !response || !allowTryItOut) ? "execute-wrapper" : "btn-group"}>

View File

@@ -1,5 +1,4 @@
import React, { PropTypes } from "react"
import {presets} from "react-motion"
export default class Operations extends React.Component {
@@ -33,7 +32,6 @@ export default class Operations extends React.Component {
const Operation = getComponent("operation")
const Collapse = getComponent("Collapse")
const Schemes = getComponent("schemes")
let showSummary = layoutSelectors.showSummary()
@@ -58,12 +56,6 @@ export default class Operations extends React.Component {
</small>
}
<button className="expand-methods" title="Expand all methods">
<svg className="expand" width="20" height="20">
<use xlinkHref="#expand" />
</svg>
</button>
<button className="expand-operation" title="Expand operation" onClick={() => layoutActions.show(isShownKey, !showTag)}>
<svg className="arrow" width="20" height="20">
<use xlinkHref={showTag ? "#large-arrow-down" : "#large-arrow"} />

View File

@@ -30,7 +30,6 @@ export default class Overview extends React.Component {
{
taggedOps.map( (tagObj, tag) => {
let operations = tagObj.get("operations")
let tagDetails = tagObj.get("tagDetails")
let showTagId = ["overview-tags", tag]
let showTag = layoutSelectors.isShown(showTagId, true)
@@ -45,7 +44,7 @@ export default class Overview extends React.Component {
<Collapse isOpened={showTag} animated>
{
operations.map( op => {
let { path, method, operation, id } = op.toObject() // toObject is shallow
let { path, method, id } = op.toObject() // toObject is shallow
let showOpIdPrefix = "operations"
let showOpId = id
let shown = layoutSelectors.isShown([showOpIdPrefix, showOpId])

View File

@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from "react"
import shallowCompare from "react-addons-shallow-compare"
import { Set, fromJS, List } from "immutable"
import { fromJS, List } from "immutable"
import { getSampleSchema } from "core/utils"
const NOOP = Function.prototype
@@ -50,14 +50,15 @@ export default class ParamBody extends Component {
}
updateValues = (props) => {
let { specSelectors, pathMethod, param, isExecute, consumesValue="", onChangeConsumes } = props
let { specSelectors, pathMethod, param, isExecute, consumesValue="" } = props
let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : {}
let isXml = /xml/i.test(consumesValue)
let paramValue = isXml ? parameter.get("value_xml") : parameter.get("value")
if ( paramValue ) {
this.setState({ value: paramValue })
this.onChange(paramValue, {isXml: isXml, isEditBox: isExecute})
if ( paramValue !== undefined ) {
let val = !paramValue && !isXml ? "{}" : paramValue
this.setState({ value: val })
this.onChange(val, {isXml: isXml, isEditBox: isExecute})
} else {
if (isXml) {
this.onChange(this.sample("xml"), {isXml: isXml, isEditBox: isExecute})

View File

@@ -28,11 +28,25 @@ export default class ParameterRow extends Component {
componentWillReceiveProps(props) {
let { specSelectors, pathMethod, param } = props
let example = param.get("example")
let defaultValue = param.get("default")
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let value = parameter ? parameter.get("value") : ""
if ( defaultValue !== undefined && value === undefined ) {
this.onChangeWrapper(defaultValue)
let paramValue = parameter ? parameter.get("value") : undefined
let enumValue = parameter ? parameter.get("enum") : undefined
let value
if ( paramValue !== undefined ) {
value = paramValue
} else if ( example !== undefined ) {
value = example
} else if ( defaultValue !== undefined) {
value = defaultValue
} else if ( param.get("required") && enumValue && enumValue.size ) {
value = enumValue.first()
}
if ( value !== undefined ) {
this.onChangeWrapper(value)
}
}

View File

@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from "react"
import ImPropTypes from "react-immutable-proptypes"
import Im, { fromJS } from "immutable"
import Im from "immutable"
// More readable, just iterate over maps, only
const eachMap = (iterable, fn) => iterable.valueSeq().filter(Im.Map.isMap).map(fn)
@@ -87,7 +87,7 @@ export default class Parameters extends Component {
</thead>
<tbody>
{
eachMap(parameters, (parameter, k) => (
eachMap(parameters, (parameter) => (
<ParameterRow fn={ fn }
getComponent={ getComponent }
param={ parameter }

View File

@@ -1,13 +1,21 @@
import React, { PropTypes } from "react"
import { fromJS } from 'immutable'
import { fromJS } from "immutable"
import { getSampleSchema } from "core/utils"
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
if ( examples && examples.size ) {
return examples.entrySeq().map( ([ key, example ]) => {
let exampleValue
try {
exampleValue = example && example.toJS ? example.toJS() : example
exampleValue = JSON.stringify(exampleValue)
}
catch(e) {
exampleValue = String(example)
}
return (<div key={ key }>
<h5>{ key }</h5>
<HighlightCode className="example" value={ example } />
<HighlightCode className="example" value={ exampleValue } />
</div>)
}).toArray()
}

View File

@@ -17,8 +17,6 @@ export default class Schemes extends React.Component {
}
onChange =( e ) => {
let { path, method, specActions } = this.props
this.setScheme( e.target.value )
}
@@ -33,7 +31,7 @@ export default class Schemes extends React.Component {
return (
<label htmlFor="schemes">
<span>Schemes</span>
<span className="schemes-title">Schemes</span>
<select onChange={ this.onChange }>
{ schemes.valueSeq().map(
( scheme ) => <option value={ scheme } key={ scheme }>{ scheme }</option>

View File

@@ -4,11 +4,13 @@ export default class TryItOutButton extends React.Component {
static propTypes = {
onTryoutClick: PropTypes.func,
onCancelClick: PropTypes.func,
enabled: PropTypes.bool, // Try it out is enabled, ie: the user has access to the form
};
static defaultProps = {
onTryoutClick: Function.prototype,
onCancelClick: Function.prototype,
enabled: false,
};