Merge branch 'master' into feature/validation_tooltips

This commit is contained in:
kyle
2017-11-10 18:40:14 -08:00
committed by GitHub
9 changed files with 67 additions and 48 deletions

View File

@@ -113,7 +113,7 @@ const SpecErrorItem = ( { error, jumpToLine } ) => {
}
function toTitleCase(str) {
return str
return (str || "")
.split(" ")
.map(substr => substr[0].toUpperCase() + substr.slice(1))
.join(" ")

View File

@@ -21,6 +21,10 @@ export default class ObjectModel extends Component {
let { specSelectors } = otherProps
let { isOAS3 } = specSelectors
if(!schema) {
return null
}
let description = schema.get("description")
let properties = schema.get("properties")
let additionalProperties = schema.get("additionalProperties")

View File

@@ -12,8 +12,10 @@ export default class Operation extends PureComponent {
method: PropTypes.string.isRequired,
operation: PropTypes.object.isRequired,
showSummary: PropTypes.bool,
isShown: PropTypes.bool.isRequired,
isShownKey: CustomPropTypes.arrayOrString.isRequired,
tagKey: PropTypes.string,
operationKey: PropTypes.string,
jumpToKey: CustomPropTypes.arrayOrString.isRequired,
allowTryItOut: PropTypes.bool,
@@ -52,38 +54,16 @@ export default class Operation extends PureComponent {
}
componentWillReceiveProps(nextProps) {
const defaultContentType = "application/json"
let { specActions, path, method, operation } = nextProps
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)
}
}
toggleShown =() => {
let { layoutActions, isShownKey } = this.props
layoutActions.show(isShownKey, !this.isShown())
}
let { layoutActions, tagKey, operationKey, isShown } = this.props
const isShownKey = ["operations", tagKey, operationKey]
isShown =() => {
let { layoutSelectors, isShownKey, getConfigs } = this.props
let { docExpansion } = getConfigs()
return layoutSelectors.isShown(isShownKey, docExpansion === "full" ) // Here is where we set the default
layoutActions.show(isShownKey, !isShown)
}
onTryoutClick =() => {
@@ -102,7 +82,9 @@ export default class Operation extends PureComponent {
render() {
let {
isShownKey,
operationKey,
tagKey,
isShown,
jumpToKey,
path,
method,
@@ -156,18 +138,17 @@ export default class Operation extends PureComponent {
}
let { tryItOutEnabled } = this.state
let shown = this.isShown()
let onChangeKey = [ path, method ] // Used to add values to _this_ operation ( indexed by path and method )
return (
<div className={deprecated ? "opblock opblock-deprecated" : shown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={isShownKey.join("-")} >
<div className={deprecated ? "opblock opblock-deprecated" : isShown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={`operations-${tagKey}-${operationKey}`} >
<div className={`opblock-summary opblock-summary-${method}`} onClick={this.toggleShown} >
<span className="opblock-summary-method">{method.toUpperCase()}</span>
<span className={ deprecated ? "opblock-summary-path__deprecated" : "opblock-summary-path" } >
<a
className="nostyle"
onClick={isDeepLinkingEnabled ? (e) => e.preventDefault() : null}
href={isDeepLinkingEnabled ? `#/${isShownKey[1]}/${isShownKey[2]}` : null}>
href={isDeepLinkingEnabled ? `#/${tagKey}/${operationKey}` : null}>
<span>{path}</span>
</a>
<JumpToPath path={jumpToKey} />
@@ -193,7 +174,7 @@ export default class Operation extends PureComponent {
}
</div>
<Collapse isOpened={shown}>
<Collapse isOpened={isShown}>
<div className="opblock-body">
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
{ description &&

View File

@@ -127,7 +127,8 @@ export default class Operations extends React.Component {
const operationId =
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id")
const isShownKey = ["operations", createDeepLinkPath(tag), createDeepLinkPath(operationId)]
const tagKey = createDeepLinkPath(tag)
const operationKey = createDeepLinkPath(operationId)
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method"))
const response = specSelectors.responseFor(op.get("path"), op.get("method"))
@@ -135,11 +136,12 @@ export default class Operations extends React.Component {
return <Operation
{...op.toObject()}
isShownKey={isShownKey}
tagKey={tagKey}
operationKey={operationKey}
isShown={layoutSelectors.isShown(["operations", tagKey, operationKey])}
jumpToKey={jumpToKey}
showSummary={showSummary}
key={isShownKey}
key={tagKey + operationKey}
response={ response }
request={ request }
allowTryItOut={allowTryItOut}

View File

@@ -3,6 +3,7 @@ import serializeError from "serialize-error"
export const NEW_THROWN_ERR = "err_new_thrown_err"
export const NEW_THROWN_ERR_BATCH = "err_new_thrown_err_batch"
export const NEW_SPEC_ERR = "err_new_spec_err"
export const NEW_SPEC_ERR_BATCH = "err_new_spec_err_batch"
export const NEW_AUTH_ERR = "err_new_auth_err"
export const CLEAR = "err_clear"
@@ -27,6 +28,13 @@ export function newSpecErr(err) {
}
}
export function newSpecErrBatch(errArray) {
return {
type: NEW_SPEC_ERR_BATCH,
payload: errArray
}
}
export function newAuthErr(err) {
return {
type: NEW_AUTH_ERR,

View File

@@ -2,6 +2,7 @@ import {
NEW_THROWN_ERR,
NEW_THROWN_ERR_BATCH,
NEW_SPEC_ERR,
NEW_SPEC_ERR_BATCH,
NEW_AUTH_ERR,
CLEAR
} from "./actions"
@@ -45,6 +46,15 @@ export default function(system) {
.update("errors", errors => transformErrors(errors, system.getSystem()))
},
[NEW_SPEC_ERR_BATCH]: (state, { payload }) => {
payload = payload.map(err => {
return fromJS(Object.assign(DEFAULT_ERROR_STRUCTURE, err, { type: "spec" }))
})
return state
.update("errors", errors => (errors || List()).concat( fromJS( payload )) )
.update("errors", errors => transformErrors(errors, system.getSystem()))
},
[NEW_AUTH_ERR]: (state, { payload }) => {
let error = fromJS(Object.assign({}, payload))

View File

@@ -494,8 +494,8 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
let listCheck = type === "array" && Im.List.isList(value) && value.count()
let fileCheck = type === "file" && value instanceof win.File
let booleanCheck = type === "boolean" && (value || value === false)
let numberCheck = type === "number" && value
let integerCheck = type === "integer" && value
let numberCheck = type === "number" && (value || value === 0)
let integerCheck = type === "integer" && (value || value === 0)
if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
errors.push("Required field is not provided")

View File

@@ -3,14 +3,16 @@
font-size: 12px;
font-weight: 300;
@include text_code();
.deprecated
{
span, td {
color: $model-deprecated-font-color !important;
}
span,
td
{
color: $model-deprecated-font-color !important;
}
}
@include text_code();
&-toggle
{
font-size: 10px;
@@ -87,7 +89,8 @@
background: rgba($model-hint-background-color,.7);
}
p {
p
{
margin: 0 0 1em 0;
}
}
@@ -106,6 +109,7 @@ section.models
h4
{
margin: 0 0 5px 0;
border-bottom: 1px solid rgba($section-models-isopen-h4-border-bottom-color, .3);
}
}
@@ -114,6 +118,7 @@ section.models
font-size: 16px;
display: flex;
align-items: center;
margin: 0;
padding: 10px 20px 10px 10px;
@@ -122,7 +127,6 @@ section.models
transition: all .2s;
@include text_headline($section-models-h4-font-color);
align-items: center;
svg
{
@@ -202,7 +206,7 @@ section.models
&.deprecated
{
opacity: .5;
opacity: .5;
}
}
@@ -218,14 +222,16 @@ section.models
{
font-size: 16px;
font-weight: 600;
margin-right: 1em;
@include text_headline($_color-delete);
}
span
{
> span.model
> span.model
{
.brace-close
{
@@ -237,8 +243,8 @@ span
.prop-name
{
display: inline-block;
margin-right: 1em;
width: 8em;
}
.prop-type

View File

@@ -700,6 +700,14 @@ describe("utils", function() {
}
assertValidateParam(param, ["Required field is not provided"])
// valid integer, but 0 is falsy in JS
param = {
required: true,
type: "integer",
value: 0
}
assertValidateParam(param, [])
// valid integer
param = {
required: true,