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() ?

No parameters

: -
- - + {!groupedParametersArr.length ?

No parameters

: +
+
+ - - + + { - eachMap(parameters, (parameter, i) => ( + groupedParametersArr.map((parameter, i) => ( - )).toArray() + pathMethod={pathMethod} + isExecute={isExecute} /> + )) } - -
Name Description
-
- } -
: 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) + } + }) + }) +})