diff --git a/README.md b/README.md index a59a2203..753894c7 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,9 @@ You can use all of the following options with standalone version on tag * **function**: A getter function. Must return a number representing the offset (in pixels). * `showExtensions` - show vendor extensions ("x-" fields). Extensions used by ReDoc are ignored. Can be boolean or an array of `string` with names of extensions to display. * `sortPropsAlphabetically` - sort properties alphabetically. +* `sortTagsAlphabetically` - sort tags alphabetically. +* `sortOperationsAlphabetically` - sort operations alphabetically. +* `sortTagGroupsAlphabetically` - sort tag groups alphabetically. * `suppressWarnings` - if set, warnings are not rendered at the top of documentation (they still are logged to the console). * `payloadSampleIdx` - if set, payload sample will be inserted at this index or last. Indexes start from 0. * `theme` - ReDoc theme. For details check [theme docs](#redoc-theme-object). diff --git a/src/services/AppStore.ts b/src/services/AppStore.ts index 9387c521..bc4fc4f4 100644 --- a/src/services/AppStore.ts +++ b/src/services/AppStore.ts @@ -81,7 +81,7 @@ export class AppStore { MenuStore.updateOnHistory(history.currentId, this.scroll); this.spec = new SpecStore(spec, specUrl, this.options); - this.menu = new MenuStore(this.spec, this.scroll, history); + this.menu = new MenuStore(this.spec, this.scroll, history, this.options); if (!this.options.disableSearch) { this.search = new SearchStore(); diff --git a/src/services/MenuStore.ts b/src/services/MenuStore.ts index ac60fee8..2afd10a7 100644 --- a/src/services/MenuStore.ts +++ b/src/services/MenuStore.ts @@ -8,6 +8,8 @@ import { ScrollService } from './ScrollService'; import { flattenByProp, SECURITY_SCHEMES_SECTION_PREFIX } from '../utils'; import { GROUP_DEPTH } from './MenuBuilder'; +import {RedocNormalizedOptions} from "./RedocNormalizedOptions"; + export type MenuItemGroupType = 'group' | 'tag' | 'section'; export type MenuItemType = MenuItemGroupType | 'operation'; @@ -74,12 +76,45 @@ export class MenuStore { * * @param spec [SpecStore](#SpecStore) which contains page content structure * @param scroll scroll service instance used by this menu + * @param history + * @param options */ - constructor(spec: SpecStore, public scroll: ScrollService, public history: HistoryService) { + constructor(spec: SpecStore, public scroll: ScrollService, public history: HistoryService, public options: RedocNormalizedOptions) { makeObservable(this); + const alphaSort = items => items.sort((a, b) => a.name.localeCompare(b.name)); this.items = spec.contentItems; + if (this.options.sortTagGroupsAlphabetically) { + const groups = this.items.filter(item => item.type === "group"); + alphaSort(groups); + this.items = this.items.filter(item => item.type !== "group").concat(groups); + } + + if (this.options.sortTagsAlphabetically) { + const tags = this.items.filter(item => item.type === "tag"); + alphaSort(tags); + this.items = this.items.filter(item => item.type !== "tag").concat(tags); + this.items.map(item => { + if(item.type === "group") { + alphaSort(item.items); + }}); + } + + if (this.options.sortOperationsAlphabetically) { + this.items.map(item => { + if(item.type === "tag") { + alphaSort(item.items); + } else if (item.type === "group") { + item.items.map(groupItem => { + if(groupItem.type === "tag") { + alphaSort(item.items); + } + }); + } + }); + } + this.flatItems = flattenByProp(this.items || [], 'items'); this.flatItems.forEach((item, idx) => (item.absoluteIdx = idx)); diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index 58d4b8b0..5bebf58e 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -13,6 +13,9 @@ export interface RedocRawOptions { requiredPropsFirst?: boolean | string; sortPropsAlphabetically?: boolean | string; sortEnumValuesAlphabetically?: boolean | string; + sortTagGroupsAlphabetically?: boolean | string; + sortTagsAlphabetically?: boolean | string; + sortOperationsAlphabetically?: boolean | string; noAutoAuth?: boolean | string; nativeScrollbars?: boolean | string; pathInMiddlePanel?: boolean | string; @@ -170,6 +173,9 @@ export class RedocNormalizedOptions { requiredPropsFirst: boolean; sortPropsAlphabetically: boolean; sortEnumValuesAlphabetically: boolean; + sortTagGroupsAlphabetically: boolean; + sortTagsAlphabetically: boolean; + sortOperationsAlphabetically: boolean; noAutoAuth: boolean; nativeScrollbars: boolean; pathInMiddlePanel: boolean; @@ -227,6 +233,9 @@ export class RedocNormalizedOptions { this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst); this.sortPropsAlphabetically = argValueToBoolean(raw.sortPropsAlphabetically); this.sortEnumValuesAlphabetically = argValueToBoolean(raw.sortEnumValuesAlphabetically); + this.sortTagGroupsAlphabetically = argValueToBoolean(raw.sortTagGroupsAlphabetically); + this.sortTagsAlphabetically = argValueToBoolean(raw.sortTagsAlphabetically); + this.sortOperationsAlphabetically = argValueToBoolean(raw.sortOperationsAlphabetically); this.noAutoAuth = argValueToBoolean(raw.noAutoAuth); this.nativeScrollbars = argValueToBoolean(raw.nativeScrollbars); this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);