From ecf33d2dca161cac374b41dc07dfb516f6a8ddcc Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Mon, 19 Feb 2018 13:31:18 +0200 Subject: [PATCH] feat: reqired-first sort order for params --- src/components/SideMenu/MenuItem.tsx | 10 ++++++++-- src/services/models/Operation.ts | 12 +++++++++++- src/services/models/Schema.ts | 17 ++--------------- src/utils/openapi.ts | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/components/SideMenu/MenuItem.tsx b/src/components/SideMenu/MenuItem.tsx index bc3ba51378..a4f2f1c198 100644 --- a/src/components/SideMenu/MenuItem.tsx +++ b/src/components/SideMenu/MenuItem.tsx @@ -47,14 +47,20 @@ export class MenuItem extends React.Component { export interface OperationMenuItemContentProps { item: OperationModel; + className?: string; } @observer class OperationMenuItemContent extends React.Component { render() { - const { item } = this.props; + const { item, className } = this.props; return ( - + {item.name} diff --git a/src/services/models/Operation.ts b/src/services/models/Operation.ts index 846bfd62cd..cc790913fc 100644 --- a/src/services/models/Operation.ts +++ b/src/services/models/Operation.ts @@ -8,7 +8,13 @@ import { SecurityRequirementModel } from './SecurityRequirement'; import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types'; -import { getOperationSummary, isAbsolutePath, JsonPointer, stripTrailingSlash } from '../../utils'; +import { + getOperationSummary, + isAbsolutePath, + JsonPointer, + stripTrailingSlash, + sortByRequired, +} from '../../utils'; import { ContentItemModel, ExtendedOpenAPIOperation } from '../MenuBuilder'; import { OpenAPIParser } from '../OpenAPIParser'; import { RedocNormalizedOptions } from '../RedocNormalizedOptions'; @@ -77,6 +83,10 @@ export class OperationModel implements IMenuItem { .concat(operationSpec.parameters || []) .map(paramOrRef => new FieldModel(parser, paramOrRef, this._$ref, options)); + if (options.requiredPropsFirst) { + sortByRequired(this.parameters); + } + let hasSuccessResponses = false; this.responses = Object.keys(operationSpec.responses || []) .filter(code => { diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index c12aa4042e..bddd68d111 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -13,6 +13,7 @@ import { isNamedDefinition, isPrimitiveType, JsonPointer, + sortByRequired, } from '../../utils/'; // TODO: refactor this model, maybe use getters instead of copying all the values @@ -226,7 +227,7 @@ function buildFields( }); if (options.requiredPropsFirst) { - sortFields(fields, schema.required); + sortByRequired(fields, schema.required); } if (typeof additionalProps === 'object') { @@ -246,17 +247,3 @@ function buildFields( return fields; } - -function sortFields(fields: FieldModel[], order: string[] = []) { - fields.sort((a, b) => { - if (!a.required && b.required) { - return 1; - } else if (a.required && !b.required) { - return -1; - } else if (a.required && b.required) { - return order.indexOf(a.name) > order.indexOf(b.name) ? 1 : -1; - } else { - return 0; - } - }); -} diff --git a/src/utils/openapi.ts b/src/utils/openapi.ts index 7ea0236970..2f9d1f7f1e 100644 --- a/src/utils/openapi.ts +++ b/src/utils/openapi.ts @@ -161,4 +161,21 @@ export function humanizeConstraints(schema: OpenAPISchema): string[] { return res; } +export function sortByRequired( + fields: { required: boolean; name: string }[], + order: string[] = [], +) { + fields.sort((a, b) => { + if (!a.required && b.required) { + return 1; + } else if (a.required && !b.required) { + return -1; + } else if (a.required && b.required) { + return order.indexOf(a.name) > order.indexOf(b.name) ? 1 : -1; + } else { + return 0; + } + }); +} + export const SECURITY_SCHEMES_SECTION = 'section/Authentication/';