From 312c85a9119eb2fa708eb07f3a7fe5478aa4ccf4 Mon Sep 17 00:00:00 2001 From: Alex Karo Date: Fri, 7 Jun 2019 00:15:06 +0300 Subject: [PATCH 1/4] feat: add sampleCollapseLevel option --- README.md | 1 + src/components/JsonViewer/JsonViewer.tsx | 19 +++++++++++++------ src/services/RedocNormalizedOptions.ts | 15 +++++++++++++++ src/utils/jsonToHtml.ts | 9 +++++---- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 16554c6b80..138e1661c7 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,7 @@ You can use all of the following options with standalone version on tag * `hideDownloadButton` - do not show "Download" spec button. **THIS DOESN'T MAKE YOUR SPEC PRIVATE**, it just hides the button. * `disableSearch` - disable search indexing and search box * `onlyRequiredInSamples` - shows only required fields in request samples. +* `sampleCollapseLevel` - set the collapse level in response samples. Special value 'all' expand all response. Default value = 2. * `theme` - ReDoc theme. Not documented yet. For details check source code: [theme.ts](https://github.com/Redocly/redoc/blob/master/src/theme.ts) ## Advanced usage of standalone version diff --git a/src/components/JsonViewer/JsonViewer.tsx b/src/components/JsonViewer/JsonViewer.tsx index 33231ee7e1..3b213ef862 100644 --- a/src/components/JsonViewer/JsonViewer.tsx +++ b/src/components/JsonViewer/JsonViewer.tsx @@ -5,6 +5,7 @@ import { SampleControls } from '../../common-elements'; import { CopyButtonWrapper } from '../../common-elements/CopyButtonWrapper'; import { PrismDiv } from '../../common-elements/PrismDiv'; import { jsonToHTML } from '../../utils/jsonToHtml'; +import { OptionsContext } from '../OptionsProvider'; import { jsonStyles } from './style'; export interface JsonProps { @@ -32,12 +33,18 @@ class Json extends React.PureComponent { Expand all Collapse all - (this.node = node!)} - dangerouslySetInnerHTML={{ __html: jsonToHTML(this.props.data) }} - /> + + {options => ( + (this.node = node!)} + dangerouslySetInnerHTML={{ + __html: jsonToHTML(this.props.data, options.sampleCollapseLevel), + }} + /> + )} + ); diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index 7c893f1b9a..1690b2905a 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -22,6 +22,7 @@ export interface RedocRawOptions { onlyRequiredInSamples?: boolean | string; showExtensions?: boolean | string | string[]; hideSingleRequestSampleTab?: boolean | string; + sampleCollapseLevel?: number | string | 'all'; unstable_ignoreMimeParameters?: boolean; @@ -110,6 +111,16 @@ export class RedocNormalizedOptions { return value; } + private static normalizeSampleCollapseLevel(level?: number | string | 'all'): number { + if (level === 'all') { + return +Infinity; + } + if (!isNaN(Number(level))) { + return Math.ceil(Number(level)); + } + return 2; + } + theme: ResolvedThemeInterface; scrollYOffset: () => number; hideHostname: boolean; @@ -125,6 +136,7 @@ export class RedocNormalizedOptions { onlyRequiredInSamples: boolean; showExtensions: boolean | string[]; hideSingleRequestSampleTab: boolean; + sampleCollapseLevel: number; /* tslint:disable-next-line */ unstable_ignoreMimeParameters: boolean; @@ -156,6 +168,9 @@ export class RedocNormalizedOptions { this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples); this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions); this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab); + this.sampleCollapseLevel = RedocNormalizedOptions.normalizeSampleCollapseLevel( + raw.sampleCollapseLevel, + ); this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters); diff --git a/src/utils/jsonToHtml.ts b/src/utils/jsonToHtml.ts index abd4b14afe..7346e62ec9 100644 --- a/src/utils/jsonToHtml.ts +++ b/src/utils/jsonToHtml.ts @@ -1,8 +1,9 @@ let level = 1; -const COLLAPSE_LEVEL = 2; +let collapseLevel; -export function jsonToHTML(json) { +export function jsonToHTML(json, maxCollapseLevel) { level = 1; + collapseLevel = maxCollapseLevel; let output = ''; output += '
'; output += valueToHTML(json); @@ -71,7 +72,7 @@ function valueToHTML(value) { } function arrayToHTML(json) { - const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : ''; + const collapsed = level > collapseLevel ? 'collapsed' : ''; let output = `
${punctuation( '[', )}
    `; @@ -94,7 +95,7 @@ function arrayToHTML(json) { } function objectToHTML(json) { - const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : ''; + const collapsed = level > collapseLevel ? 'collapsed' : ''; const keys = Object.keys(json); const length = keys.length; let output = `
    ${punctuation( From 2375077f8f400fe4ad9333332922f020576c50c1 Mon Sep 17 00:00:00 2001 From: Alex Karo Date: Thu, 11 Jul 2019 16:04:20 +0300 Subject: [PATCH 2/4] fix: rename sampleCollapseLevel option to jsonSampleExpandLevel Change README.md description --- README.md | 2 +- src/components/JsonViewer/JsonViewer.tsx | 2 +- src/services/RedocNormalizedOptions.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 138e1661c7..82eeeecf6f 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ You can use all of the following options with standalone version on tag * `hideDownloadButton` - do not show "Download" spec button. **THIS DOESN'T MAKE YOUR SPEC PRIVATE**, it just hides the button. * `disableSearch` - disable search indexing and search box * `onlyRequiredInSamples` - shows only required fields in request samples. -* `sampleCollapseLevel` - set the collapse level in response samples. Special value 'all' expand all response. Default value = 2. +* `jsonSampleExpandLevel` - set the default expand level for JSON payload samples (responses and request body). Special value 'all' expands all levels. The default value is `2`. * `theme` - ReDoc theme. Not documented yet. For details check source code: [theme.ts](https://github.com/Redocly/redoc/blob/master/src/theme.ts) ## Advanced usage of standalone version diff --git a/src/components/JsonViewer/JsonViewer.tsx b/src/components/JsonViewer/JsonViewer.tsx index 3b213ef862..bf7352991d 100644 --- a/src/components/JsonViewer/JsonViewer.tsx +++ b/src/components/JsonViewer/JsonViewer.tsx @@ -40,7 +40,7 @@ class Json extends React.PureComponent { // tslint:disable-next-line ref={node => (this.node = node!)} dangerouslySetInnerHTML={{ - __html: jsonToHTML(this.props.data, options.sampleCollapseLevel), + __html: jsonToHTML(this.props.data, options.jsonSampleExpandLevel), }} /> )} diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index 1690b2905a..fe924cded7 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -22,7 +22,7 @@ export interface RedocRawOptions { onlyRequiredInSamples?: boolean | string; showExtensions?: boolean | string | string[]; hideSingleRequestSampleTab?: boolean | string; - sampleCollapseLevel?: number | string | 'all'; + jsonSampleExpandLevel?: number | string | 'all'; unstable_ignoreMimeParameters?: boolean; @@ -136,7 +136,7 @@ export class RedocNormalizedOptions { onlyRequiredInSamples: boolean; showExtensions: boolean | string[]; hideSingleRequestSampleTab: boolean; - sampleCollapseLevel: number; + jsonSampleExpandLevel: number; /* tslint:disable-next-line */ unstable_ignoreMimeParameters: boolean; @@ -168,8 +168,8 @@ export class RedocNormalizedOptions { this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples); this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions); this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab); - this.sampleCollapseLevel = RedocNormalizedOptions.normalizeSampleCollapseLevel( - raw.sampleCollapseLevel, + this.jsonSampleExpandLevel = RedocNormalizedOptions.normalizeSampleCollapseLevel( + raw.jsonSampleExpandLevel, ); this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters); From bccde07990ad3bbdd61ab74207013775b3422279 Mon Sep 17 00:00:00 2001 From: Alex Karo Date: Thu, 11 Jul 2019 16:41:03 +0300 Subject: [PATCH 3/4] fix: provide maxCollapseLevel option via argument --- src/utils/jsonToHtml.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/utils/jsonToHtml.ts b/src/utils/jsonToHtml.ts index 7346e62ec9..e0eadc9e2f 100644 --- a/src/utils/jsonToHtml.ts +++ b/src/utils/jsonToHtml.ts @@ -1,12 +1,10 @@ let level = 1; -let collapseLevel; export function jsonToHTML(json, maxCollapseLevel) { level = 1; - collapseLevel = maxCollapseLevel; let output = ''; output += '
    '; - output += valueToHTML(json); + output += valueToHTML(json, maxCollapseLevel); output += '
    '; return output; } @@ -34,20 +32,20 @@ function punctuation(val) { return '' + val + ''; } -function valueToHTML(value) { +function valueToHTML(value, maxCollapseLevel: number) { const valueType = typeof value; let output = ''; if (value === undefined || value === null) { output += decorateWithSpan('null', 'token keyword'); } else if (value && value.constructor === Array) { level++; - output += arrayToHTML(value); + output += arrayToHTML(value, maxCollapseLevel); level--; } else if (value && value.constructor === Date) { output += decorateWithSpan('"' + value.toISOString() + '"', 'token string'); } else if (valueType === 'object') { level++; - output += objectToHTML(value); + output += objectToHTML(value, maxCollapseLevel); level--; } else if (valueType === 'number') { output += decorateWithSpan(value, 'token number'); @@ -71,8 +69,8 @@ function valueToHTML(value) { return output; } -function arrayToHTML(json) { - const collapsed = level > collapseLevel ? 'collapsed' : ''; +function arrayToHTML(json, maxCollapseLevel: number) { + const collapsed = level > maxCollapseLevel ? 'collapsed' : ''; let output = `
    ${punctuation( '[', )}
      `; @@ -81,7 +79,7 @@ function arrayToHTML(json) { for (let i = 0; i < length; i++) { hasContents = true; output += '