Merge branch 'master' into bug/3361-non-required-integers
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ node_modules
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
.eslintcache
|
.eslintcache
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
*.iml
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -82,17 +82,17 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
presets: [
|
presets: [
|
||||||
SwaggerUIBundle.presets.apis,
|
SwaggerUIBundle.presets.apis,
|
||||||
SwaggerUIStandalonePreset
|
SwaggerUIStandalonePreset
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
SwaggerUIBundle.plugins.DownloadUrl
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
],
|
],
|
||||||
layout: "StandaloneLayout"
|
layout: "StandaloneLayout"
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
#### OAuth2 configuration
|
#### OAuth2 configuration
|
||||||
@@ -137,6 +137,7 @@ spec | A JSON object describing the OpenAPI Specification. When used, the `url`
|
|||||||
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
|
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
|
||||||
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
|
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
|
||||||
oauth2RedirectUrl | OAuth redirect URL
|
oauth2RedirectUrl | OAuth redirect URL
|
||||||
|
tagsSorter | Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger-UI.
|
||||||
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
|
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
|
||||||
configUrl | Configs URL
|
configUrl | Configs URL
|
||||||
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
|
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
|
||||||
@@ -144,6 +145,8 @@ modelPropertyMacro | MUST be a function. Function to set default values to each
|
|||||||
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
|
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
|
||||||
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
|
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
|
||||||
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
|
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
|
||||||
|
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
||||||
|
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
<style>
|
<style>
|
||||||
html
|
html
|
||||||
{
|
{
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: -moz-scrollbars-vertical;
|
overflow: -moz-scrollbars-vertical;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
*,
|
*,
|
||||||
*:before,
|
*:before,
|
||||||
*:after
|
*:after
|
||||||
{
|
{
|
||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
|
||||||
<defs>
|
<defs>
|
||||||
<symbol viewBox="0 0 20 20" id="unlocked">
|
<symbol viewBox="0 0 20 20" id="unlocked">
|
||||||
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
|
||||||
</symbol>
|
</symbol>
|
||||||
|
|
||||||
<symbol viewBox="0 0 20 20" id="locked">
|
<symbol viewBox="0 0 20 20" id="locked">
|
||||||
@@ -70,34 +70,34 @@
|
|||||||
<script src="./swagger-ui-bundle.js"> </script>
|
<script src="./swagger-ui-bundle.js"> </script>
|
||||||
<script src="./swagger-ui-standalone-preset.js"> </script>
|
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
|
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
|
||||||
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
|
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
|
||||||
// Build a system
|
// Build a system
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
presets: [
|
presets: [
|
||||||
SwaggerUIBundle.presets.apis,
|
SwaggerUIBundle.presets.apis,
|
||||||
SwaggerUIStandalonePreset
|
SwaggerUIStandalonePreset
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
SwaggerUIBundle.plugins.DownloadUrl
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
],
|
],
|
||||||
layout: "StandaloneLayout"
|
layout: "StandaloneLayout"
|
||||||
})
|
})
|
||||||
|
|
||||||
window.ui = ui
|
window.ui = ui
|
||||||
|
|
||||||
ui.initOAuth({
|
ui.initOAuth({
|
||||||
clientId: "your-client-id",
|
clientId: "your-client-id",
|
||||||
clientSecret: "your-client-secret-if-required",
|
clientSecret: "your-client-secret-if-required",
|
||||||
realm: "your-realms",
|
realm: "your-realms",
|
||||||
appName: "your-app-name",
|
appName: "your-app-name",
|
||||||
scopeSeparator: " ",
|
scopeSeparator: " ",
|
||||||
additionalQueryStringParams: {}
|
additionalQueryStringParams: {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
var path = require('path')
|
var path = require("path")
|
||||||
|
|
||||||
var webpack = require('webpack')
|
var webpack = require("webpack")
|
||||||
var ExtractTextPlugin = require('extract-text-webpack-plugin')
|
var ExtractTextPlugin = require("extract-text-webpack-plugin")
|
||||||
var deepExtend = require('deep-extend')
|
var deepExtend = require("deep-extend")
|
||||||
const {gitDescribeSync} = require('git-describe');
|
const {gitDescribeSync} = require("git-describe")
|
||||||
|
const os = require("os")
|
||||||
|
|
||||||
var pkg = require('./package.json')
|
var pkg = require("./package.json")
|
||||||
|
|
||||||
let gitInfo
|
let gitInfo
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ try {
|
|||||||
gitInfo = gitDescribeSync(__dirname)
|
gitInfo = gitDescribeSync(__dirname)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
gitInfo = {
|
gitInfo = {
|
||||||
hash: 'noGit',
|
hash: "noGit",
|
||||||
dirty: false
|
dirty: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,21 +22,21 @@ try {
|
|||||||
var commonRules = [
|
var commonRules = [
|
||||||
{ test: /\.(js(x)?)(\?.*)?$/,
|
{ test: /\.(js(x)?)(\?.*)?$/,
|
||||||
use: [{
|
use: [{
|
||||||
loader: 'babel-loader',
|
loader: "babel-loader",
|
||||||
options: {
|
options: {
|
||||||
retainLines: true
|
retainLines: true
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
include: [ path.join(__dirname, 'src') ]
|
include: [ path.join(__dirname, "src") ]
|
||||||
},
|
},
|
||||||
{ test: /\.(txt|yaml)(\?.*)?$/,
|
{ test: /\.(txt|yaml)(\?.*)?$/,
|
||||||
loader: 'raw-loader' },
|
loader: "raw-loader" },
|
||||||
{ test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/,
|
{ test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/,
|
||||||
loader: 'url-loader?limit=10000' },
|
loader: "url-loader?limit=10000" },
|
||||||
{ test: /\.(woff|woff2)(\?.*)?$/,
|
{ test: /\.(woff|woff2)(\?.*)?$/,
|
||||||
loader: 'url-loader?limit=100000' },
|
loader: "url-loader?limit=100000" },
|
||||||
{ test: /\.(ttf|eot)(\?.*)?$/,
|
{ test: /\.(ttf|eot)(\?.*)?$/,
|
||||||
loader: 'file-loader' }
|
loader: "file-loader" }
|
||||||
]
|
]
|
||||||
|
|
||||||
module.exports = function(rules, options) {
|
module.exports = function(rules, options) {
|
||||||
@@ -54,7 +55,7 @@ module.exports = function(rules, options) {
|
|||||||
|
|
||||||
if( specialOptions.separateStylesheets ) {
|
if( specialOptions.separateStylesheets ) {
|
||||||
plugins.push(new ExtractTextPlugin({
|
plugins.push(new ExtractTextPlugin({
|
||||||
filename: '[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''),
|
filename: "[name].css" + (specialOptions.longTermCaching ? "?[contenthash]" : ""),
|
||||||
allChunks: true
|
allChunks: true
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -78,35 +79,36 @@ module.exports = function(rules, options) {
|
|||||||
|
|
||||||
plugins.push(
|
plugins.push(
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
'process.env': {
|
"process.env": {
|
||||||
NODE_ENV: specialOptions.minimize ? JSON.stringify('production') : null,
|
NODE_ENV: specialOptions.minimize ? JSON.stringify("production") : null,
|
||||||
WEBPACK_INLINE_STYLES: !Boolean(specialOptions.separateStylesheets)
|
WEBPACK_INLINE_STYLES: !specialOptions.separateStylesheets
|
||||||
|
|
||||||
},
|
},
|
||||||
'buildInfo': JSON.stringify({
|
"buildInfo": JSON.stringify({
|
||||||
PACKAGE_VERSION: (pkg.version),
|
PACKAGE_VERSION: (pkg.version),
|
||||||
GIT_COMMIT: gitInfo.hash,
|
GIT_COMMIT: gitInfo.hash,
|
||||||
GIT_DIRTY: gitInfo.dirty
|
GIT_DIRTY: gitInfo.dirty,
|
||||||
|
HOSTNAME: os.hostname(),
|
||||||
|
BUILD_TIME: new Date().toUTCString()
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
delete options._special
|
delete options._special
|
||||||
|
|
||||||
var completeConfig = deepExtend({
|
var completeConfig = deepExtend({
|
||||||
entry: {},
|
entry: {},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'dist'),
|
path: path.join(__dirname, "dist"),
|
||||||
publicPath: '/',
|
publicPath: "/",
|
||||||
filename: '[name].js',
|
filename: "[name].js",
|
||||||
chunkFilename: '[name].js'
|
chunkFilename: "[name].js"
|
||||||
},
|
},
|
||||||
|
|
||||||
target: 'web',
|
target: "web",
|
||||||
|
|
||||||
// yaml-js has a reference to `fs`, this is a workaround
|
// yaml-js has a reference to `fs`, this is a workaround
|
||||||
node: {
|
node: {
|
||||||
fs: 'empty'
|
fs: "empty"
|
||||||
},
|
},
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
@@ -114,17 +116,17 @@ module.exports = function(rules, options) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
resolveLoader: {
|
resolveLoader: {
|
||||||
modules: [path.join(__dirname, 'node_modules')],
|
modules: [path.join(__dirname, "node_modules")],
|
||||||
},
|
},
|
||||||
|
|
||||||
externals: {
|
externals: {
|
||||||
'buffertools': true // json-react-schema/deeper depends on buffertools, which fails.
|
"buffertools": true // json-react-schema/deeper depends on buffertools, which fails.
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: [
|
modules: [
|
||||||
path.join(__dirname, './src'),
|
path.join(__dirname, "./src"),
|
||||||
'node_modules'
|
"node_modules"
|
||||||
],
|
],
|
||||||
extensions: [".web.js", ".js", ".jsx", ".json", ".less"],
|
extensions: [".web.js", ".js", ".jsx", ".json", ".less"],
|
||||||
alias: {
|
alias: {
|
||||||
@@ -132,7 +134,7 @@ module.exports = function(rules, options) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
devtool: specialOptions.sourcemaps ? 'cheap-module-source-map' : null,
|
devtool: specialOptions.sourcemaps ? "cheap-module-source-map" : null,
|
||||||
|
|
||||||
plugins,
|
plugins,
|
||||||
|
|
||||||
|
|||||||
44
src/core/components/array-model.jsx
Normal file
44
src/core/components/array-model.jsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import React, { Component } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||||
|
|
||||||
|
export default class ArrayModel extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string,
|
||||||
|
required: PropTypes.bool,
|
||||||
|
expandDepth: PropTypes.number,
|
||||||
|
depth: PropTypes.number
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
let { getComponent, required, schema, depth, expandDepth } = this.props
|
||||||
|
let items = schema.get("items")
|
||||||
|
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
|
||||||
|
|
||||||
|
const ModelCollapse = getComponent("ModelCollapse")
|
||||||
|
const Model = getComponent("Model")
|
||||||
|
|
||||||
|
return <span className="model">
|
||||||
|
<span className="model-title">
|
||||||
|
<span className="model-title__text">{ schema.get("title") }</span>
|
||||||
|
</span>
|
||||||
|
<ModelCollapse collapsed={ depth > expandDepth } collapsedContent="[...]">
|
||||||
|
[
|
||||||
|
<span><Model { ...this.props } schema={ items } required={ false }/></span>
|
||||||
|
]
|
||||||
|
{
|
||||||
|
properties.size ? <span>
|
||||||
|
{ properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={propStyle}>
|
||||||
|
<br />{ `${key}:`}{ String(v) }</span>)
|
||||||
|
}<br /></span>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</ModelCollapse>
|
||||||
|
{ required && <span style={{ color: "red" }}>*</span>}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/core/components/enum-model.jsx
Normal file
19
src/core/components/enum-model.jsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import React from "react"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
|
const EnumModel = ({ value, getComponent }) => {
|
||||||
|
let ModelCollapse = getComponent("ModelCollapse")
|
||||||
|
let collapsedContent = <span>Array [ { value.count() } ]</span>
|
||||||
|
return <span className="prop-enum">
|
||||||
|
Enum:<br />
|
||||||
|
<ModelCollapse collapsedContent={ collapsedContent }>
|
||||||
|
[ { value.join(", ") } ]
|
||||||
|
</ModelCollapse>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
EnumModel.propTypes = {
|
||||||
|
value: ImPropTypes.iterable,
|
||||||
|
getComponent: ImPropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnumModel
|
||||||
@@ -13,8 +13,13 @@ export default class BaseLayout extends React.Component {
|
|||||||
getComponent: PropTypes.func.isRequired
|
getComponent: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFilterChange =(e) => {
|
||||||
|
let {target: {value}} = e
|
||||||
|
this.props.layoutActions.updateFilter(value)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { specSelectors, specActions, getComponent } = this.props
|
let { specSelectors, specActions, getComponent, layoutSelectors } = this.props
|
||||||
|
|
||||||
let info = specSelectors.info()
|
let info = specSelectors.info()
|
||||||
let url = specSelectors.url()
|
let url = specSelectors.url()
|
||||||
@@ -26,11 +31,20 @@ export default class BaseLayout extends React.Component {
|
|||||||
|
|
||||||
let Info = getComponent("info")
|
let Info = getComponent("info")
|
||||||
let Operations = getComponent("operations", true)
|
let Operations = getComponent("operations", true)
|
||||||
let Models = getComponent("models", true)
|
let Models = getComponent("Models", true)
|
||||||
let AuthorizeBtn = getComponent("authorizeBtn", true)
|
let AuthorizeBtn = getComponent("authorizeBtn", true)
|
||||||
let Row = getComponent("Row")
|
let Row = getComponent("Row")
|
||||||
let Col = getComponent("Col")
|
let Col = getComponent("Col")
|
||||||
let Errors = getComponent("errors", true)
|
let Errors = getComponent("errors", true)
|
||||||
|
|
||||||
|
let isLoading = specSelectors.loadingStatus() === "loading"
|
||||||
|
let isFailed = specSelectors.loadingStatus() === "failed"
|
||||||
|
let filter = layoutSelectors.currentFilter()
|
||||||
|
|
||||||
|
let inputStyle = {}
|
||||||
|
if(isFailed) inputStyle.color = "red"
|
||||||
|
if(isLoading) inputStyle.color = "#aaa"
|
||||||
|
|
||||||
const Schemes = getComponent("schemes")
|
const Schemes = getComponent("schemes")
|
||||||
|
|
||||||
const isSpecEmpty = !specSelectors.specStr()
|
const isSpecEmpty = !specSelectors.specStr()
|
||||||
@@ -57,6 +71,7 @@ export default class BaseLayout extends React.Component {
|
|||||||
{ schemes && schemes.size ? (
|
{ schemes && schemes.size ? (
|
||||||
<Schemes schemes={ schemes } specActions={ specActions } />
|
<Schemes schemes={ schemes } specActions={ specActions } />
|
||||||
) : null }
|
) : null }
|
||||||
|
|
||||||
{ securityDefinitions ? (
|
{ securityDefinitions ? (
|
||||||
<AuthorizeBtn />
|
<AuthorizeBtn />
|
||||||
) : null }
|
) : null }
|
||||||
@@ -64,6 +79,15 @@ export default class BaseLayout extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
) : null }
|
) : null }
|
||||||
|
|
||||||
|
{
|
||||||
|
filter === null || filter === false ? null :
|
||||||
|
<div className="filter-container">
|
||||||
|
<Col className="filter wrapper" mobile={12}>
|
||||||
|
<input className="operation-filter-input" placeholder="Filter by tag" type="text" onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter} disabled={isLoading} style={inputStyle} />
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<Col mobile={12} desktop={12} >
|
<Col mobile={12} desktop={12} >
|
||||||
<Operations/>
|
<Operations/>
|
||||||
|
|||||||
41
src/core/components/model-collapse.jsx
Normal file
41
src/core/components/model-collapse.jsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import React, { Component } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
export default class ModelCollapse extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
collapsedContent: PropTypes.any,
|
||||||
|
collapsed: PropTypes.bool,
|
||||||
|
children: PropTypes.any
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
collapsedContent: "{...}",
|
||||||
|
collapsed: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
|
||||||
|
let { collapsed, collapsedContent } = this.props
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
collapsed: collapsed !== undefined ? collapsed : ModelCollapse.defaultProps.collapsed,
|
||||||
|
collapsedContent: collapsedContent || ModelCollapse.defaultProps.collapsedContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCollapsed=()=>{
|
||||||
|
this.setState({
|
||||||
|
collapsed: !this.state.collapsed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (<span>
|
||||||
|
<span onClick={ this.toggleCollapsed } style={{ "cursor": "pointer" }}>
|
||||||
|
<span className={ "model-toggle" + ( this.state.collapsed ? " collapsed" : "" ) }></span>
|
||||||
|
</span>
|
||||||
|
{ this.state.collapsed ? this.state.collapsedContent : this.props.children }
|
||||||
|
</span>)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ export default class ModelExample extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { getComponent, specSelectors, schema, example, isExecute } = this.props
|
let { getComponent, specSelectors, schema, example, isExecute } = this.props
|
||||||
const Model = getComponent("model")
|
const ModelWrapper = getComponent("ModelWrapper")
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<ul className="tab">
|
<ul className="tab">
|
||||||
@@ -44,7 +44,7 @@ export default class ModelExample extends React.Component {
|
|||||||
(isExecute || this.state.activeTab === "example") && example
|
(isExecute || this.state.activeTab === "example") && example
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!isExecute && this.state.activeTab === "model" && <Model schema={ schema }
|
!isExecute && this.state.activeTab === "model" && <ModelWrapper schema={ schema }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
expandDepth={ 1 } />
|
expandDepth={ 1 } />
|
||||||
|
|||||||
23
src/core/components/model-wrapper.jsx
Normal file
23
src/core/components/model-wrapper.jsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React, { Component, } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
export default class ModelComponent extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
expandDepth: PropTypes.number
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
let { getComponent } = this.props
|
||||||
|
const Model = getComponent("Model")
|
||||||
|
|
||||||
|
return <div className="model-box">
|
||||||
|
<Model { ...this.props } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,219 +1,7 @@
|
|||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
|
||||||
import { List } from "immutable"
|
|
||||||
const braceOpen = "{"
|
|
||||||
const braceClose = "}"
|
|
||||||
|
|
||||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
export default class Model extends Component {
|
||||||
|
|
||||||
const EnumModel = ({ value }) => {
|
|
||||||
let collapsedContent = <span>Array [ { value.count() } ]</span>
|
|
||||||
return <span className="prop-enum">
|
|
||||||
Enum:<br />
|
|
||||||
<Collapse collapsedContent={ collapsedContent }>
|
|
||||||
[ { value.join(", ") } ]
|
|
||||||
</Collapse>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
EnumModel.propTypes = {
|
|
||||||
value: ImPropTypes.iterable
|
|
||||||
}
|
|
||||||
|
|
||||||
class ObjectModel extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
schema: PropTypes.object.isRequired,
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
specSelectors: PropTypes.object.isRequired,
|
|
||||||
name: PropTypes.string,
|
|
||||||
isRef: PropTypes.bool,
|
|
||||||
expandDepth: PropTypes.number,
|
|
||||||
depth: PropTypes.number
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let { schema, name, isRef, getComponent, depth, ...props } = this.props
|
|
||||||
let { expandDepth } = this.props
|
|
||||||
const JumpToPath = getComponent("JumpToPath", true)
|
|
||||||
let description = schema.get("description")
|
|
||||||
let properties = schema.get("properties")
|
|
||||||
let additionalProperties = schema.get("additionalProperties")
|
|
||||||
let title = schema.get("title") || name
|
|
||||||
let required = schema.get("required")
|
|
||||||
const Markdown = getComponent("Markdown")
|
|
||||||
const JumpToPathSection = ({ name }) => <span className="model-jump-to-path"><JumpToPath path={`definitions.${name}`} /></span>
|
|
||||||
let collapsedContent = (<span>
|
|
||||||
<span>{ braceOpen }</span>...<span>{ braceClose }</span>
|
|
||||||
{
|
|
||||||
isRef ? <JumpToPathSection name={ name }/> : ""
|
|
||||||
}
|
|
||||||
</span>)
|
|
||||||
|
|
||||||
return <span className="model">
|
|
||||||
{
|
|
||||||
title && <span className="model-title">
|
|
||||||
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
|
|
||||||
<span className="model-title__text">{ title }</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
<Collapse collapsed={ depth > expandDepth } collapsedContent={ collapsedContent }>
|
|
||||||
<span className="brace-open object">{ braceOpen }</span>
|
|
||||||
{
|
|
||||||
!isRef ? null : <JumpToPathSection name={ name }/>
|
|
||||||
}
|
|
||||||
<span className="inner-object">
|
|
||||||
{
|
|
||||||
<table className="model" style={{ marginLeft: "2em" }}><tbody>
|
|
||||||
{
|
|
||||||
!description ? null : <tr style={{ color: "#999", fontStyle: "italic" }}>
|
|
||||||
<td>description:</td>
|
|
||||||
<td>
|
|
||||||
<Markdown source={ description } />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!(properties && properties.size) ? null : properties.entrySeq().map(
|
|
||||||
([key, value]) => {
|
|
||||||
let isRequired = List.isList(required) && required.contains(key)
|
|
||||||
let propertyStyle = { verticalAlign: "top", paddingRight: "0.2em" }
|
|
||||||
if ( isRequired ) {
|
|
||||||
propertyStyle.fontWeight = "bold"
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<tr key={key}>
|
|
||||||
<td style={ propertyStyle }>{ key }:</td>
|
|
||||||
<td style={{ verticalAlign: "top" }}>
|
|
||||||
<Model key={ `object-${name}-${key}_${value}` } { ...props }
|
|
||||||
required={ isRequired }
|
|
||||||
getComponent={ getComponent }
|
|
||||||
schema={ value }
|
|
||||||
depth={ depth + 1 } />
|
|
||||||
</td>
|
|
||||||
</tr>)
|
|
||||||
}).toArray()
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!additionalProperties || !additionalProperties.size ? null
|
|
||||||
: <tr>
|
|
||||||
<td>{ "< * >:" }</td>
|
|
||||||
<td>
|
|
||||||
<Model { ...props } required={ false }
|
|
||||||
getComponent={ getComponent }
|
|
||||||
schema={ additionalProperties }
|
|
||||||
depth={ depth + 1 } />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody></table>
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
<span className="brace-close">{ braceClose }</span>
|
|
||||||
</Collapse>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Primitive extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
schema: PropTypes.object.isRequired,
|
|
||||||
name: PropTypes.string,
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
required: PropTypes.bool
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let { schema, getComponent, name, required } = this.props
|
|
||||||
|
|
||||||
if(!schema || !schema.get) {
|
|
||||||
// don't render if schema isn't correctly formed
|
|
||||||
return <div></div>
|
|
||||||
}
|
|
||||||
|
|
||||||
let type = schema.get("type")
|
|
||||||
let format = schema.get("format")
|
|
||||||
let xml = schema.get("xml")
|
|
||||||
let enumArray = schema.get("enum")
|
|
||||||
let title = schema.get("title") || name
|
|
||||||
let description = schema.get("description")
|
|
||||||
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
|
||||||
let style = required ? { fontWeight: "bold" } : {}
|
|
||||||
const Markdown = getComponent("Markdown")
|
|
||||||
|
|
||||||
return <span className="model">
|
|
||||||
{
|
|
||||||
title && <span className="model-title" style={{ marginRight: "2em" }}>
|
|
||||||
<span className="model-title__text">{ title }</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
|
|
||||||
{ format && <span className="prop-format">(${format})</span>}
|
|
||||||
{
|
|
||||||
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
|
|
||||||
<br />{ key }: { String(v) }</span>)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!description ? null :
|
|
||||||
<Markdown source={ description } />
|
|
||||||
}
|
|
||||||
{
|
|
||||||
xml && xml.size ? (<span><br /><span style={ propStyle }>xml:</span>
|
|
||||||
{
|
|
||||||
xml.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }><br/> {key}: { String(v) }</span>).toArray()
|
|
||||||
}
|
|
||||||
</span>): null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
enumArray && <EnumModel value={ enumArray } />
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ArrayModel extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
schema: PropTypes.object.isRequired,
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
specSelectors: PropTypes.object.isRequired,
|
|
||||||
name: PropTypes.string,
|
|
||||||
required: PropTypes.bool,
|
|
||||||
expandDepth: PropTypes.number,
|
|
||||||
depth: PropTypes.number
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let { required, schema, depth, name, expandDepth } = this.props
|
|
||||||
let items = schema.get("items")
|
|
||||||
let title = schema.get("title") || name
|
|
||||||
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
|
|
||||||
|
|
||||||
return <span className="model">
|
|
||||||
{
|
|
||||||
title && <span className="model-title">
|
|
||||||
<span className="model-title__text">{ title }</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
<Collapse collapsed={ depth > expandDepth } collapsedContent="[...]">
|
|
||||||
[
|
|
||||||
<span><Model { ...this.props } name="" schema={ items } required={ false }/></span>
|
|
||||||
]
|
|
||||||
{
|
|
||||||
properties.size ? <span>
|
|
||||||
{ properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={propStyle}>
|
|
||||||
<br />{ `${key}:`}{ String(v) }</span>)
|
|
||||||
}<br /></span>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</Collapse>
|
|
||||||
{ required && <span style={{ color: "red" }}>*</span>}
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Model extends Component {
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
schema: PropTypes.object.isRequired,
|
schema: PropTypes.object.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
@@ -239,6 +27,9 @@ class Model extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
let { schema, getComponent, required, name, isRef } = this.props
|
let { schema, getComponent, required, name, isRef } = this.props
|
||||||
|
let ObjectModel = getComponent("ObjectModel")
|
||||||
|
let ArrayModel = getComponent("ArrayModel")
|
||||||
|
let PrimitiveModel = getComponent("PrimitiveModel")
|
||||||
let $$ref = schema && schema.get("$$ref")
|
let $$ref = schema && schema.get("$$ref")
|
||||||
let modelName = $$ref && this.getModelName( $$ref )
|
let modelName = $$ref && this.getModelName( $$ref )
|
||||||
let modelSchema, type
|
let modelSchema, type
|
||||||
@@ -260,69 +51,13 @@ class Model extends Component {
|
|||||||
name={ name || modelName }
|
name={ name || modelName }
|
||||||
isRef={ isRef!== undefined ? isRef : !!$$ref }/>
|
isRef={ isRef!== undefined ? isRef : !!$$ref }/>
|
||||||
case "array":
|
case "array":
|
||||||
return <ArrayModel className="array" { ...this.props } schema={ modelSchema } name={ name || modelName } required={ required } />
|
return <ArrayModel className="array" { ...this.props } schema={ modelSchema } required={ required } />
|
||||||
case "string":
|
case "string":
|
||||||
case "number":
|
case "number":
|
||||||
case "integer":
|
case "integer":
|
||||||
case "boolean":
|
case "boolean":
|
||||||
default:
|
default:
|
||||||
return <Primitive { ...this.props } getComponent={ getComponent } schema={ modelSchema } name={ name || modelName } required={ required }/>
|
return <PrimitiveModel getComponent={ getComponent } schema={ modelSchema } required={ required }/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class ModelComponent extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
schema: PropTypes.object.isRequired,
|
|
||||||
name: PropTypes.string,
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
|
||||||
specSelectors: PropTypes.object.isRequired,
|
|
||||||
expandDepth: PropTypes.number
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
return <div className="model-box">
|
|
||||||
<Model { ...this.props } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Collapse extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
collapsedContent: PropTypes.any,
|
|
||||||
collapsed: PropTypes.bool,
|
|
||||||
children: PropTypes.any
|
|
||||||
}
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
collapsedContent: "{...}",
|
|
||||||
collapsed: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context)
|
|
||||||
|
|
||||||
let { collapsed, collapsedContent } = this.props
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
collapsed: collapsed !== undefined ? collapsed : Collapse.defaultProps.collapsed,
|
|
||||||
collapsedContent: collapsedContent || Collapse.defaultProps.collapsedContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCollapsed=()=>{
|
|
||||||
this.setState({
|
|
||||||
collapsed: !this.state.collapsed
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return (<span>
|
|
||||||
<span onClick={ this.toggleCollapsed } style={{ "cursor": "pointer" }}>
|
|
||||||
<span className={ "model-toggle" + ( this.state.collapsed ? " collapsed" : "" ) }></span>
|
|
||||||
</span>
|
|
||||||
{ this.state.collapsed ? this.state.collapsedContent : this.props.children }
|
|
||||||
</span>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default class Models extends Component {
|
|||||||
let { docExpansion } = getConfigs()
|
let { docExpansion } = getConfigs()
|
||||||
let showModels = layoutSelectors.isShown("models", docExpansion === "full" || docExpansion === "list" )
|
let showModels = layoutSelectors.isShown("models", docExpansion === "full" || docExpansion === "list" )
|
||||||
|
|
||||||
const Model = getComponent("model")
|
const ModelWrapper = getComponent("ModelWrapper")
|
||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
|
|
||||||
if (!definitions.size) return null
|
if (!definitions.size) return null
|
||||||
@@ -24,15 +24,15 @@ export default class Models extends Component {
|
|||||||
return <section className={ showModels ? "models is-open" : "models"}>
|
return <section className={ showModels ? "models is-open" : "models"}>
|
||||||
<h4 onClick={() => layoutActions.show("models", !showModels)}>
|
<h4 onClick={() => layoutActions.show("models", !showModels)}>
|
||||||
<span>Models</span>
|
<span>Models</span>
|
||||||
<svg className="arrow" width="20" height="20">
|
<svg width="20" height="20">
|
||||||
<use xlinkHref={showModels ? "#large-arrow-down" : "#large-arrow"} />
|
<use xlinkHref="#large-arrow" />
|
||||||
</svg>
|
</svg>
|
||||||
</h4>
|
</h4>
|
||||||
<Collapse isOpened={showModels} animated>
|
<Collapse isOpened={showModels} animated>
|
||||||
{
|
{
|
||||||
definitions.entrySeq().map( ( [ name, model ])=>{
|
definitions.entrySeq().map( ( [ name, model ])=>{
|
||||||
return <div className="model-container" key={ `models-section-${name}` }>
|
return <div className="model-container" key={ `models-section-${name}` }>
|
||||||
<Model name={ name }
|
<ModelWrapper name={ name }
|
||||||
schema={ model }
|
schema={ model }
|
||||||
isRef={ true }
|
isRef={ true }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
|
|||||||
105
src/core/components/object-model.jsx
Normal file
105
src/core/components/object-model.jsx
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import React, { Component, } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import { List } from "immutable"
|
||||||
|
|
||||||
|
const braceOpen = "{"
|
||||||
|
const braceClose = "}"
|
||||||
|
|
||||||
|
export default class ObjectModel extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
specSelectors: PropTypes.object.isRequired,
|
||||||
|
name: PropTypes.string,
|
||||||
|
isRef: PropTypes.bool,
|
||||||
|
expandDepth: PropTypes.number,
|
||||||
|
depth: PropTypes.number
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
let { schema, name, isRef, getComponent, depth, ...props } = this.props
|
||||||
|
let { expandDepth } = this.props
|
||||||
|
let description = schema.get("description")
|
||||||
|
let properties = schema.get("properties")
|
||||||
|
let additionalProperties = schema.get("additionalProperties")
|
||||||
|
let title = schema.get("title") || name
|
||||||
|
let required = schema.get("required")
|
||||||
|
|
||||||
|
const JumpToPath = getComponent("JumpToPath", true)
|
||||||
|
const Markdown = getComponent("Markdown")
|
||||||
|
const Model = getComponent("Model")
|
||||||
|
const ModelCollapse = getComponent("ModelCollapse")
|
||||||
|
|
||||||
|
const JumpToPathSection = ({ name }) => <span className="model-jump-to-path"><JumpToPath path={`definitions.${name}`} /></span>
|
||||||
|
const collapsedContent = (<span>
|
||||||
|
<span>{ braceOpen }</span>...<span>{ braceClose }</span>
|
||||||
|
{
|
||||||
|
isRef ? <JumpToPathSection name={ name }/> : ""
|
||||||
|
}
|
||||||
|
</span>)
|
||||||
|
|
||||||
|
|
||||||
|
return <span className="model">
|
||||||
|
{
|
||||||
|
title && <span className="model-title">
|
||||||
|
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
|
||||||
|
<span className="model-title__text">{ title }</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
<ModelCollapse collapsed={ depth > expandDepth } collapsedContent={ collapsedContent }>
|
||||||
|
<span className="brace-open object">{ braceOpen }</span>
|
||||||
|
{
|
||||||
|
!isRef ? null : <JumpToPathSection name={ name }/>
|
||||||
|
}
|
||||||
|
<span className="inner-object">
|
||||||
|
{
|
||||||
|
<table className="model" style={{ marginLeft: "2em" }}><tbody>
|
||||||
|
{
|
||||||
|
!description ? null : <tr style={{ color: "#999", fontStyle: "italic" }}>
|
||||||
|
<td>description:</td>
|
||||||
|
<td>
|
||||||
|
<Markdown source={ description } />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!(properties && properties.size) ? null : properties.entrySeq().map(
|
||||||
|
([key, value]) => {
|
||||||
|
let isRequired = List.isList(required) && required.contains(key)
|
||||||
|
let propertyStyle = { verticalAlign: "top", paddingRight: "0.2em" }
|
||||||
|
if ( isRequired ) {
|
||||||
|
propertyStyle.fontWeight = "bold"
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<tr key={key}>
|
||||||
|
<td style={ propertyStyle }>{ key }:</td>
|
||||||
|
<td style={{ verticalAlign: "top" }}>
|
||||||
|
<Model key={ `object-${name}-${key}_${value}` } { ...props }
|
||||||
|
required={ isRequired }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
schema={ value }
|
||||||
|
depth={ depth + 1 } />
|
||||||
|
</td>
|
||||||
|
</tr>)
|
||||||
|
}).toArray()
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!additionalProperties || !additionalProperties.size ? null
|
||||||
|
: <tr>
|
||||||
|
<td>{ "< * >:" }</td>
|
||||||
|
<td>
|
||||||
|
<Model { ...props } required={ false }
|
||||||
|
getComponent={ getComponent }
|
||||||
|
schema={ additionalProperties }
|
||||||
|
depth={ depth + 1 } />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody></table>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
<span className="brace-close">{ braceClose }</span>
|
||||||
|
</ModelCollapse>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,21 @@ export default class Operations extends React.Component {
|
|||||||
const Collapse = getComponent("Collapse")
|
const Collapse = getComponent("Collapse")
|
||||||
|
|
||||||
let showSummary = layoutSelectors.showSummary()
|
let showSummary = layoutSelectors.showSummary()
|
||||||
let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs()
|
let { docExpansion, displayOperationId, displayRequestDuration, maxDisplayedTags } = getConfigs()
|
||||||
|
|
||||||
|
let filter = layoutSelectors.currentFilter()
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
if (filter !== true) {
|
||||||
|
taggedOps = taggedOps.filter((tagObj, tag) => {
|
||||||
|
return tag.indexOf(filter) !== -1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDisplayedTags && !isNaN(maxDisplayedTags) && maxDisplayedTags >= 0) {
|
||||||
|
taggedOps = taggedOps.slice(0, maxDisplayedTags)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
55
src/core/components/primitive-model.jsx
Normal file
55
src/core/components/primitive-model.jsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import React, { Component } from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||||
|
|
||||||
|
export default class Primitive extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
schema: PropTypes.object.isRequired,
|
||||||
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
required: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
let { schema, getComponent, required } = this.props
|
||||||
|
|
||||||
|
if(!schema || !schema.get) {
|
||||||
|
// don't render if schema isn't correctly formed
|
||||||
|
return <div></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
let type = schema.get("type")
|
||||||
|
let format = schema.get("format")
|
||||||
|
let xml = schema.get("xml")
|
||||||
|
let enumArray = schema.get("enum")
|
||||||
|
let description = schema.get("description")
|
||||||
|
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
||||||
|
let style = required ? { fontWeight: "bold" } : {}
|
||||||
|
const Markdown = getComponent("Markdown")
|
||||||
|
const EnumModel = getComponent("EnumModel")
|
||||||
|
|
||||||
|
return <span className="prop">
|
||||||
|
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
|
||||||
|
{ format && <span className="prop-format">(${format})</span>}
|
||||||
|
{
|
||||||
|
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
|
||||||
|
<br />{ key }: { String(v) }</span>)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!description ? null :
|
||||||
|
<Markdown source={ description } />
|
||||||
|
}
|
||||||
|
{
|
||||||
|
xml && xml.size ? (<span><br /><span style={ propStyle }>xml:</span>
|
||||||
|
{
|
||||||
|
xml.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }><br/> {key}: { String(v) }</span>).toArray()
|
||||||
|
}
|
||||||
|
</span>): null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
enumArray && <EnumModel value={ enumArray } getComponent={ getComponent } />
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,17 +6,45 @@ import ApisPreset from "core/presets/apis"
|
|||||||
import * as AllPlugins from "core/plugins/all"
|
import * as AllPlugins from "core/plugins/all"
|
||||||
import { parseSeach, filterConfigs } from "core/utils"
|
import { parseSeach, filterConfigs } from "core/utils"
|
||||||
|
|
||||||
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
|
const CONFIGS = [
|
||||||
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
|
"url",
|
||||||
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]
|
"urls",
|
||||||
|
"urls.primaryName",
|
||||||
|
"spec",
|
||||||
|
"validatorUrl",
|
||||||
|
"onComplete",
|
||||||
|
"onFailure",
|
||||||
|
"authorizations",
|
||||||
|
"docExpansion",
|
||||||
|
"tagsSorter",
|
||||||
|
"maxDisplayedTags",
|
||||||
|
"filter",
|
||||||
|
"operationsSorter",
|
||||||
|
"supportedSubmitMethods",
|
||||||
|
"dom_id",
|
||||||
|
"defaultModelRendering",
|
||||||
|
"oauth2RedirectUrl",
|
||||||
|
"showRequestHeaders",
|
||||||
|
"custom",
|
||||||
|
"modelPropertyMacro",
|
||||||
|
"parameterMacro",
|
||||||
|
"displayOperationId",
|
||||||
|
"displayRequestDuration",
|
||||||
|
]
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
|
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION, HOSTNAME, BUILD_TIME } = buildInfo
|
||||||
|
|
||||||
module.exports = function SwaggerUI(opts) {
|
module.exports = function SwaggerUI(opts) {
|
||||||
|
|
||||||
win.versions = win.versions || {}
|
win.versions = win.versions || {}
|
||||||
win.versions.swaggerUi = `${PACKAGE_VERSION}/${GIT_COMMIT || "unknown"}${GIT_DIRTY ? "-dirty" : ""}`
|
win.versions.swaggerUi = {
|
||||||
|
version: PACKAGE_VERSION,
|
||||||
|
gitRevision: GIT_COMMIT,
|
||||||
|
gitDirty: GIT_DIRTY,
|
||||||
|
buildTimestamp: BUILD_TIME,
|
||||||
|
machine: HOSTNAME
|
||||||
|
}
|
||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
// Some general settings, that we floated to the top
|
// Some general settings, that we floated to the top
|
||||||
@@ -26,6 +54,8 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
urls: null,
|
urls: null,
|
||||||
layout: "BaseLayout",
|
layout: "BaseLayout",
|
||||||
docExpansion: "list",
|
docExpansion: "list",
|
||||||
|
maxDisplayedTags: null,
|
||||||
|
filter: null,
|
||||||
validatorUrl: "https://online.swagger.io/validator",
|
validatorUrl: "https://online.swagger.io/validator",
|
||||||
configs: {},
|
configs: {},
|
||||||
custom: {},
|
custom: {},
|
||||||
@@ -50,7 +80,9 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
store: { },
|
store: { },
|
||||||
}
|
}
|
||||||
|
|
||||||
const constructorConfig = deepExtend({}, defaults, opts)
|
let queryConfig = parseSeach()
|
||||||
|
|
||||||
|
const constructorConfig = deepExtend({}, defaults, opts, queryConfig)
|
||||||
|
|
||||||
const storeConfigs = deepExtend({}, constructorConfig.store, {
|
const storeConfigs = deepExtend({}, constructorConfig.store, {
|
||||||
system: {
|
system: {
|
||||||
@@ -59,7 +91,8 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
plugins: constructorConfig.presets,
|
plugins: constructorConfig.presets,
|
||||||
state: {
|
state: {
|
||||||
layout: {
|
layout: {
|
||||||
layout: constructorConfig.layout
|
layout: constructorConfig.layout,
|
||||||
|
filter: constructorConfig.filter
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
spec: "",
|
spec: "",
|
||||||
@@ -80,7 +113,6 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
store.register([constructorConfig.plugins, inlinePlugin])
|
store.register([constructorConfig.plugins, inlinePlugin])
|
||||||
|
|
||||||
var system = store.getSystem()
|
var system = store.getSystem()
|
||||||
let queryConfig = parseSeach()
|
|
||||||
|
|
||||||
system.initOAuth = system.authActions.configureAuth
|
system.initOAuth = system.authActions.configureAuth
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { normalizeArray } from "core/utils"
|
import { normalizeArray } from "core/utils"
|
||||||
|
|
||||||
export const UPDATE_LAYOUT = "layout_update_layout"
|
export const UPDATE_LAYOUT = "layout_update_layout"
|
||||||
|
export const UPDATE_FILTER = "layout_update_filter"
|
||||||
export const UPDATE_MODE = "layout_update_mode"
|
export const UPDATE_MODE = "layout_update_mode"
|
||||||
export const SHOW = "layout_show"
|
export const SHOW = "layout_show"
|
||||||
|
|
||||||
@@ -13,6 +14,13 @@ export function updateLayout(layout) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateFilter(filter) {
|
||||||
|
return {
|
||||||
|
type: UPDATE_FILTER,
|
||||||
|
payload: filter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function show(thing, shown=true) {
|
export function show(thing, shown=true) {
|
||||||
thing = normalizeArray(thing)
|
thing = normalizeArray(thing)
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
UPDATE_LAYOUT,
|
UPDATE_LAYOUT,
|
||||||
|
UPDATE_FILTER,
|
||||||
UPDATE_MODE,
|
UPDATE_MODE,
|
||||||
SHOW
|
SHOW
|
||||||
} from "./actions"
|
} from "./actions"
|
||||||
@@ -8,6 +9,8 @@ export default {
|
|||||||
|
|
||||||
[UPDATE_LAYOUT]: (state, action) => state.set("layout", action.payload),
|
[UPDATE_LAYOUT]: (state, action) => state.set("layout", action.payload),
|
||||||
|
|
||||||
|
[UPDATE_FILTER]: (state, action) => state.set("filter", action.payload),
|
||||||
|
|
||||||
[SHOW]: (state, action) => {
|
[SHOW]: (state, action) => {
|
||||||
let thing = action.payload.thing
|
let thing = action.payload.thing
|
||||||
let shown = action.payload.shown
|
let shown = action.payload.shown
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ const state = state => state
|
|||||||
|
|
||||||
export const current = state => state.get("layout")
|
export const current = state => state.get("layout")
|
||||||
|
|
||||||
|
export const currentFilter = state => state.get("filter")
|
||||||
|
|
||||||
export const isShown = (state, thing, def) => {
|
export const isShown = (state, thing, def) => {
|
||||||
thing = normalizeArray(thing)
|
thing = normalizeArray(thing)
|
||||||
return Boolean(state.getIn(["shown", ...thing], def))
|
return Boolean(state.getIn(["shown", ...thing], def))
|
||||||
|
|||||||
@@ -200,15 +200,22 @@ export const operationsWithTags = createSelector(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const taggedOperations = ( state ) =>( { getConfigs } ) => {
|
export const taggedOperations = (state) => ({ getConfigs }) => {
|
||||||
let { operationsSorter }= getConfigs()
|
let { tagsSorter, operationsSorter } = getConfigs()
|
||||||
|
return operationsWithTags(state)
|
||||||
|
.sortBy(
|
||||||
|
(val, key) => key, // get the name of the tag to be passed to the sorter
|
||||||
|
(tagA, tagB) => {
|
||||||
|
let sortFn = (typeof tagsSorter === "function" ? tagsSorter : sorters.tagsSorter[ tagsSorter ])
|
||||||
|
return (!sortFn ? null : sortFn(tagA, tagB))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.map((ops, tag) => {
|
||||||
|
let sortFn = (typeof operationsSorter === "function" ? operationsSorter : sorters.operationsSorter[ operationsSorter ])
|
||||||
|
let operations = (!sortFn ? ops : ops.sort(sortFn))
|
||||||
|
|
||||||
return operationsWithTags(state).map((ops, tag) => {
|
return Map({ tagDetails: tagDetails(state, tag), operations: operations })
|
||||||
let sortFn = typeof operationsSorter === "function" ? operationsSorter
|
})
|
||||||
: sorters.operationsSorter[operationsSorter]
|
|
||||||
let operations = !sortFn ? ops : ops.sort(sortFn)
|
|
||||||
|
|
||||||
return Map({tagDetails: tagDetails(state, tag), operations: operations})})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const responses = createSelector(
|
export const responses = createSelector(
|
||||||
@@ -277,12 +284,13 @@ export function parametersIncludeType(parameters, typeValue="") {
|
|||||||
export function contentTypeValues(state, pathMethod) {
|
export function contentTypeValues(state, pathMethod) {
|
||||||
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
|
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
|
||||||
const parameters = op.get("parameters") || new List()
|
const parameters = op.get("parameters") || new List()
|
||||||
const requestContentType = (
|
|
||||||
parametersIncludeType(parameters, "file") ? "multipart/form-data"
|
|
||||||
: parametersIncludeIn(parameters, "formData") ? "application/x-www-form-urlencoded"
|
|
||||||
: op.get("consumes_value")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
const requestContentType = (
|
||||||
|
op.get("consumes_value") ? op.get("consumes_value")
|
||||||
|
: parametersIncludeType(parameters, "file") ? "multipart/form-data"
|
||||||
|
: parametersIncludeType(parameters, "formData") ? "application/x-www-form-urlencoded"
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
|
||||||
return fromJS({
|
return fromJS({
|
||||||
requestContentType,
|
requestContentType,
|
||||||
|
|||||||
@@ -41,9 +41,15 @@ import Footer from "core/components/footer"
|
|||||||
import ParamBody from "core/components/param-body"
|
import ParamBody from "core/components/param-body"
|
||||||
import Curl from "core/components/curl"
|
import Curl from "core/components/curl"
|
||||||
import Schemes from "core/components/schemes"
|
import Schemes from "core/components/schemes"
|
||||||
|
import ModelCollapse from "core/components/model-collapse"
|
||||||
import ModelExample from "core/components/model-example"
|
import ModelExample from "core/components/model-example"
|
||||||
|
import ModelWrapper from "core/components/model-wrapper"
|
||||||
import Model from "core/components/model"
|
import Model from "core/components/model"
|
||||||
import Models from "core/components/models"
|
import Models from "core/components/models"
|
||||||
|
import EnumModel from "core/components/enum-model"
|
||||||
|
import ObjectModel from "core/components/object-model"
|
||||||
|
import ArrayModel from "core/components/array-model"
|
||||||
|
import PrimitiveModel from "core/components/primitive-model"
|
||||||
import TryItOutButton from "core/components/try-it-out-button"
|
import TryItOutButton from "core/components/try-it-out-button"
|
||||||
|
|
||||||
import Markdown from "core/components/providers/markdown"
|
import Markdown from "core/components/providers/markdown"
|
||||||
@@ -88,8 +94,14 @@ export default function() {
|
|||||||
curl: Curl,
|
curl: Curl,
|
||||||
schemes: Schemes,
|
schemes: Schemes,
|
||||||
modelExample: ModelExample,
|
modelExample: ModelExample,
|
||||||
model: Model,
|
ModelWrapper,
|
||||||
models: Models,
|
ModelCollapse,
|
||||||
|
Model,
|
||||||
|
Models,
|
||||||
|
EnumModel,
|
||||||
|
ObjectModel,
|
||||||
|
ArrayModel,
|
||||||
|
PrimitiveModel,
|
||||||
TryItOutButton,
|
TryItOutButton,
|
||||||
Markdown,
|
Markdown,
|
||||||
BaseLayout
|
BaseLayout
|
||||||
|
|||||||
@@ -578,6 +578,9 @@ export const sorters = {
|
|||||||
operationsSorter: {
|
operationsSorter: {
|
||||||
alpha: (a, b) => a.get("path").localeCompare(b.get("path")),
|
alpha: (a, b) => a.get("path").localeCompare(b.get("path")),
|
||||||
method: (a, b) => a.get("method").localeCompare(b.get("method"))
|
method: (a, b) => a.get("method").localeCompare(b.get("method"))
|
||||||
|
},
|
||||||
|
tagsSorter: {
|
||||||
|
alpha: (a, b) => a.localeCompare(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import Logo from "./logo_small.png"
|
|||||||
|
|
||||||
export default class Topbar extends React.Component {
|
export default class Topbar extends React.Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
layoutActions: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context)
|
super(props, context)
|
||||||
this.state = { url: props.specSelectors.url(), selectedIndex: 0 }
|
this.state = { url: props.specSelectors.url(), selectedIndex: 0 }
|
||||||
@@ -80,6 +84,11 @@ export default class Topbar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFilterChange =(e) => {
|
||||||
|
let {target: {value}} = e
|
||||||
|
this.props.layoutActions.updateFilter(value)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { getComponent, specSelectors, getConfigs } = this.props
|
let { getComponent, specSelectors, getConfigs } = this.props
|
||||||
const Button = getComponent("Button")
|
const Button = getComponent("Button")
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class StandaloneLayout extends React.Component {
|
|||||||
return (
|
return (
|
||||||
|
|
||||||
<Container className='swagger-ui'>
|
<Container className='swagger-ui'>
|
||||||
{ Topbar ? <Topbar/> : null }
|
{ Topbar ? <Topbar /> : null }
|
||||||
{ loadingStatus === "loading" &&
|
{ loadingStatus === "loading" &&
|
||||||
<div className="info">
|
<div className="info">
|
||||||
<h4 className="title">Loading...</h4>
|
<h4 className="title">Loading...</h4>
|
||||||
@@ -45,7 +45,7 @@ export default class StandaloneLayout extends React.Component {
|
|||||||
<h4 className="title">Failed to load config.</h4>
|
<h4 className="title">Failed to load config.</h4>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{ !loadingStatus || loadingStatus === "success" && <BaseLayout/> }
|
{ !loadingStatus || loadingStatus === "success" && <BaseLayout /> }
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<OnlineValidatorBadge />
|
<OnlineValidatorBadge />
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ body
|
|||||||
.opblock-tag
|
.opblock-tag
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
padding: 10px 20px 10px 10px;
|
padding: 10px 20px 10px 10px;
|
||||||
|
|
||||||
@@ -53,8 +54,6 @@ body
|
|||||||
|
|
||||||
border-bottom: 1px solid rgba(#3b4151, .3);
|
border-bottom: 1px solid rgba(#3b4151, .3);
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
background: rgba(#000,.02);
|
background: rgba(#000,.02);
|
||||||
@@ -106,9 +105,10 @@ body
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
|
||||||
flex: 1;
|
|
||||||
@include text_body();
|
@include text_body();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,6 +134,8 @@ body
|
|||||||
transition: all .5s;
|
transition: all .5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.opblock
|
.opblock
|
||||||
{
|
{
|
||||||
margin: 0 0 15px 0;
|
margin: 0 0 15px 0;
|
||||||
@@ -154,24 +156,23 @@ body
|
|||||||
.opblock-section-header
|
.opblock-section-header
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
padding: 8px 20px;
|
padding: 8px 20px;
|
||||||
|
|
||||||
background: rgba(#fff,.8);
|
background: rgba(#fff,.8);
|
||||||
box-shadow: 0 1px 2px rgba(#000,.1);
|
box-shadow: 0 1px 2px rgba(#000,.1);
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
label
|
label
|
||||||
{
|
{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
|
|
||||||
span
|
span
|
||||||
@@ -184,9 +185,10 @@ body
|
|||||||
{
|
{
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
flex: 1;
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,11 +217,11 @@ body
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
|
||||||
@include text_code();
|
@include text_code();
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.view-line-link
|
.view-line-link
|
||||||
{
|
{
|
||||||
@@ -258,18 +260,18 @@ body
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
@include text_body();
|
@include text_body();
|
||||||
}
|
}
|
||||||
|
|
||||||
.opblock-summary
|
.opblock-summary
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.opblock-post
|
&.opblock-post
|
||||||
@@ -316,12 +318,24 @@ body
|
|||||||
|
|
||||||
.opblock-schemes
|
.opblock-schemes
|
||||||
{
|
{
|
||||||
padding: 8px 20px;
|
padding: 8px 20px;
|
||||||
|
|
||||||
.schemes-title
|
.schemes-title
|
||||||
{
|
{
|
||||||
padding: 0 10px 0 0;
|
padding: 0 10px 0 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter
|
||||||
|
{
|
||||||
|
.operation-filter-input
|
||||||
|
{
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 10px 10px;
|
||||||
|
|
||||||
|
border: 2px solid #d8dde7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,13 +512,11 @@ body
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
white-space: pre-wrap;
|
|
||||||
|
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #41444e;
|
background: #41444e;
|
||||||
@@ -533,10 +545,9 @@ body
|
|||||||
.schemes
|
.schemes
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> label
|
> label
|
||||||
{
|
{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -624,3 +635,12 @@ body
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
section
|
||||||
|
{
|
||||||
|
h3
|
||||||
|
{
|
||||||
|
@include text_headline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
border: 2px solid #547f00;
|
border: 2px solid #547f00;
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ describe("spec plugin - selectors", function(){
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("contentTypeValues", function(){
|
describe("contentTypeValues", function(){
|
||||||
|
|
||||||
it("should return { requestContentType, responseContentType } from an operation", function(){
|
it("should return { requestContentType, responseContentType } from an operation", function(){
|
||||||
// Given
|
// Given
|
||||||
let state = fromJS({
|
let state = fromJS({
|
||||||
@@ -77,6 +76,73 @@ describe("spec plugin - selectors", function(){
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should prioritize consumes value first from an operation", function(){
|
||||||
|
// Given
|
||||||
|
let state = fromJS({
|
||||||
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"consumes_value": "one",
|
||||||
|
"parameters": [{
|
||||||
|
"type": "file"
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
let contentTypes = contentTypeValues(state, [ "/one", "get" ])
|
||||||
|
// Then
|
||||||
|
expect(contentTypes.toJS().requestContentType).toEqual("one")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fallback to multipart/form-data if there is no consumes value but there is a file parameter", function(){
|
||||||
|
// Given
|
||||||
|
let state = fromJS({
|
||||||
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"parameters": [{
|
||||||
|
"type": "file"
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
let contentTypes = contentTypeValues(state, [ "/one", "get" ])
|
||||||
|
// Then
|
||||||
|
expect(contentTypes.toJS().requestContentType).toEqual("multipart/form-data")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fallback to application/x-www-form-urlencoded if there is no consumes value, no file parameter, but there is a formData parameter", function(){
|
||||||
|
// Given
|
||||||
|
let state = fromJS({
|
||||||
|
resolved: {
|
||||||
|
paths: {
|
||||||
|
"/one": {
|
||||||
|
get: {
|
||||||
|
"parameters": [{
|
||||||
|
"type": "formData"
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
let contentTypes = contentTypeValues(state, [ "/one", "get" ])
|
||||||
|
// Then
|
||||||
|
expect(contentTypes.toJS().requestContentType).toEqual("application/x-www-form-urlencoded")
|
||||||
|
})
|
||||||
|
|
||||||
it("should be ok, if no operation found", function(){
|
it("should be ok, if no operation found", function(){
|
||||||
// Given
|
// Given
|
||||||
let state = fromJS({ })
|
let state = fromJS({ })
|
||||||
|
|||||||
Reference in New Issue
Block a user