From 4f31adaa236e103a6f55ef865f5e408ce9f115db Mon Sep 17 00:00:00 2001 From: Xiaoyu Guo Date: Tue, 9 Jan 2018 14:24:10 +0100 Subject: [PATCH 1/3] Add support to "examples" as per OpenAPI 3.0.0 spec Merged from https://github.com/swagger-api/swagger-ui/pull/3616, then collected and re-applied the diff to have a nice git history --- src/core/components/model-example.jsx | 40 ++++++++++++++++- src/core/components/parameter-row.jsx | 39 +++++++++++++--- src/core/components/response.jsx | 17 ++++++- .../oas3/components/external-value.jsx | 33 ++++++++++++++ src/core/plugins/oas3/components/index.js | 3 ++ .../plugins/oas3/components/request-body.jsx | 4 ++ src/core/plugins/oas3/utils.js | 26 +++++++++++ src/style/_layout.scss | 44 ++++++++++++------- 8 files changed, 181 insertions(+), 25 deletions(-) create mode 100644 src/core/plugins/oas3/components/external-value.jsx create mode 100644 src/core/plugins/oas3/utils.js diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx index e7d13adafaf..02c19da9080 100644 --- a/src/core/components/model-example.jsx +++ b/src/core/components/model-example.jsx @@ -8,6 +8,7 @@ export default class ModelExample extends React.Component { specSelectors: PropTypes.object.isRequired, schema: PropTypes.object.isRequired, example: PropTypes.any.isRequired, + examples: ImPropTypes.orderedMap, isExecute: PropTypes.bool, getConfigs: PropTypes.func.isRequired, specPath: ImPropTypes.list.isRequired, @@ -15,6 +16,7 @@ export default class ModelExample extends React.Component { constructor(props, context) { super(props, context) + let { getConfigs } = this.props let { defaultModelRendering } = getConfigs() if (defaultModelRendering !== "example" && defaultModelRendering !== "model") { @@ -33,16 +35,36 @@ export default class ModelExample extends React.Component { }) } + formatValue = (value) => { + if(typeof(value) === "string") { + return value + } else { + return JSON.stringify(value, null, 2) + } + } + render() { - let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath } = this.props + let { getComponent, specSelectors, schema, example, examples, isExecute, getConfigs, specPath } = this.props let { defaultModelExpandDepth } = getConfigs() const ModelWrapper = getComponent("ModelWrapper") + const HighlightCode = getComponent("highlightCode") + const Markdown = getComponent("Markdown") + const ExternalValue = getComponent("ExternalValue") + // TODO fetch externalValue and display it on demand return
} diff --git a/src/core/plugins/oas3/utils.js b/src/core/plugins/oas3/utils.js new file mode 100644 index 00000000000..f46542097f0 --- /dev/null +++ b/src/core/plugins/oas3/utils.js @@ -0,0 +1,26 @@ +import memoizee from "memoizee" +import { fromJS } from "immutable" + +/** + * Convert OAS3 "Examples" (in requestBody) section and convert to Map + * @param examplesInSpec {object} "examples" in OAS3 spec + * @returns {Map} Map {name: {summary, description, value, externalValue}} + */ +export const getExamples = (examplesInSpec) => { + return fromJS(examplesInSpec) +} + +export const memoizedGetExamples = memoizee(getExamples) + +/** + * Convert 'value' to serialized format, so can be handled correctly in + * @param value value + */ +export const formatParamValue = (value) => { + if (typeof ( value ) === "string") { + return value + } else { + // TODO apply 'style', 'explode', 'allowReserved' in OAS3 + return JSON.stringify(value, null, 2) + } +} diff --git a/src/style/_layout.scss b/src/style/_layout.scss index 812f461eccc..f54f0aefbd5 100644 --- a/src/style/_layout.scss +++ b/src/style/_layout.scss @@ -396,33 +396,29 @@ { font-size: 12px; - min-width: 100px; - min-width: 90px; padding: 0; cursor: pointer; @include text_headline(); - &:first-of-type - { - position: relative; + position: relative; - padding-left: 0; + padding-left: 0; + padding-right: 5px; + margin-right: 5px; - &:after - { - position: absolute; - top: 0; - right: 6px; - - width: 1px; - height: 100%; + &:nth-last-child(n+2):after + { + position: absolute; + top: 0; + right: 0; - content: ''; + width: 1px; + height: 100%; - background: rgba($tab-list-item-first-background-color,.2); - } + content: ''; + background: rgba($tab-list-item-first-background-color,.2); } &.active @@ -796,3 +792,17 @@ a.nostyle { cursor: pointer; } } + +/* OAS3 responseBody examples start */ +.example-description { + margin: 0 0 5px 0; + padding: 5px 0; +} + +/* .example-summary is the summary line of parameter examples */ +.example-summary { + margin: 0; + /* use the same font as .opblock-summary-description */ + @include text_body(); +} +/* OAS3 responseBody examples end */ From b4cef6ad4209820c10a8f513d432b4f16cc01723 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 9 Jan 2018 17:48:00 +0100 Subject: [PATCH 2/3] Shows first examples if "examples" is specified, and hides main "example" --- src/core/components/model-example.jsx | 13 +++++++++---- src/core/components/parameter-row.jsx | 6 ------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx index 02c19da9080..ff50d3cf1d9 100644 --- a/src/core/components/model-example.jsx +++ b/src/core/components/model-example.jsx @@ -17,11 +17,14 @@ export default class ModelExample extends React.Component { constructor(props, context) { super(props, context) - let { getConfigs } = this.props + let { getConfigs, examples } = this.props let { defaultModelRendering } = getConfigs() if (defaultModelRendering !== "example" && defaultModelRendering !== "model") { defaultModelRendering = "example" } + if (defaultModelRendering === "example" && examples) { + defaultModelRendering = `example_${ examples.keySeq().first() }` + } this.state = { activeTab: defaultModelRendering } @@ -54,9 +57,11 @@ export default class ModelExample extends React.Component { // TODO fetch externalValue and display it on demand return
    -
  • - Example Value -
  • + { !examples && example && +
  • + Example Value +
  • + } { examples && examples.map( (item, key) => { return ( !isExecute &&
  • diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 10f2d7bd5cb..97fd931b24b 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -154,12 +154,6 @@ export default class ParameterRow extends Component { if (paramExample === undefined) { paramExample = param.get("x-example") } - - if(paramExample) { - paramExample = - } else { - paramExample = - } } } From 7a79c61309d616f321099c20723015c8dfac1196 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 9 Jan 2018 17:48:41 +0100 Subject: [PATCH 3/3] Removed a "isRequired" property not passed from callers, and removed a undefined param --- src/core/components/model-wrapper.jsx | 2 +- src/core/components/parameter-row.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/components/model-wrapper.jsx b/src/core/components/model-wrapper.jsx index fe878d613b3..817e7601e83 100644 --- a/src/core/components/model-wrapper.jsx +++ b/src/core/components/model-wrapper.jsx @@ -15,7 +15,7 @@ export default class ModelWrapper extends Component { specSelectors: PropTypes.object.isRequired, expandDepth: PropTypes.number, layoutActions: PropTypes.object, - layoutSelectors: PropTypes.object.isRequired + layoutSelectors: PropTypes.object } onToggle = (name,isShown) => { diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 97fd931b24b..e058ddb59fd 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -198,7 +198,7 @@ export default class ParameterRow extends Component { { bodyParam || !isExecute ? null :