diff --git a/src/components/Endpoint/Endpoint.tsx b/src/components/Endpoint/Endpoint.tsx index 9579eeca..87795d3b 100644 --- a/src/components/Endpoint/Endpoint.tsx +++ b/src/components/Endpoint/Endpoint.tsx @@ -22,6 +22,7 @@ export interface EndpointProps { hideHostname?: boolean; inverted?: boolean; compact?: boolean; + isJsonRpc?: boolean; } export interface EndpointState { @@ -41,7 +42,7 @@ export class Endpoint extends React.Component { }; render() { - const { operation, inverted, hideHostname } = this.props; + const { operation, inverted, hideHostname, isJsonRpc } = this.props; const { expanded } = this.state; // TODO: highlight server variables, e.g. https://{user}.test.com @@ -80,7 +81,7 @@ export class Endpoint extends React.Component { : basePath : normalizedUrl} - {operation.path} + {!!isJsonRpc ? `/json` : operation.path} diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index 57776cf0..9809a1ab 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -37,7 +37,7 @@ export class Operation extends React.Component { render() { const { operation } = this.props; - const { name: summary, description, deprecated, externalDocs, isWebhook } = operation; + const { name: summary, description, deprecated, externalDocs, isWebhook, isJsonRpc } = operation; const hasDescription = !!(description || externalDocs); return ( @@ -49,9 +49,10 @@ export class Operation extends React.Component { {summary} {deprecated && Deprecated } {isWebhook && Webhook } + {isJsonRpc && JSON-RPC } {options.pathInMiddlePanel && !isWebhook && ( - + )} {hasDescription && ( @@ -66,7 +67,7 @@ export class Operation extends React.Component { - {!options.pathInMiddlePanel && !isWebhook && } + {!options.pathInMiddlePanel && (!isWebhook || !isJsonRpc) && } diff --git a/src/components/SideMenu/MenuItem.tsx b/src/components/SideMenu/MenuItem.tsx index 9a19fa07..c498168b 100644 --- a/src/components/SideMenu/MenuItem.tsx +++ b/src/components/SideMenu/MenuItem.tsx @@ -91,11 +91,7 @@ export class OperationMenuItemContent extends React.Component - {item.isWebhook ? ( - {l('webhook')} - ) : ( - {shortenHTTPVerb(item.httpVerb)} - )} + {this.renderOperationBadge(item)} {item.name} {this.props.children} @@ -103,4 +99,14 @@ export class OperationMenuItemContent extends React.Component ); } + + renderOperationBadge(item: OperationModel) { + if (item.isWebhook) { + return {l('webhook')} + } else if (item.isJsonRpc) { + return {l('jsonrpc')}; + } else { + return {shortenHTTPVerb(item.httpVerb)} + } + } } diff --git a/src/components/SideMenu/styled.elements.ts b/src/components/SideMenu/styled.elements.ts index 55846434..c1df48f0 100644 --- a/src/components/SideMenu/styled.elements.ts +++ b/src/components/SideMenu/styled.elements.ts @@ -7,7 +7,7 @@ import styled, { css, ResolvedThemeInterface } from '../../styled-components'; export const OperationBadge = styled.span.attrs((props: { type: string }) => ({ className: `operation-type ${props.type}`, }))<{ type: string }>` - width: 9ex; + width: 15ex; display: inline-block; height: ${props => props.theme.typography.code.fontSize}; line-height: ${props => props.theme.typography.code.fontSize}; @@ -138,6 +138,7 @@ export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({ (type === 'section' && depth > 1 && 'padding-left: ' + theme.spacing.unit * 8 + 'px;') || ''} display: flex; justify-content: space-between; + align-items: center; font-family: ${props => props.theme.typography.headings.fontFamily}; ${props => menuItemDepth[props.depth]}; background-color: ${props => (props.active ? menuItemActiveBg(props.depth, props) : '')}; diff --git a/src/services/Labels.ts b/src/services/Labels.ts index c0bddfed..31a4ce3d 100644 --- a/src/services/Labels.ts +++ b/src/services/Labels.ts @@ -9,6 +9,7 @@ export interface LabelsConfig { recursive: string; arrayOf: string; webhook: string; + jsonrpc: string; } export type LabelsConfigRaw = Partial; @@ -24,6 +25,7 @@ const labels: LabelsConfig = { recursive: 'Recursive', arrayOf: 'Array of ', webhook: 'Event', + jsonrpc: 'Json-RPC', }; export function setRedocLabels(_labels?: LabelsConfigRaw) { diff --git a/src/services/MenuBuilder.ts b/src/services/MenuBuilder.ts index 339ba6cf..524e657e 100644 --- a/src/services/MenuBuilder.ts +++ b/src/services/MenuBuilder.ts @@ -30,6 +30,7 @@ export type ExtendedOpenAPIOperation = { pathParameters: Array>; pathServers: Array | undefined; isWebhook: boolean; + isJsonRpc: boolean; } & OpenAPIOperation; export type TagsInfoMap = Record; @@ -129,10 +130,10 @@ export class MenuBuilder { } /** - * Returns array of OperationsGroup items for the tags of the group or for all tags - * @param tagsMap tags info returned from `getTagsWithOperations` - * @param parent parent item - * @param group group which this tag belongs to. if not provided gets all tags + * 그룹의 태그 또는 모든 태그에 대한 OperationsGroup 항목의 배열을 반환한다. + * @param tagsMap `getTagsWithOperations`에서 반환된 태그 정보 + * @param parent 상위 항목 + * @param group 이 태그가 속한 그룹. 주어지지 않으면 모든 태그를 가져온다. */ static getTagsItems( parser: OpenAPIParser, @@ -213,7 +214,7 @@ export class MenuBuilder { } /** - * collects tags and maps each tag to list of operations belonging to this tag + * 태그를 수집하고 각 태그를 이 태그에 속하는 operations 목록에 매핑한다. */ static getTagsWithOperations(spec: OpenAPISpec): TagsInfoMap { const tags: TagsInfoMap = {}; @@ -225,8 +226,11 @@ export class MenuBuilder { if (spec['x-webhooks']) { getTags(spec['x-webhooks'], true); } + if (spec['jsonrpc']) { + getTags(spec['jsonrpc'], false, true); + } - function getTags(paths: OpenAPIPaths, isWebhook?: boolean) { + function getTags(paths: OpenAPIPaths, isWebhook?: boolean, isJsonRpc?: boolean) { for (const pathName of Object.keys(paths)) { const path = paths[pathName]; const operations = Object.keys(path).filter(isOperationName); @@ -259,6 +263,7 @@ export class MenuBuilder { pathParameters: path.parameters || [], pathServers: path.servers, isWebhook: !!isWebhook, + isJsonRpc: !!isJsonRpc, }); } } diff --git a/src/services/SpecStore.ts b/src/services/SpecStore.ts index 1f39f903..e0718b5c 100644 --- a/src/services/SpecStore.ts +++ b/src/services/SpecStore.ts @@ -7,7 +7,7 @@ import { SecuritySchemesModel } from './models/SecuritySchemes'; import { OpenAPIParser } from './OpenAPIParser'; import { RedocNormalizedOptions } from './RedocNormalizedOptions'; /** - * Store that contains all the specification related information in the form of tree + * 모든 specification 관련 정보를 트리 형태로 포함하는 Store */ export class SpecStore { parser: OpenAPIParser; diff --git a/src/services/models/Operation.ts b/src/services/models/Operation.ts index d00461a1..ae4c1102 100644 --- a/src/services/models/Operation.ts +++ b/src/services/models/Operation.ts @@ -76,6 +76,7 @@ export class OperationModel implements IMenuItem { extensions: Record; isCallback: boolean; isWebhook: boolean; + isJsonRpc: boolean; constructor( private parser: OpenAPIParser, @@ -99,6 +100,7 @@ export class OperationModel implements IMenuItem { this.path = operationSpec.pathName; this.isCallback = isCallback; this.isWebhook = !!operationSpec.isWebhook; + this.isJsonRpc = !!operationSpec.isJsonRpc; this.name = getOperationSummary(operationSpec); diff --git a/src/types/open-api.d.ts b/src/types/open-api.d.ts index aefc0b73..fb80a9c7 100644 --- a/src/types/open-api.d.ts +++ b/src/types/open-api.d.ts @@ -10,6 +10,7 @@ export interface OpenAPISpec { tags?: OpenAPITag[]; externalDocs?: OpenAPIExternalDocumentation; 'x-webhooks'?: OpenAPIPaths; + 'jsonrpc'?: OpenAPIPaths; } export interface OpenAPIInfo {