mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-06 05:10:20 +03:00
Small fixes, update docs and readme
This commit is contained in:
parent
5fff1c5002
commit
43527b197d
|
@ -130,6 +130,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
|||
* [`x-displayName`](docs/redoc-vendor-extensions.md#x-displayname) - specify human-friendly names for the menu categories
|
||||
* [`x-tagGroups`](docs/redoc-vendor-extensions.md#x-tagGroups) - group tags by categories in the side menu
|
||||
* [`x-servers`](docs/redoc-vendor-extensions.md#x-servers) - ability to specify different servers for API (backported from OpenAPI 3.0)
|
||||
* [`x-sort-order`](docs/redoc-vendor-extensions.md#x-sort-order) - specify custom sorting for endpoints
|
||||
|
||||
### `<redoc>` tag attributes
|
||||
* `spec-url` - relative or absolute url to your spec file;
|
||||
|
|
|
@ -243,3 +243,40 @@ PayPalPayment:
|
|||
|
||||
In the example above the names of definitions (`PayPalPayment`) are named differently than
|
||||
names in the payload (`paypal`) which is not supported by default `discriminator`.
|
||||
|
||||
### Sort endpoints vendor extensions
|
||||
#### x-sort-order
|
||||
| Field Name | Type | Description |
|
||||
| :------------- | :------: | :---------- |
|
||||
| x-sort-order | int | specifies sorting order |
|
||||
|
||||
###### Usage in ReDoc
|
||||
By using `x-sort-order` you can override default alphabetical sorting and arrange elements in any way you want.
|
||||
|
||||
|
||||
Add `x-sort-order` with number from 0 to number of elements in group - 1 (e.g. for 3 items, the scope is 0-2).
|
||||
Endpoints with lower `x-sort-order` number come first in a group.
|
||||
|
||||
###### x-sort-order example
|
||||
|
||||
```
|
||||
/store/inventory:
|
||||
get:
|
||||
tags:
|
||||
- store
|
||||
summary: Return pet inventories by status
|
||||
x-sort-order: 1
|
||||
description: Returns a map of status codes to quantities
|
||||
|
||||
/store/order:
|
||||
post:
|
||||
tags:
|
||||
- store
|
||||
summary: Place an order for a pet
|
||||
x-sort-order: 0
|
||||
description: Places an order for a pet
|
||||
|
||||
```
|
||||
|
||||
In this example "Place an order for a pet" endpoint will come before "Return pet inventories by status"
|
||||
(because of the `x-sort-order` property).
|
188
lib/components/SideMenu/fixed-array.ts
Normal file
188
lib/components/SideMenu/fixed-array.ts
Normal file
|
@ -0,0 +1,188 @@
|
|||
export let fixedMenuItemsList =
|
||||
[
|
||||
{
|
||||
name: "Pagination",
|
||||
id: "section/Pagination",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "JSONP",
|
||||
id: "section/JSONP",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "Authentication",
|
||||
id: "section/Authentication",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "pet",
|
||||
id: "tag/pet",
|
||||
items: [
|
||||
{
|
||||
name: "Deletes a pet",
|
||||
id: "/paths/~1pet~1{petId}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Find pet by ID",
|
||||
id: "/paths/~1pet~1{petId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Add a new pet to the store",
|
||||
id: "/paths/~1pet/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Updates a pet in the store with form data",
|
||||
id: "/paths/~1pet~1{petId}/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "uploads an image",
|
||||
id: "/paths/~1pet~1{petId}~1uploadImage/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Update an existing pet",
|
||||
id: "/paths/~1pet/put",
|
||||
metadata: {operation: "put"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "store",
|
||||
id: "tag/store",
|
||||
items: [
|
||||
{
|
||||
name: "Delete purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Find purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Returns pet inventories by status",
|
||||
id: "/paths/~1store~1inventory/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Place an order for a pet",
|
||||
id: "/paths/~1store~1order/post",
|
||||
metadata: {operation: "post"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
id: "tag/user",
|
||||
items: [
|
||||
{
|
||||
name: "Delete user",
|
||||
id: "/paths/~1user~1{username}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Get user by user name",
|
||||
id: "/paths/~1user~1{username}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Logs out current logged in user session",
|
||||
id: "/paths/~1user~1logout/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Logs user into the system",
|
||||
id: "/paths/~1user~1login/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Create user",
|
||||
id: "/paths/~1user/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Creates list of users with given input array",
|
||||
id: "/paths/~1user~1createWithArray/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Creates list of users with given input array",
|
||||
id: "/paths/~1user~1createWithList/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Updated user",
|
||||
id: "/paths/~1user~1{username}/put",
|
||||
metadata: {operation: "put"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Pagination",
|
||||
id: "tag/Pagination",
|
||||
items: [
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "JSONP",
|
||||
id: "tag/JSONP",
|
||||
items: [
|
||||
{
|
||||
name: "Find pet by ID",
|
||||
id: "/paths/~1pet~1{petId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Find purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Get user by user name",
|
||||
id: "/paths/~1user~1{username}/get",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Returns pet inventories by status",
|
||||
id: "/paths/~1store~1inventory/get",
|
||||
metadata: {operation: "post"}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
|
@ -3,7 +3,8 @@
|
|||
import { getChildDebugElement } from '../../../tests/helpers';
|
||||
import { Component } from '@angular/core';
|
||||
import { OptionsService, MenuItem } from '../../services/index';
|
||||
import { compareEndpoints, menuItemsList } from './sort';
|
||||
import { endpointComparator } from './sort';
|
||||
import { fixedMenuItemsList } from './fixed-array';
|
||||
|
||||
import {
|
||||
inject,
|
||||
|
@ -66,12 +67,14 @@ describe('Redoc components', () => {
|
|||
});
|
||||
|
||||
it('should confirm that component is sorted', () => {
|
||||
for(var i=0;i<menuItemsList.length;i++) {
|
||||
if(menuItemsList[i].items !== null){
|
||||
for(var j=0;j<menuItemsList[i].items.length;j++){
|
||||
component.menuItems[i].items[j].name.should.be.equal(menuItemsList[i].items[j].name);
|
||||
}
|
||||
let firstMenuItemsListLength = fixedMenuItemsList.length;
|
||||
for(var firstMenuItemIndex = 0; firstMenuItemIndex < firstMenuItemsListLength; firstMenuItemIndex++) {
|
||||
if(fixedMenuItemsList[firstMenuItemIndex].items !== null) {
|
||||
let secondMenuItemsListLength = fixedMenuItemsList[firstMenuItemIndex].items.length;
|
||||
for(var secondMenuItemIndex = 0; secondMenuItemIndex < secondMenuItemsListLength; secondMenuItemIndex++) {
|
||||
component.menuItems[firstMenuItemIndex].items[secondMenuItemIndex].name.should.be.equal(fixedMenuItemsList[firstMenuItemIndex].items[secondMenuItemIndex].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { trigger, state, animate, transition, style } from '@angular/core';
|
|||
import { ScrollService, MenuService, OptionsService, MenuItem } from '../../services/';
|
||||
import { PerfectScrollbar } from '../../shared/components';
|
||||
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
||||
import { compareEndpoints, menuItemsList } from './sort';
|
||||
import { endpointComparator } from './sort';
|
||||
|
||||
const global = window;
|
||||
|
||||
|
@ -114,14 +114,18 @@ export class SideMenu implements OnInit, OnDestroy {
|
|||
|
||||
init() {
|
||||
this.menuItems = this.menuService.items;
|
||||
let firstMenuItemsLength = this.menuItems.length;
|
||||
|
||||
for(var i=0;i<this.menuItems.length;i++){
|
||||
if(this.menuItems[i].items !== null){
|
||||
for(var j=0;j<this.menuItems[i].items.length;j++){
|
||||
if(this.menuItems[i].items[j].items == null)
|
||||
this.menuItems[i].items.sort(compareEndpoints);
|
||||
else
|
||||
this.menuItems[i].items[j].items.sort(compareEndpoints);
|
||||
for(var firstMenuItemIndex = 0; firstMenuItemIndex < firstMenuItemsLength; firstMenuItemIndex++) {
|
||||
if(this.menuItems[firstMenuItemIndex].items !== null) {
|
||||
let secondMenuItemsLength = this.menuItems[firstMenuItemIndex].items.length;
|
||||
for(var secondMenuItemIndex = 0; secondMenuItemIndex < secondMenuItemsLength; secondMenuItemIndex++) {
|
||||
if(this.menuItems[firstMenuItemIndex].items[secondMenuItemIndex].items == null) {
|
||||
this.menuItems[firstMenuItemIndex].items.sort(endpointComparator);
|
||||
}
|
||||
else{
|
||||
this.menuItems[firstMenuItemIndex].items[secondMenuItemIndex].items.sort(endpointComparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,204 +1,23 @@
|
|||
export const compareEndpoints = (a,b) => {
|
||||
export const endpointComparator = (a, b) => {
|
||||
let sortOrderComparisonResult: number;
|
||||
if(a.metadata.sortOrder != null && b.metadata.sortOrder != null)
|
||||
sortOrderComparisonResult = a.metadata.sortOrder.localeCompare(b.metadata.sortOrder);
|
||||
let operationComparisonResult: number;
|
||||
if(a.metadata.operation != null && b.metadata.operation != null)
|
||||
operationComparisonResult = a.metadata.operation.localeCompare(b.metadata.operation);
|
||||
let nameComparisonResult: number = a.name.localeCompare(b.name);
|
||||
|
||||
if(sortOrderComparisonResult != null && sortOrderComparisonResult !== 0)
|
||||
return sortOrderComparisonResult;
|
||||
else if(operationComparisonResult != null && operationComparisonResult !== 0)
|
||||
return operationComparisonResult;
|
||||
else
|
||||
return nameComparisonResult;
|
||||
}
|
||||
export let menuItemsList =
|
||||
[
|
||||
{
|
||||
name: "Pagination",
|
||||
id: "section/Pagination",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "JSONP",
|
||||
id: "section/JSONP",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "Authentication",
|
||||
id: "section/Authentication",
|
||||
items: []
|
||||
},
|
||||
{
|
||||
name: "pet",
|
||||
id: "tag/pet",
|
||||
items: [
|
||||
{
|
||||
name: "Deletes a pet",
|
||||
id: "/paths/~1pet~1{petId}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Find pet by ID",
|
||||
id: "/paths/~1pet~1{petId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Add a new pet to the store",
|
||||
id: "/paths/~1pet/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Updates a pet in the store with form data",
|
||||
id: "/paths/~1pet~1{petId}/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "uploads an image",
|
||||
id: "/paths/~1pet~1{petId}~1uploadImage/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Update an existing pet",
|
||||
id: "/paths/~1pet/put",
|
||||
metadata: {operation: "put"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "store",
|
||||
id: "tag/store",
|
||||
items: [
|
||||
{
|
||||
name: "Delete purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Find purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Returns pet inventories by status",
|
||||
id: "/paths/~1store~1inventory/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Place an order for a pet",
|
||||
id: "/paths/~1store~1order/post",
|
||||
metadata: {operation: "post"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
id: "tag/user",
|
||||
items: [
|
||||
{
|
||||
name: "Delete user",
|
||||
id: "/paths/~1user~1{username}/delete",
|
||||
metadata: {operation: "delete"}
|
||||
},
|
||||
{
|
||||
name: "Get user by user name",
|
||||
id: "/paths/~1user~1{username}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Logs out current logged in user session",
|
||||
id: "/paths/~1user~1logout/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Logs user into the system",
|
||||
id: "/paths/~1user~1login/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Create user",
|
||||
id: "/paths/~1user/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Creates list of users with given input array",
|
||||
id: "/paths/~1user~1createWithArray/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Creates list of users with given input array",
|
||||
id: "/paths/~1user~1createWithList/post",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Updated user",
|
||||
id: "/paths/~1user~1{username}/put",
|
||||
metadata: {operation: "put"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Pagination",
|
||||
id: "tag/Pagination",
|
||||
items: [
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "JSONP",
|
||||
id: "tag/JSONP",
|
||||
items: [
|
||||
{
|
||||
name: "Find pet by ID",
|
||||
id: "/paths/~1pet~1{petId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Find purchase order by ID",
|
||||
id: "/paths/~1store~1order~1{orderId}/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by status",
|
||||
id: "/paths/~1pet~1findByStatus/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Finds Pets by tags",
|
||||
id: "/paths/~1pet~1findByTags/get",
|
||||
metadata: {operation: "get"}
|
||||
},
|
||||
{
|
||||
name: "Get user by user name",
|
||||
id: "/paths/~1user~1{username}/get",
|
||||
metadata: {operation: "post"}
|
||||
},
|
||||
{
|
||||
name: "Returns pet inventories by status",
|
||||
id: "/paths/~1store~1inventory/get",
|
||||
metadata: {operation: "post"}
|
||||
}
|
||||
]
|
||||
if(a.metadata.sortOrder != null && b.metadata.sortOrder != null) {
|
||||
sortOrderComparisonResult = a.metadata.sortOrder.localeCompare(b.metadata.sortOrder);
|
||||
}
|
||||
];
|
||||
|
||||
if(a.metadata.operation != null && b.metadata.operation != null) {
|
||||
operationComparisonResult = a.metadata.operation.localeCompare(b.metadata.operation);
|
||||
}
|
||||
|
||||
if(sortOrderComparisonResult != null && sortOrderComparisonResult !== 0) {
|
||||
return sortOrderComparisonResult;
|
||||
}
|
||||
else if(operationComparisonResult != null && operationComparisonResult !== 0) {
|
||||
return operationComparisonResult;
|
||||
}
|
||||
else {
|
||||
return nameComparisonResult;
|
||||
}
|
||||
}
|
|
@ -334,7 +334,13 @@ export class MenuService {
|
|||
for (let operationInfo of tag.operations) {
|
||||
let xSortOrder;
|
||||
let orderInfo = operationInfo['x-sort-order'];
|
||||
if(orderInfo>=0 && orderInfo<tag.operations.length && Number.isInteger(orderInfo)) xSortOrder = operationInfo['x-sort-order'];
|
||||
|
||||
if(orderInfo != null) {
|
||||
if(orderInfo >= 0 && orderInfo < tag.operations.length && Number.isInteger(orderInfo)) {
|
||||
xSortOrder = operationInfo['x-sort-order'];
|
||||
}
|
||||
}
|
||||
|
||||
let subItem = {
|
||||
name: SchemaHelper.operationSummary(operationInfo),
|
||||
id: operationInfo._pointer,
|
||||
|
|
Loading…
Reference in New Issue
Block a user