From 8f99cd08824062abc75b39334e7c5250407a1f06 Mon Sep 17 00:00:00 2001 From: Vincent Leon Date: Tue, 13 Oct 2020 13:47:58 +0200 Subject: [PATCH 01/15] feat: Dockerfile compatible with OpenShift (#1407) (#1408) Co-authored-by: Vincent LEON --- config/docker/Dockerfile | 12 ++++++++++++ config/docker/README.md | 24 +++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/config/docker/Dockerfile b/config/docker/Dockerfile index 82995837..fc7481f4 100644 --- a/config/docker/Dockerfile +++ b/config/docker/Dockerfile @@ -36,6 +36,18 @@ COPY demo/favicon.png /usr/share/nginx/html/ COPY config/docker/nginx.conf /etc/nginx/ COPY config/docker/docker-run.sh /usr/local/bin +# Provide rights to the root group to write to nginx repositories (needed to run in OpenShift) +RUN chgrp -R 0 /etc/nginx && \ + chgrp -R 0 /usr/share/nginx/html && \ + chgrp -R 0 /var/cache/nginx && \ + chgrp -R 0 /var/log/nginx && \ + chgrp -R 0 /var/run && \ + chmod -R g+rwX /etc/nginx && \ + chmod -R g+rwX /usr/share/nginx/html && \ + chmod -R g+rwX /var/cache/nginx && \ + chmod -R g+rwX /var/log/nginx && \ + chmod -R g+rwX /var/run + EXPOSE 80 CMD ["sh", "/usr/local/bin/docker-run.sh"] diff --git a/config/docker/README.md b/config/docker/README.md index e8864899..b25f41bd 100644 --- a/config/docker/README.md +++ b/config/docker/README.md @@ -2,6 +2,8 @@ ## Usage +### Docker + Serve remote spec by URL: docker run -it --rm -p 80:80 \ @@ -12,13 +14,33 @@ Serve local file: docker run -it --rm -p 80:80 \ -v $(pwd)/demo/swagger.yaml:/usr/share/nginx/html/swagger.yaml \ -e SPEC_URL=swagger.yaml redocly/redoc - + Serve local file and watch for updates: docker run -it --rm -p 80:80 \ -v $(pwd)/demo/:/usr/share/nginx/html/swagger/ \ -e SPEC_URL=swagger/swagger.yaml redocly/redoc +### OpenShift + +To quote [OpenShift Container Platform-Specific Guidelines](https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines): + +> Support Arbitrary User IDs +> +> By default, OpenShift Container Platform runs containers using an arbitrarily assigned user ID. This provides additional security against processes escaping the container due to a container engine vulnerability and thereby achieving escalated permissions on the host node. +> +> For an image to support running as an arbitrary user, directories and files that may be written to by processes in the image should be owned by the root group and be read/writable by that group. Files to be executed should also have group execute permissions. + +To comply with those requirements the `Dockerfile` contains instructions to adapt the rights for the folders: + +- `/etc/nginx` because the `docker-run.sh` script modifies it at startup time +- `/usr/share/nginx/html` because the `docker-run.sh` script modifies it at startup time +- `/var/cache/nginx` because the Nginx process writes to it +- `/var/log/nginx` because the Nginx process writes to it +- `/var/run` because the Nginx process writes to it + +Another issue with OpenShift is that the default exposed port `80` cannot be used as it is restricted. So one needs to use another port like `8080` (using the `PORT` configuration as described below), and then to configure the `container spec` accordingly. + ## Runtime configuration options - `PAGE_TITLE` (default `"ReDoc"`) - page title From 6632d844536532227cb92290f9fc2b6b2f913270 Mon Sep 17 00:00:00 2001 From: Anna Stasiuk Date: Tue, 13 Oct 2020 14:50:00 +0300 Subject: [PATCH 02/15] fix: hide dropdown input on IE 11 (#1403) --- src/common-elements/dropdown.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common-elements/dropdown.ts b/src/common-elements/dropdown.ts index c06295a0..f4bcc281 100644 --- a/src/common-elements/dropdown.ts +++ b/src/common-elements/dropdown.ts @@ -107,6 +107,7 @@ export const StyledDropdown = styled(Dropdown)` input { cursor: pointer; height: 1px; + background-color: transparent; } } `; From 0c782ec51f2656ab6152a15e68b609e0162614d3 Mon Sep 17 00:00:00 2001 From: Swapnil Ogale Date: Tue, 13 Oct 2020 22:55:45 +1100 Subject: [PATCH 03/15] docs: improvements to vendor extensions topic (#1386) --- docs/redoc-vendor-extensions.md | 111 ++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/docs/redoc-vendor-extensions.md b/docs/redoc-vendor-extensions.md index 639e21b2..884dfb70 100644 --- a/docs/redoc-vendor-extensions.md +++ b/docs/redoc-vendor-extensions.md @@ -1,8 +1,34 @@ # ReDoc vendor extensions -ReDoc makes use of the following [vendor extensions](https://swagger.io/specification/#specificationExtensions) -### Swagger Object vendor extensions -Extend OpenAPI root [Swagger Object](https://swagger.io/specification/#oasObject) +You can use the following [vendor extensions](https://swagger.io/specification/#specificationExtensions) with Redoc. + +- [Swagger Object](#swagger-object) + - [x-servers](#x-servers) + - [x-tagGroups](#x-taggroups) + - [Tag Group Object](#a-nametaggroupobjectatag-group-object) + - [x-ignoredHeaderParameters](#x-ignoredheaderparameters) +- [Info Object](#info-object) + - [x-logo](#x-logo) + - [Logo Object](#a-namelogoobjectalogo-object) +- [Tag Object](#tag-object) + - [x-traitTag](#x-traittag) + - [x-displayName](#x-displayname) +- [Operation Object](#operation-object-vendor-extensions) + - [x-codeSamples](#x-codesamples) + - [Code Sample Object](#a-namecodesampleobjectacode-sample-object) +- [Parameter Object](#parameter-object) + - [x-examples](#x-examples) +- [Response Object vendor extensions](#response-object-vendor-extensions) + - [x-summary](#x-summary) +- [Schema Object](#schema-object) + - [x-nullable](#x-nullable) + - [x-extendedDiscriminator](#x-extendeddiscriminator) + - [x-additionalPropertiesName](#x-additionalpropertiesname) + - [x-explicitMappingOnly](#x-explicitmappingonly) + +### Swagger Object +Extends the OpenAPI root [OpenAPI Object](https://swagger.io/specification/#oasObject) + #### x-servers Backported from OpenAPI 3.0 [`servers`](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#serverObject). Currently doesn't support templates. @@ -12,9 +38,9 @@ Backported from OpenAPI 3.0 [`servers`](https://github.com/OAI/OpenAPI-Specifica | :------------- | :-----------: | :---------- | | x-tagGroups | [ [Tag Group Object](#tagGroupObject) ] | A list of tag groups | -###### Usage in Redoc +###### How to use with Redoc `x-tagGroups` is used to group tags in the side menu. -If you are going to use `x-tagGroups`, please make sure you **add all tags to a group**, since a tag that is not in a group, **will not be displayed** at all! +Before you use `x-tagGroups`, make sure you **add all tags to a group**, since a tag that is not in a group, **will not be displayed** at all! #### Tag Group Object Information about tags group @@ -62,8 +88,8 @@ x-tagGroups: | x-ignoredHeaderParameters | [ string ] | A list of ignored headers | -###### Usage in Redoc -`x-ignoredHeaderParameters` is used to specify header parameter names which are ignored by ReDoc +###### How to use with Redoc +Use `x-ignoredHeaderParameters` to specify header parameter names which are ignored by ReDoc. ###### x-ignoredHeaderParameters example ```yaml @@ -77,19 +103,20 @@ x-ignoredHeaderParameters: - X-Test-Header ``` -### Info Object vendor extensions -Extends OpenAPI [Info Object](http://swagger.io/specification/#infoObject) +### Info Object +Extends the OpenAPI [Info Object](http://swagger.io/specification/#infoObject) #### x-logo | Field Name | Type | Description | | :------------- | :-----------: | :---------- | | x-logo | [Logo Object](#logoObject) | The information about API logo | -###### Usage in Redoc -`x-logo` is used to specify API logo. The corresponding image are displayed just above side-menu. +###### How to use with Redoc +`x-logo` is used to specify API logo. The corresponding image is displayed just above the side-menu. #### Logo Object The information about API logo + ###### Fixed fields | Field Name | Type | Description | | :-------------- | :------: | :---------- | @@ -125,17 +152,16 @@ info: altText: "Petstore logo" ``` +### Tag Object +Extends the OpenAPI [Tag Object](http://swagger.io/specification/#tagObject) - -### Tag Object vendor extensions -Extends OpenAPI [Tag Object](http://swagger.io/specification/#tagObject) #### x-traitTag | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-traitTag | boolean | In Swagger two operations can have multiple tags. This property distinguishes between tags that are used to group operations (default) from tags that are used to mark operation with certain trait (`true` value) | -###### Usage in Redoc -Tags that have `x-traitTag` set to `true` are listed in side-menu but don't have any subitems (operations). Tag `description` is rendered as well. +###### How to use with Redoc +Tags that have `x-traitTag` set to `true` are listed in the side-menu but don't have any subitems (operations). It also renders the `description` tag. This is useful for handling out common things like Pagination, Rate-Limits, etc. ###### x-traitTag example @@ -161,17 +187,19 @@ x-traitTag: true | x-displayName | string | Defines the text that is used for this tag in the menu and in section headings | ### Operation Object vendor extensions -Extends OpenAPI [Operation Object](http://swagger.io/specification/#operationObject) +Extends the OpenAPI [Operation Object](http://swagger.io/specification/#operationObject) + #### x-codeSamples | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-codeSamples | [ [Code Sample Object](#codeSampleObject) ] | A list of code samples associated with operation | -###### Usage in ReDoc -`x-codeSamples` are rendered on the right panel of ReDoc +###### How to use with ReDoc +`x-codeSamples` are rendered on the right panel in ReDoc. #### Code Sample Object Operation code sample + ###### Fixed fields | Field Name | Type | Description | | :---------- | :------: | :----------- | @@ -194,49 +222,51 @@ lang: JavaScript source: console.log('Hello World'); ``` -### Parameter Object vendor extensions -Extends OpenAPI [Parameter Object](http://swagger.io/specification/#parameterObject) +### Parameter Object +Extends the OpenAPI [Parameter Object](http://swagger.io/specification/#parameterObject) + #### x-examples | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-examples | [Example Object](http://swagger.io/specification/#exampleObject) | Object that contains examples for the request. Applies when `in` is `body` and mime-type is `application/json` | -###### Usage in ReDoc -`x-examples` are rendered in the JSON tab on the right panel of ReDoc. +###### How to use with ReDoc +`x-examples` are rendered in the JSON tab on the right panel in ReDoc. ### Response Object vendor extensions -Extends OpenAPI [Response Object](https://swagger.io/specification/#responseObject) +Extends the OpenAPI [Response Object](https://swagger.io/specification/#responseObject) #### x-summary | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-summary | string | a short summary of the response | -###### Usage in ReDoc -If specified, `x-summary` is used as the response button text. Description is rendered under the button. +###### How to use with ReDoc +If specified, you can use `x-summary` as the response button text, with description rendered under the button. + +### Schema Object +Extends the OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject) -### Schema Object vendor extensions -Extends OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject) #### x-nullable | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-nullable | boolean | marks schema as a nullable | -###### Usage in ReDoc +###### How to use with ReDoc Schemas marked as `x-nullable` are marked in ReDoc with the label Nullable #### x-extendedDiscriminator -**ATTENTION**: This is ReDoc-specific vendor extension. It won't be supported by other tools. +**ATTENTION**: This is a ReDoc-specific vendor extension, and is not supported by other tools. | Field Name | Type | Description | | :------------- | :------: | :---------- | | x-extendedDiscriminator | string | specifies extended discriminator | -###### Usage in ReDoc +###### How to use with ReDoc ReDoc uses this vendor extension to solve name-clash issues with the standard `discriminator`. Value of this field specifies the field which will be used as a extended discriminator. ReDoc displays definition with selectpicker using which user can select value of the `x-extendedDiscriminator`-marked field. -ReDoc displays the definition which is derived from the current (using `allOf`) and has `enum` with only one value which is the same as the selected value of the field specified as `x-extendedDiscriminator`. +ReDoc displays the definition derived from the current (using `allOf`) and has `enum` with only one value which is the same as the selected value of the field specified as `x-extendedDiscriminator`. ###### x-extendedDiscriminator example @@ -276,11 +306,10 @@ PayPalPayment: type: string ``` -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`. +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`. #### x-additionalPropertiesName -**ATTENTION**: This is ReDoc-specific vendor extension. It won't be supported by other tools. +**ATTENTION**: This is a ReDoc-specific vendor extension, and is not supported by other tools. Extends the `additionalProperties` property of the schema object. @@ -288,7 +317,7 @@ Extends the `additionalProperties` property of the schema object. | :------------- | :------: | :---------- | | x-additionalPropertiesName | string | descriptive name of additional properties keys | -###### Usage in ReDoc +###### How to use with ReDoc ReDoc uses this extension to display a more descriptive property name in objects with `additionalProperties` when viewing the property list with an `object`. ###### x-additionalPropertiesName example @@ -308,7 +337,7 @@ Player: ``` #### x-explicitMappingOnly -**ATTENTION**: This is ReDoc-specific vendor extension. It won't be supported by other tools. +**ATTENTION**: This is ReDoc-specific vendor extension, and is not supported by other tools. Extends the `discriminator` property of the schema object. @@ -316,10 +345,9 @@ Extends the `discriminator` property of the schema object. | :------------- | :------: | :---------- | | x-explicitMappingOnly | boolean | limit the discriminator selectpicker to the explicit mappings only | -###### Usage in ReDoc +###### How to use with ReDoc ReDoc uses this extension to filter the `discriminator` mappings shown in the selectpicker. -When set to `true`, the selectpicker will only list the the explicitly defined mappings. When `false`, -the default behavior is kept, i.e. explicit and implicit mappings will be shown. +When set to `true`, the selectpicker will only list the the explicitly defined mappings. When `false`, the default behavior is kept, i.e. explicit and implicit mappings will be shown. ###### x-explicitMappingOnly example @@ -338,5 +366,4 @@ Pet: bee: "#/components/schemas/HoneyBee" ``` -Will show in the selectpicker only the items `cat` and `bee`, even though the `Dog` class inherits from -the `Pet` class. +Will show in the selectpicker only the items `cat` and `bee`, even though the `Dog` class inherits from the `Pet` class. From 146b38c9d0b926765d8e00dd37204c30bf3ac4e0 Mon Sep 17 00:00:00 2001 From: Anna Stasiuk Date: Tue, 13 Oct 2020 14:56:03 +0300 Subject: [PATCH 04/15] fix: make samples accessible by keyboard (#1401) * fix: make samples accessible by keyboard * chore: set outline-width and padding to collapser --- src/components/JsonViewer/JsonViewer.tsx | 19 ++++++++--- src/components/JsonViewer/style.ts | 40 +++++++++++++++++------- src/utils/jsonToHtml.ts | 4 +-- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/components/JsonViewer/JsonViewer.tsx b/src/components/JsonViewer/JsonViewer.tsx index 0ef0da51..f320473a 100644 --- a/src/components/JsonViewer/JsonViewer.tsx +++ b/src/components/JsonViewer/JsonViewer.tsx @@ -34,11 +34,11 @@ class Json extends React.PureComponent { - {options => ( + {(options) => ( (this.node = node!)} + ref={(node) => (this.node = node!)} dangerouslySetInnerHTML={{ __html: jsonToHTML(this.props.data, options.jsonSampleExpandLevel), }} @@ -65,9 +65,8 @@ class Json extends React.PureComponent { } }; - clickListener = (event: MouseEvent) => { + collapseElement = (target: HTMLElement) => { let collapsed; - const target = event.target as HTMLElement; if (target.className === 'collapser') { collapsed = target.parentElement!.getElementsByClassName('collapsible')[0]; if (collapsed.parentElement.classList.contains('collapsed')) { @@ -78,12 +77,24 @@ class Json extends React.PureComponent { } }; + clickListener = (event: MouseEvent) => { + this.collapseElement(event.target as HTMLElement); + }; + + focusListener = (event: KeyboardEvent) => { + if (event.key === 'Enter') { + this.collapseElement(event.target as HTMLElement); + } + }; + componentDidMount() { this.node!.addEventListener('click', this.clickListener); + this.node!.addEventListener('focus', this.focusListener); } componentWillUnmount() { this.node!.removeEventListener('click', this.clickListener); + this.node!.removeEventListener('focus', this.focusListener); } } diff --git a/src/components/JsonViewer/style.ts b/src/components/JsonViewer/style.ts index 14ef6492..82b1677a 100644 --- a/src/components/JsonViewer/style.ts +++ b/src/components/JsonViewer/style.ts @@ -1,12 +1,13 @@ import { css } from '../../styled-components'; export const jsonStyles = css` - .redoc-json > .collapser { + .redoc-json code > .collapser { display: none; + pointer-events: none; } - font-family: ${props => props.theme.typography.code.fontFamily}; - font-size: ${props => props.theme.typography.code.fontSize}; + font-family: ${(props) => props.theme.typography.code.fontFamily}; + font-size: ${(props) => props.theme.typography.code.fontSize}; white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')}; contain: content; @@ -47,8 +48,32 @@ export const jsonStyles = css` } .collapser { + background-color: transparent; + border: 0; + color: #fff; + font-family: ${(props) => props.theme.typography.code.fontFamily}; + font-size: ${(props) => props.theme.typography.code.fontSize}; padding-right: 6px; padding-left: 6px; + padding-top: 0; + padding-bottom: 0; + display: flex; + align-items: center; + justify-content: center; + width: 15px; + height: 15px; + position: absolute; + top: 4px; + left: -1.5em; + cursor: default; + user-select: none; + -webkit-user-select: none; + padding: 2px; + &:focus { + outline-color: #fff; + outline-style: dotted; + outline-width: 1px; + } } ul { @@ -83,13 +108,4 @@ export const jsonStyles = css` .collapsed > .ellipsis { display: inherit; } - - .collapser { - position: absolute; - top: 1px; - left: -1.5em; - cursor: default; - user-select: none; - -webkit-user-select: none; - } `; diff --git a/src/utils/jsonToHtml.ts b/src/utils/jsonToHtml.ts index e950ee2c..65a7edfb 100644 --- a/src/utils/jsonToHtml.ts +++ b/src/utils/jsonToHtml.ts @@ -73,7 +73,7 @@ function valueToHTML(value, maxExpandLevel: number) { function arrayToHTML(json, maxExpandLevel: number) { const collapsed = level > maxExpandLevel ? 'collapsed' : ''; - let output = `
${punctuation( + let output = `${punctuation( '[', )}
    `; let hasContents = false; @@ -98,7 +98,7 @@ function objectToHTML(json, maxExpandLevel: number) { const collapsed = level > maxExpandLevel ? 'collapsed' : ''; const keys = Object.keys(json); const length = keys.length; - let output = `
    ${punctuation( + let output = `${punctuation( '{', )}
      `; let hasContents = false; From 086302bb237e369ec07846425348ba84cc0e95da Mon Sep 17 00:00:00 2001 From: David Goss Date: Tue, 13 Oct 2020 12:56:53 +0100 Subject: [PATCH 05/15] docs: unqualify mobx version for react usage (#1380) Per https://github.com/Redocly/redoc/issues/1189#issuecomment-606857342 the latest version works now, and the currently-specified version doesn't. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 435ce9fc..bf879406 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ For npm: Install peer dependencies required by ReDoc if you don't have them installed already: - npm i react react-dom mobx@^4.2.0 styled-components core-js + npm i react react-dom mobx styled-components core-js Import `RedocStandalone` component from 'redoc' module: From 84ab95ddc7b5dc159098aecf82ad922ffd4a3093 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Tue, 13 Oct 2020 16:21:36 +0300 Subject: [PATCH 06/15] fix: make schema layout more responsive on small screen (#1411) --- src/common-elements/fields-layout.ts | 35 +++++++++++++++++-- .../SecurityRequirement.tsx | 11 ++++-- src/styled-components.ts | 4 +-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/common-elements/fields-layout.ts b/src/common-elements/fields-layout.ts index 533ccb01..e6985f15 100644 --- a/src/common-elements/fields-layout.ts +++ b/src/common-elements/fields-layout.ts @@ -1,6 +1,6 @@ // import { transparentize } from 'polished'; -import styled, { extensionsHook } from '../styled-components'; +import styled, { extensionsHook, media } from '../styled-components'; import { deprecatedCss } from './mixins'; export const PropertiesTableCaption = styled.caption` @@ -16,6 +16,11 @@ export const PropertyCell = styled.td<{ kind?: string }>` position: relative; padding: 10px 10px 10px 0; + ${media.lessThan('small')` + display: block; + overflow: hidden; + `} + tr:first-of-type > &, tr.last > & { border-left-width: 0; @@ -63,7 +68,7 @@ export const PropertyNameCell = styled(PropertyCell)` line-height: 20px; white-space: nowrap; font-size: 13px; - font-family: ${props => props.theme.typography.code.fontFamily}; + font-family: ${(props) => props.theme.typography.code.fontFamily}; &.deprecated { ${deprecatedCss}; @@ -77,12 +82,22 @@ export const PropertyNameCell = styled(PropertyCell)` export const PropertyDetailsCell = styled.td` border-bottom: 1px solid #9fb4be; padding: 10px 0; - width: ${props => props.theme.schema.defaultDetailsWidth}; + width: ${(props) => props.theme.schema.defaultDetailsWidth}; box-sizing: border-box; tr.expanded & { border-bottom: none; } + + ${media.lessThan('small')` + padding: 0 20px; + border-bottom: none; + border-left: 1px solid ${(props) => props.theme.schema.linesColor}; + + tr.last > & { + border-left: none; + } + `} `; export const PropertyBullet = styled.span` @@ -125,6 +140,20 @@ export const PropertiesTable = styled.table` vertical-align: middle; } + ${media.lessThan('small')` + display: block; + > tr, > tbody > tr { + display: block; + } + `} + + ${media.lessThan('small', false, ' and (-ms-high-contrast:none)')` + td { + float: left; + width: 100%; + } + `} + & ${InnerPropertiesWrap}, & diff --git a/src/components/SecurityRequirement/SecurityRequirement.tsx b/src/components/SecurityRequirement/SecurityRequirement.tsx index e6aafb30..3a52ad81 100644 --- a/src/components/SecurityRequirement/SecurityRequirement.tsx +++ b/src/components/SecurityRequirement/SecurityRequirement.tsx @@ -1,7 +1,7 @@ // import { transparentize } from 'polished'; import * as React from 'react'; -import styled from '../../styled-components'; +import styled, { media } from '../../styled-components'; import { Link, UnderlinedHeader } from '../../common-elements/'; import { SecurityRequirementModel } from '../../services/models/SecurityRequirement'; @@ -85,11 +85,14 @@ export class SecurityRequirement extends React.PureComponent props.theme.schema.defaultDetailsWidth}; + ${media.lessThan('small')` + margin-top: 10px; + `} `; const AuthHeader = styled(UnderlinedHeader)` @@ -101,6 +104,10 @@ const Wrap = styled.div` width: 100%; display: flex; margin: 1em 0; + + ${media.lessThan('small')` + flex-direction: column; + `} `; export interface SecurityRequirementsProps { diff --git a/src/styled-components.ts b/src/styled-components.ts index 9db27997..8acd13d4 100644 --- a/src/styled-components.ts +++ b/src/styled-components.ts @@ -13,10 +13,10 @@ const { } = styledComponents as styledComponents.ThemedStyledComponentsModule; export const media = { - lessThan(breakpoint, print?: boolean) { + lessThan(breakpoint, print?: boolean, extra?: string) { return (...args) => css` @media ${print ? 'print, ' : ''} screen and (max-width: ${props => - props.theme.breakpoints[breakpoint]}) { + props.theme.breakpoints[breakpoint]})${extra || ''} { ${(css as any)(...args)}; } `; From a0f15d99f0a26d6ac5d79890da0f1b0cc4919c50 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Tue, 13 Oct 2020 16:58:27 +0300 Subject: [PATCH 07/15] chore: upgrade to mobx@6 (#1412) --- package-lock.json | 6 +++--- package.json | 4 ++-- src/polyfills.ts | 2 ++ src/services/MenuStore.ts | 4 +++- src/services/models/Callback.ts | 4 +++- src/services/models/Field.ts | 4 +++- src/services/models/Group.model.ts | 4 +++- src/services/models/MediaContent.ts | 4 +++- src/services/models/Operation.ts | 4 +++- src/services/models/Response.ts | 4 +++- src/services/models/Schema.ts | 4 +++- src/standalone.tsx | 5 +++++ 12 files changed, 36 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9f4b2201..950b4c0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12998,9 +12998,9 @@ "dev": true }, "mobx": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.4.tgz", - "integrity": "sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.0.1.tgz", + "integrity": "sha512-Pk6uJXZ34yqd661yRmS6z/9avm4FOGXpFpVjnEfiYYOsZXnAxv1fpYjxTCEZ9tuwk0Xe1qnUUlgm+rJtGe0YJA==", "dev": true }, "mobx-react": { diff --git a/package.json b/package.json index 7df1754c..a5ec49be 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "jest": "^26.1.0", "license-checker": "^25.0.1", "lodash": "^4.17.19", - "mobx": "^5.15.4", + "mobx": "^6.0.1", "prettier": "^2.0.5", "raf": "^3.4.1", "react": "^16.13.1", @@ -129,7 +129,7 @@ }, "peerDependencies": { "core-js": "^3.1.4", - "mobx": "^4.2.0 || ^5.0.0", + "mobx": "^6.0.1", "react": "^16.8.4", "react-dom": "^16.8.4", "styled-components": "^4.1.1 || ^5.1.1" diff --git a/src/polyfills.ts b/src/polyfills.ts index 5c8a5635..f0dbc02b 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -2,6 +2,8 @@ import 'core-js/es/promise'; import 'core-js/es/array/find'; import 'core-js/es/object/assign'; +import 'core-js/es/object/entries'; +import 'core-js/es/object/is'; import 'core-js/es/string/ends-with'; import 'core-js/es/string/starts-with'; diff --git a/src/services/MenuStore.ts b/src/services/MenuStore.ts index 2a619af6..ac60fee8 100644 --- a/src/services/MenuStore.ts +++ b/src/services/MenuStore.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { querySelector } from '../utils/dom'; import { SpecStore } from './models'; @@ -76,6 +76,8 @@ export class MenuStore { * @param scroll scroll service instance used by this menu */ constructor(spec: SpecStore, public scroll: ScrollService, public history: HistoryService) { + makeObservable(this); + this.items = spec.contentItems; this.flatItems = flattenByProp(this.items || [], 'items'); diff --git a/src/services/models/Callback.ts b/src/services/models/Callback.ts index 7adfc27f..956537af 100644 --- a/src/services/models/Callback.ts +++ b/src/services/models/Callback.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { OpenAPICallback, Referenced } from '../../types'; import { isOperationName, JsonPointer } from '../../utils'; @@ -19,6 +19,8 @@ export class CallbackModel { pointer: string, options: RedocNormalizedOptions, ) { + makeObservable(this); + this.name = name; const paths = parser.deref(infoOrRef); parser.exitRef(infoOrRef); diff --git a/src/services/models/Field.ts b/src/services/models/Field.ts index b7b0311a..d156b039 100644 --- a/src/services/models/Field.ts +++ b/src/services/models/Field.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { OpenAPIParameter, @@ -61,6 +61,8 @@ export class FieldModel { pointer: string, options: RedocNormalizedOptions, ) { + makeObservable(this); + const info = parser.deref(infoOrRef); this.kind = infoOrRef.kind || 'field'; this.name = infoOrRef.name || info.name; diff --git a/src/services/models/Group.model.ts b/src/services/models/Group.model.ts index be3fc479..f1009f4e 100644 --- a/src/services/models/Group.model.ts +++ b/src/services/models/Group.model.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { OpenAPIExternalDocumentation, OpenAPITag } from '../../types'; import { safeSlugify } from '../../utils'; @@ -35,6 +35,8 @@ export class GroupModel implements IMenuItem { tagOrGroup: OpenAPITag | MarkdownHeading, parent?: GroupModel, ) { + makeObservable(this); + // markdown headings already have ids calculated as they are needed for heading anchors this.id = (tagOrGroup as MarkdownHeading).id || type + '/' + safeSlugify(tagOrGroup.name); this.type = type; diff --git a/src/services/models/MediaContent.ts b/src/services/models/MediaContent.ts index ff2c4950..e993da91 100644 --- a/src/services/models/MediaContent.ts +++ b/src/services/models/MediaContent.ts @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { action, computed, observable, makeObservable } from 'mobx'; import { OpenAPIMediaType } from '../../types'; import { MediaTypeModel } from './MediaType'; @@ -26,6 +26,8 @@ export class MediaContentModel { public isRequestType: boolean, options: RedocNormalizedOptions, ) { + makeObservable(this); + if (options.unstable_ignoreMimeParameters) { info = mergeSimilarMediaTypes(info); } diff --git a/src/services/models/Operation.ts b/src/services/models/Operation.ts index 107865a0..d00461a1 100644 --- a/src/services/models/Operation.ts +++ b/src/services/models/Operation.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { IMenuItem } from '../MenuStore'; import { GroupModel } from './Group.model'; @@ -84,6 +84,8 @@ export class OperationModel implements IMenuItem { private options: RedocNormalizedOptions, isCallback: boolean = false, ) { + makeObservable(this); + this.pointer = operationSpec.pointer; this.description = operationSpec.description; diff --git a/src/services/models/Response.ts b/src/services/models/Response.ts index 3fc4d06c..2b4631ca 100644 --- a/src/services/models/Response.ts +++ b/src/services/models/Response.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { OpenAPIResponse, Referenced } from '../../types'; @@ -26,6 +26,8 @@ export class ResponseModel { infoOrRef: Referenced, options: RedocNormalizedOptions, ) { + makeObservable(this); + this.expanded = options.expandResponses === 'all' || options.expandResponses[code]; const info = parser.deref(infoOrRef); diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index b5986154..dd4a4d6f 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, makeObservable } from 'mobx'; import { OpenAPIExternalDocumentation, OpenAPISchema, Referenced } from '../../types'; @@ -72,6 +72,8 @@ export class SchemaModel { private options: RedocNormalizedOptions, isChild: boolean = false, ) { + makeObservable(this); + this.pointer = schemaOrRef.$ref || pointer || ''; this.rawSchema = parser.deref(schemaOrRef); this.schema = parser.mergeAllOf(this.rawSchema, this.pointer, isChild); diff --git a/src/standalone.tsx b/src/standalone.tsx index fb5a34d6..f0eda0b1 100644 --- a/src/standalone.tsx +++ b/src/standalone.tsx @@ -1,11 +1,16 @@ import * as React from 'react'; import { hydrate as hydrateComponent, render } from 'react-dom'; +import { configure } from "mobx" import { Redoc, RedocStandalone } from './components/'; import { AppStore, StoreState } from './services/AppStore'; import { debugTime, debugTimeEnd } from './utils/debug'; import { querySelector } from './utils/dom'; +configure({ + useProxies: 'ifavailable' +}) + export { Redoc, AppStore } from '.'; export const version = __REDOC_VERSION__; From c90245598e6212b78cdc9a2d3cadac1a730311ec Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Tue, 13 Oct 2020 17:13:35 +0300 Subject: [PATCH 08/15] chore: update test snapshot (#1414) --- .../__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index cab69a5e..3af7ce99 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -9,7 +9,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "deprecated": false, "description": "", "example": undefined, - "expanded": undefined, "explode": false, "in": undefined, "kind": "field", @@ -59,7 +58,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "deprecated": false, "description": "", "example": undefined, - "expanded": undefined, "explode": false, "in": undefined, "kind": "field", From b848988c342775c33cb51b2ea490c6bfde21a633 Mon Sep 17 00:00:00 2001 From: romanhotsiy Date: Tue, 13 Oct 2020 17:19:10 +0300 Subject: [PATCH 09/15] =?UTF-8?q?chore:=20Release=202.0.0-rc.42=20?= =?UTF-8?q?=F0=9F=94=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 11 +++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e00a4ccd..f6decd61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# [2.0.0-rc.42](https://github.com/Redocly/redoc/compare/v2.0.0-rc.41...v2.0.0-rc.42) (2020-10-13) + + +### Bug Fixes + +* hide dropdown input on IE 11 ([#1403](https://github.com/Redocly/redoc/issues/1403)) ([6632d84](https://github.com/Redocly/redoc/commit/6632d844536532227cb92290f9fc2b6b2f913270)) +* make samples accessible by keyboard ([#1401](https://github.com/Redocly/redoc/issues/1401)) ([146b38c](https://github.com/Redocly/redoc/commit/146b38c9d0b926765d8e00dd37204c30bf3ac4e0)) +* make schema layout more responsive on small screen ([#1411](https://github.com/Redocly/redoc/issues/1411)) ([84ab95d](https://github.com/Redocly/redoc/commit/84ab95ddc7b5dc159098aecf82ad922ffd4a3093)) + + + # [2.0.0-rc.41](https://github.com/Redocly/redoc/compare/v2.0.0-rc.40...v2.0.0-rc.41) (2020-09-24) diff --git a/package-lock.json b/package-lock.json index 950b4c0c..67ee9338 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.41", + "version": "2.0.0-rc.42", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a5ec49be..8dac085a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.41", + "version": "2.0.0-rc.42", "description": "ReDoc", "repository": { "type": "git", From 26c407bd0f2bc1ec9881e0a3668e09e645fc0cc0 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Tue, 13 Oct 2020 18:59:58 +0300 Subject: [PATCH 10/15] fix: fix broken observable after mobx upgrade (#1415) --- src/services/models/Callback.ts | 3 ++- src/services/models/Field.ts | 2 +- src/services/models/Response.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/services/models/Callback.ts b/src/services/models/Callback.ts index 956537af..05499f5a 100644 --- a/src/services/models/Callback.ts +++ b/src/services/models/Callback.ts @@ -8,7 +8,8 @@ import { RedocNormalizedOptions } from '../RedocNormalizedOptions'; export class CallbackModel { @observable - expanded: boolean; + expanded: boolean = false; + name: string; operations: OperationModel[] = []; diff --git a/src/services/models/Field.ts b/src/services/models/Field.ts index d156b039..ab30d094 100644 --- a/src/services/models/Field.ts +++ b/src/services/models/Field.ts @@ -39,7 +39,7 @@ const DEFAULT_SERIALIZATION: Record< */ export class FieldModel { @observable - expanded: boolean | undefined; + expanded: boolean | undefined = false; schema: SchemaModel; name: string; diff --git a/src/services/models/Response.ts b/src/services/models/Response.ts index 2b4631ca..f50ee0f1 100644 --- a/src/services/models/Response.ts +++ b/src/services/models/Response.ts @@ -10,7 +10,7 @@ import { MediaContentModel } from './MediaContent'; export class ResponseModel { @observable - expanded: boolean; + expanded: boolean = false; content?: MediaContentModel; code: string; From 129e18b939d071f46907a2bedd8b04bd06d99122 Mon Sep 17 00:00:00 2001 From: romanhotsiy Date: Tue, 13 Oct 2020 19:00:36 +0300 Subject: [PATCH 11/15] =?UTF-8?q?chore:=20Release=202.0.0-rc.43=20?= =?UTF-8?q?=F0=9F=94=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6decd61..6a3041ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [2.0.0-rc.43](https://github.com/Redocly/redoc/compare/v2.0.0-rc.42...v2.0.0-rc.43) (2020-10-13) + + +### Bug Fixes + +* fix broken observable after mobx upgrade ([#1415](https://github.com/Redocly/redoc/issues/1415)) ([26c407b](https://github.com/Redocly/redoc/commit/26c407bd0f2bc1ec9881e0a3668e09e645fc0cc0)) + + + # [2.0.0-rc.42](https://github.com/Redocly/redoc/compare/v2.0.0-rc.41...v2.0.0-rc.42) (2020-10-13) diff --git a/package-lock.json b/package-lock.json index 67ee9338..5c6ac455 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.42", + "version": "2.0.0-rc.43", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8dac085a..668f9c20 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.42", + "version": "2.0.0-rc.43", "description": "ReDoc", "repository": { "type": "git", From d4016b81422984288e626041ef34074a6f11aa21 Mon Sep 17 00:00:00 2001 From: romanhotsiy Date: Tue, 13 Oct 2020 19:10:04 +0300 Subject: [PATCH 12/15] chore: fix tests --- .../__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap | 2 ++ src/services/__tests__/models/Callback.test.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index 3af7ce99..745c4cad 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -9,6 +9,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat "deprecated": false, "description": "", "example": undefined, + "expanded": false, "explode": false, "in": undefined, "kind": "field", @@ -58,6 +59,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat "deprecated": false, "description": "", "example": undefined, + "expanded": false, "explode": false, "in": undefined, "kind": "field", diff --git a/src/services/__tests__/models/Callback.test.ts b/src/services/__tests__/models/Callback.test.ts index 9fb67799..1bfe8ca7 100644 --- a/src/services/__tests__/models/Callback.test.ts +++ b/src/services/__tests__/models/Callback.test.ts @@ -20,7 +20,7 @@ describe('Models', () => { ); expect(callback.name).toEqual('Test.Callback'); expect(callback.operations.length).toEqual(0); - expect(callback.expanded).toBeUndefined(); + expect(callback.expanded).toBeFalsy(); }); }); }); From f5eeacfd054c2fccd566d00858f3230ce5e63f1c Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Wed, 14 Oct 2020 11:49:54 +0300 Subject: [PATCH 13/15] chore: add .vscode to .gitignore (#1416) --- .gitignore | 1 + .vscode/settings.json | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index fa07d0df..5a12009a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ cli/index.js stats.json yarn.lock .idea +.vscode diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 3a19d2f7..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "editor.formatOnSave": true, - "typescript.tsdk": "node_modules/typescript/lib" -} From 0703f73f79a1cabafdc1a908ebb0c5ab142ca825 Mon Sep 17 00:00:00 2001 From: romanhotsiy Date: Fri, 16 Oct 2020 17:41:35 +0300 Subject: [PATCH 14/15] feat: new extensions hook PropertyDetailsCell + wrap property name into span --- src/common-elements/fields-layout.ts | 2 ++ src/components/Fields/Field.tsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common-elements/fields-layout.ts b/src/common-elements/fields-layout.ts index e6985f15..5b9a578f 100644 --- a/src/common-elements/fields-layout.ts +++ b/src/common-elements/fields-layout.ts @@ -98,6 +98,8 @@ export const PropertyDetailsCell = styled.td` border-left: none; } `} + + ${extensionsHook('PropertyDetailsCell')}; `; export const PropertyBullet = styled.span` diff --git a/src/components/Fields/Field.tsx b/src/components/Fields/Field.tsx index 53bedc77..3f18b225 100644 --- a/src/components/Fields/Field.tsx +++ b/src/components/Fields/Field.tsx @@ -64,7 +64,7 @@ export class Field extends React.Component { onKeyPress={this.handleKeyPress} aria-label="expand properties" > - {name} + {name} {required && required } @@ -72,7 +72,7 @@ export class Field extends React.Component { ) : ( - {name} + {name} {required && required } ); From 1fdfd1353dfc07aca5f5d55e5e2195648bde6e2b Mon Sep 17 00:00:00 2001 From: romanhotsiy Date: Fri, 16 Oct 2020 17:57:51 +0300 Subject: [PATCH 15/15] =?UTF-8?q?chore:=20Release=202.0.0-rc.44=20?= =?UTF-8?q?=F0=9F=94=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a3041ed..49f15f5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [2.0.0-rc.44](https://github.com/Redocly/redoc/compare/v2.0.0-rc.43...v2.0.0-rc.44) (2020-10-16) + + +### Features + +* new extensions hook PropertyDetailsCell + wrap property name into span ([0fae030](https://github.com/Redocly/redoc/commit/0fae03099645bd9d3795709175640583b08dfc3d)) + + + # [2.0.0-rc.43](https://github.com/Redocly/redoc/compare/v2.0.0-rc.42...v2.0.0-rc.43) (2020-10-13) diff --git a/package-lock.json b/package-lock.json index 5c6ac455..752dbbbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.43", + "version": "2.0.0-rc.44", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 668f9c20..a8646c96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redoc", - "version": "2.0.0-rc.43", + "version": "2.0.0-rc.44", "description": "ReDoc", "repository": { "type": "git",