diff --git a/src/core/components/parameters/parameters.jsx b/src/core/components/parameters/parameters.jsx
index a1bb9eb6..d09700dd 100644
--- a/src/core/components/parameters/parameters.jsx
+++ b/src/core/components/parameters/parameters.jsx
@@ -1,20 +1,17 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
-import Im, { Map, List } from "immutable"
+import { Map, List } from "immutable"
import ImPropTypes from "react-immutable-proptypes"
-// More readable, just iterate over maps, only
-const eachMap = (iterable, fn) => iterable.valueSeq().filter(Im.Map.isMap).map(fn)
-
export default class Parameters extends Component {
constructor(props) {
- super(props)
- this.state = {
- callbackVisible: false,
- parametersVisible: true
- }
- }
+ super(props)
+ this.state = {
+ callbackVisible: false,
+ parametersVisible: true,
+ }
+ }
static propTypes = {
parameters: ImPropTypes.list.isRequired,
@@ -45,7 +42,7 @@ export default class Parameters extends Component {
specPath: [],
}
- onChange = ( param, value, isXml ) => {
+ onChange = (param, value, isXml) => {
let {
specActions: { changeParamByIdentity },
onChangeKey,
@@ -54,30 +51,30 @@ export default class Parameters extends Component {
changeParamByIdentity(onChangeKey, param, value, isXml)
}
- onChangeConsumesWrapper = ( val ) => {
+ onChangeConsumesWrapper = (val) => {
let {
specActions: { changeConsumesValue },
- onChangeKey
+ onChangeKey,
} = this.props
changeConsumesValue(onChangeKey, val)
}
toggleTab = (tab) => {
- if(tab === "parameters"){
+ if (tab === "parameters") {
return this.setState({
parametersVisible: true,
- callbackVisible: false
+ callbackVisible: false,
})
- }else if(tab === "callbacks"){
+ } else if (tab === "callbacks") {
return this.setState({
callbackVisible: true,
- parametersVisible: false
+ parametersVisible: false,
})
}
}
- onChangeMediaType = ( { value, pathMethod } ) => {
+ onChangeMediaType = ({ value, pathMethod }) => {
let { specSelectors, specActions, oas3Selectors, oas3Actions } = this.props
let targetMediaType = value
let currentMediaType = oas3Selectors.requestContentType(...pathMethod)
@@ -92,7 +89,7 @@ export default class Parameters extends Component {
oas3Actions.initRequestBodyValidateError({ pathMethod })
}
- render(){
+ render() {
let {
onTryoutClick,
@@ -110,7 +107,7 @@ export default class Parameters extends Component {
pathMethod,
oas3Actions,
oas3Selectors,
- operation
+ operation,
} = this.props
const ParameterRow = getComponent("parameterRow")
@@ -124,17 +121,29 @@ export default class Parameters extends Component {
const requestBody = operation.get("requestBody")
+
+ const groupedParametersArr = Object.values(parameters
+ .reduce((acc, x) => {
+ const key = x.get("in")
+ acc[key] ??= []
+ acc[key].push(x)
+ return acc
+ }, {}))
+ .reduce((acc, x) => acc.concat(x), [])
+
return (
- { isOAS3 ? (
-
-
this.toggleTab("parameters")} className={`tab-item ${this.state.parametersVisible && "active"}`}>
+ {isOAS3 ? (
+
+
this.toggleTab("parameters")}
+ className={`tab-item ${this.state.parametersVisible && "active"}`}>
Parameters
- { operation.get("callbacks") ?
+ {operation.get("callbacks") ?
(
-
this.toggleTab("callbacks")} className={`tab-item ${this.state.callbackVisible && "active"}`}>
+
this.toggleTab("callbacks")}
+ className={`tab-item ${this.state.callbackVisible && "active"}`}>
Callbacks
) : null
@@ -142,65 +151,66 @@ export default class Parameters extends Component {
) : (
-
Parameters
-
+
Parameters
+
)}
- { allowTryItOut ? (
-
- ) : null }
+ {allowTryItOut ? (
+
+ ) : null}
{this.state.parametersVisible ?
- { !parameters.count() ?
:
-
-
-
+ {!groupedParametersArr.length ? :
+
+
+
| Name |
Description |
-
-
+
+
{
- eachMap(parameters, (parameter, i) => (
+ groupedParametersArr.map((parameter, i) => (
- )).toArray()
+ pathMethod={pathMethod}
+ isExecute={isExecute} />
+ ))
}
-
-
-
- }
- : null }
+
+
+
+ }
+
: null}
{this.state.callbackVisible ?
-
: null }
+
: null}
{
isOAS3 && requestBody && this.state.parametersVisible &&
-
Request body
+ Request
+ body
}
diff --git a/test/e2e-cypress/static/documents/features/parameter-order.yaml b/test/e2e-cypress/static/documents/features/parameter-order.yaml
new file mode 100644
index 00000000..2f22742a
--- /dev/null
+++ b/test/e2e-cypress/static/documents/features/parameter-order.yaml
@@ -0,0 +1,63 @@
+openapi: 3.0.1
+info:
+ title: Example Swagger
+ version: '1.0'
+servers:
+ - url: /api/v1
+paths:
+ /test/{id}/related/{relatedId}:
+ post:
+ parameters:
+ - in: path
+ name: relatedId
+ required: true
+ schema:
+ type: integer
+ default: 1
+ description: The related ID
+ - in: header
+ name: TRACE-ID
+ required: true
+ schema:
+ type: integer
+ default: 1
+ description: The trace ID
+ - in: cookie
+ name: debug
+ required: true
+ schema:
+ type: number
+ enum:
+ - 0
+ - 1
+ description: debug flag
+ - in: header
+ name: USER-ID
+ required: true
+ schema:
+ type: integer
+ default: 1
+ description: The user ID
+ - in: query
+ name: asc
+ required: true
+ schema:
+ type: boolean
+ default: true
+ description: sort asc
+ - in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ default: 1
+ description: The ID
+ requestBody:
+ description: Some
+ content:
+ application/json:
+ schema:
+ type: string
+ responses:
+ 200:
+ description: Some
\ No newline at end of file
diff --git a/test/e2e-cypress/tests/features/parameter-order.js b/test/e2e-cypress/tests/features/parameter-order.js
new file mode 100644
index 00000000..f6509292
--- /dev/null
+++ b/test/e2e-cypress/tests/features/parameter-order.js
@@ -0,0 +1,30 @@
+describe("Parameter order", () => {
+
+ it("should be well ordered", () => {
+ cy.visit("/?url=/documents/features/parameter-order.yaml")
+ .get("#operations-default-post_test__id__related__relatedId_")
+ .click()
+ .get(".parameters > tbody")
+ .children()
+ .each((tr, i, arr) => {
+ const parameterTableRows = Array.from(arr)
+ expect(tr).to.have.attr("data-param-in")
+ if (i === 0) {
+ return
+ }
+ const inValue = tr[0].getAttribute("data-param-in")
+ if (!inValue) {
+ return
+ }
+ const beforeInValue = parameterTableRows[i - 1].getAttribute("data-param-in")
+ const sameAsBefore = beforeInValue === inValue
+ if (sameAsBefore) {
+ expect(parameterTableRows[i - 1]).to.have.attr("data-param-in", inValue)
+ return
+ }
+ for (let x = i + 1; x < parameterTableRows.length; x++) {
+ expect(parameterTableRows[x]).to.not.have.attr("data-param-in", beforeInValue)
+ }
+ })
+ })
+})