From b2d8ef73126eff6c436464ba99a93043802323cf Mon Sep 17 00:00:00 2001 From: Alex Varchuk Date: Wed, 11 May 2022 11:31:49 +0300 Subject: [PATCH 1/5] feat: add option for display request method in webhook --- src/components/Operation/Operation.tsx | 89 ++++++++++--------- src/components/SideMenu/MenuItem.tsx | 56 ++++++------ .../DiscriminatorDropdown.test.tsx.snap | 10 +++ src/services/RedocNormalizedOptions.ts | 3 + 4 files changed, 85 insertions(+), 73 deletions(-) diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index 8170351e7f..24d12f435f 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -18,6 +18,7 @@ import { ResponsesList } from '../Responses/ResponsesList'; import { ResponseSamples } from '../ResponseSamples/ResponseSamples'; import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement'; import { SECTION_ATTR } from '../../services'; +import { titleize } from '../../utils/helpers'; const Description = styled.div` margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px; @@ -27,48 +28,48 @@ export interface OperationProps { operation: OperationModel; } -@observer -export class Operation extends React.Component { - render() { - const { operation } = this.props; - - const { name: summary, description, deprecated, externalDocs, isWebhook } = operation; - const hasDescription = !!(description || externalDocs); - - return ( - - {options => ( - - -

- - {summary} {deprecated && Deprecated } - {isWebhook && Webhook } -

- {options.pathInMiddlePanel && !isWebhook && ( - +export const Operation = observer(({ operation }: OperationProps): JSX.Element => { + const { name: summary, description, deprecated, externalDocs, isWebhook, httpVerb } = operation; + const hasDescription = !!(description || externalDocs); + const { showWebhookVerb } = React.useContext(OptionsContext); + return ( + + {options => ( + + +

+ + {summary} {deprecated && Deprecated } + {isWebhook && ( + + {' '} + Webhook {showWebhookVerb && '| ' + titleize(httpVerb)} + )} - {hasDescription && ( - - {description !== undefined && } - {externalDocs && } - - )} - - - - - - - - {!options.pathInMiddlePanel && !isWebhook && } - - - - - - )} - - ); - } -} +

+ {options.pathInMiddlePanel && !isWebhook && ( + + )} + {hasDescription && ( + + {description !== undefined && } + {externalDocs && } + + )} + + + + + +
+ + {!options.pathInMiddlePanel && !isWebhook && } + + + + +
+ )} +
+ ); +}); diff --git a/src/components/SideMenu/MenuItem.tsx b/src/components/SideMenu/MenuItem.tsx index 138e88c91d..5e79943b91 100644 --- a/src/components/SideMenu/MenuItem.tsx +++ b/src/components/SideMenu/MenuItem.tsx @@ -8,11 +8,13 @@ import { MenuItems } from './MenuItems'; import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styled.elements'; import { l } from '../../services/Labels'; import { scrollIntoViewIfNeeded } from '../../utils'; +import { OptionsContext } from '../OptionsProvider'; export interface MenuItemProps { item: IMenuItem; onActivate?: (item: IMenuItem) => void; withoutChildren?: boolean; + children?: React.ReactChild; } @observer @@ -70,37 +72,33 @@ export class MenuItem extends React.Component { export interface OperationMenuItemContentProps { item: OperationModel; + children?: React.ReactChild; } -@observer -export class OperationMenuItemContent extends React.Component { - ref = React.createRef(); +export const OperationMenuItemContent = observer((props: OperationMenuItemContentProps) => { + const { item } = props; + const ref = React.createRef(); + const { showWebhookVerb } = React.useContext(OptionsContext); - componentDidUpdate() { - if (this.props.item.active && this.ref.current) { - scrollIntoViewIfNeeded(this.ref.current); + React.useEffect(() => { + if (props.item.active && ref.current) { + scrollIntoViewIfNeeded(ref.current); } - } + }, [props.item.active, ref]); - render() { - const { item } = this.props; - return ( - - {item.isWebhook ? ( - {l('webhook')} - ) : ( - {shortenHTTPVerb(item.httpVerb)} - )} - - {item.sidebarLabel} - {this.props.children} - - - ); - } -} + return ( + + {item.isWebhook ? ( + + {showWebhookVerb ? item.httpVerb : l('webhook')} + + ) : ( + {shortenHTTPVerb(item.httpVerb)} + )} + + {item.sidebarLabel} + {props.children} + + + ); +}); diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index 4b0ada9782..81245601b5 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -106,6 +106,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -360,6 +361,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -589,6 +591,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -885,6 +888,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -1139,6 +1143,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -1368,6 +1373,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -1620,6 +1626,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -1913,6 +1920,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -2167,6 +2175,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, @@ -2396,6 +2405,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "scrollYOffset": [Function], "showExtensions": false, "showObjectSchemaExamples": false, + "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, "sortEnumValuesAlphabetically": false, diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index 0628affd87..92bec6b632 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -59,6 +59,7 @@ export interface RedocRawOptions { nonce?: string; hideFab?: boolean; minCharacterLengthToInitSearch?: number; + showWebhookVerb?: boolean; } export function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean { @@ -257,6 +258,7 @@ export class RedocNormalizedOptions { generatedPayloadSamplesMaxDepth: number; hideFab: boolean; minCharacterLengthToInitSearch: number; + showWebhookVerb: boolean; nonce?: string; @@ -334,5 +336,6 @@ export class RedocNormalizedOptions { this.nonce = raw.nonce; this.hideFab = argValueToBoolean(raw.hideFab); this.minCharacterLengthToInitSearch = argValueToNumber(raw.minCharacterLengthToInitSearch) || 3; + this.showWebhookVerb = argValueToBoolean(raw.showWebhookVerb); } } From 313d043afb93479c0518a5528e9549962136810e Mon Sep 17 00:00:00 2001 From: Alex Varchuk Date: Wed, 11 May 2022 11:34:23 +0300 Subject: [PATCH 2/5] chore: cli test run ts files --- cli/__test__/build/configRedoc/index.test.ts | 4 ++-- cli/__test__/build/configRedoc/inlineOptions.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/__test__/build/configRedoc/index.test.ts b/cli/__test__/build/configRedoc/index.test.ts index f28f08bd85..382700b5d4 100644 --- a/cli/__test__/build/configRedoc/index.test.ts +++ b/cli/__test__/build/configRedoc/index.test.ts @@ -4,8 +4,8 @@ import { readFileSync } from 'fs'; describe('build', () => { it('should use .redocly.yaml', () => { const r = spawnSync( - 'node', - ['../../../index.js', 'build', ' ../../../../demo/openapi.yaml', '--output=redocTest.html'], + 'ts-node', + ['../../../index.ts', 'build', ' ../../../../demo/openapi.yaml', '--output=redocTest.html'], { cwd: __dirname, shell: true, diff --git a/cli/__test__/build/configRedoc/inlineOptions.test.ts b/cli/__test__/build/configRedoc/inlineOptions.test.ts index fffc1acea9..9ed0cfad42 100644 --- a/cli/__test__/build/configRedoc/inlineOptions.test.ts +++ b/cli/__test__/build/configRedoc/inlineOptions.test.ts @@ -4,9 +4,9 @@ import { readFileSync } from 'fs'; describe('build with inline options', () => { it('should use inline options and ignore .redocly.yaml', () => { const r = spawnSync( - 'node', + 'ts-node', [ - '../../../index.js', + '../../../index.ts', 'build', ' ../../../../demo/openapi.yaml', '--options.disableSearch="false" ', From 3044db5c4373e3416096ae3099af9bd38cf69be2 Mon Sep 17 00:00:00 2001 From: Alex Varchuk Date: Wed, 11 May 2022 12:05:47 +0300 Subject: [PATCH 3/5] chore: add showWebhookVerb to readme file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8163836663..2dc0ab7b55 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ You can use all of the following options with the standalone version of the ` theme object * `spacing` From bd3c3370c4c46fcc8ef1cf2aebbd97c65f0c5bf6 Mon Sep 17 00:00:00 2001 From: Ivana Isadora Devcic <33730345+skadinna@users.noreply.github.com> Date: Wed, 11 May 2022 11:20:41 +0200 Subject: [PATCH 4/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2dc0ab7b55..ddc7411dae 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ You can use all of the following options with the standalone version of the ` theme object * `spacing` From 70e8ab43b975ef2d43878e5bb1f669968ffe46d2 Mon Sep 17 00:00:00 2001 From: Alex Varchuk Date: Wed, 11 May 2022 14:22:51 +0300 Subject: [PATCH 5/5] fix: convert httpVerb to uppercase --- src/components/Operation/Operation.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index 24d12f435f..b6904f62cc 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -18,7 +18,6 @@ import { ResponsesList } from '../Responses/ResponsesList'; import { ResponseSamples } from '../ResponseSamples/ResponseSamples'; import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement'; import { SECTION_ATTR } from '../../services'; -import { titleize } from '../../utils/helpers'; const Description = styled.div` margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px; @@ -43,7 +42,7 @@ export const Operation = observer(({ operation }: OperationProps): JSX.Element = {isWebhook && ( {' '} - Webhook {showWebhookVerb && '| ' + titleize(httpVerb)} + Webhook {showWebhookVerb && httpVerb && '| ' + httpVerb.toUpperCase()} )}