Skip to content

Commit d8ba716

Browse files
authored
Merge branch 'master' into feature/apisSorter
2 parents e6c8eb3 + be7b244 commit d8ba716

File tree

13 files changed

+230
-70
lines changed

13 files changed

+230
-70
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ modelPropertyMacro | MUST be a function. Function to set default values to each
145145
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'.
146146
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
147147
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
148+
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
149+
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.
148150

149151
### Plugins
150152

make-webpack-config.js

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,42 @@
1-
var path = require('path')
1+
var path = require("path")
22

3-
var webpack = require('webpack')
4-
var ExtractTextPlugin = require('extract-text-webpack-plugin')
5-
var deepExtend = require('deep-extend')
6-
const {gitDescribeSync} = require('git-describe');
3+
var webpack = require("webpack")
4+
var ExtractTextPlugin = require("extract-text-webpack-plugin")
5+
var deepExtend = require("deep-extend")
6+
const {gitDescribeSync} = require("git-describe")
7+
const os = require("os")
78

8-
var pkg = require('./package.json')
9+
var pkg = require("./package.json")
910

1011
let gitInfo
1112

1213
try {
1314
gitInfo = gitDescribeSync(__dirname)
1415
} catch(e) {
1516
gitInfo = {
16-
hash: 'noGit',
17+
hash: "noGit",
1718
dirty: false
1819
}
1920
}
2021

2122
var commonRules = [
2223
{ test: /\.(js(x)?)(\?.*)?$/,
2324
use: [{
24-
loader: 'babel-loader',
25+
loader: "babel-loader",
2526
options: {
2627
retainLines: true
2728
}
2829
}],
29-
include: [ path.join(__dirname, 'src') ]
30+
include: [ path.join(__dirname, "src") ]
3031
},
3132
{ test: /\.(txt|yaml)(\?.*)?$/,
32-
loader: 'raw-loader' },
33+
loader: "raw-loader" },
3334
{ test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/,
34-
loader: 'url-loader?limit=10000' },
35+
loader: "url-loader?limit=10000" },
3536
{ test: /\.(woff|woff2)(\?.*)?$/,
36-
loader: 'url-loader?limit=100000' },
37+
loader: "url-loader?limit=100000" },
3738
{ test: /\.(ttf|eot)(\?.*)?$/,
38-
loader: 'file-loader' }
39+
loader: "file-loader" }
3940
]
4041

4142
module.exports = function(rules, options) {
@@ -54,7 +55,7 @@ module.exports = function(rules, options) {
5455

5556
if( specialOptions.separateStylesheets ) {
5657
plugins.push(new ExtractTextPlugin({
57-
filename: '[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''),
58+
filename: "[name].css" + (specialOptions.longTermCaching ? "?[contenthash]" : ""),
5859
allChunks: true
5960
}))
6061
}
@@ -78,61 +79,62 @@ module.exports = function(rules, options) {
7879

7980
plugins.push(
8081
new webpack.DefinePlugin({
81-
'process.env': {
82-
NODE_ENV: specialOptions.minimize ? JSON.stringify('production') : null,
83-
WEBPACK_INLINE_STYLES: !Boolean(specialOptions.separateStylesheets)
84-
82+
"process.env": {
83+
NODE_ENV: specialOptions.minimize ? JSON.stringify("production") : null,
84+
WEBPACK_INLINE_STYLES: !specialOptions.separateStylesheets
8585
},
86-
'buildInfo': JSON.stringify({
86+
"buildInfo": JSON.stringify({
8787
PACKAGE_VERSION: (pkg.version),
8888
GIT_COMMIT: gitInfo.hash,
89-
GIT_DIRTY: gitInfo.dirty
89+
GIT_DIRTY: gitInfo.dirty,
90+
HOSTNAME: os.hostname(),
91+
BUILD_TIME: new Date().toUTCString()
9092
})
9193
}))
9294

9395
delete options._special
9496

95-
var completeConfig = deepExtend({
97+
var completeConfig = deepExtend({
9698
entry: {},
9799

98100
output: {
99-
path: path.join(__dirname, 'dist'),
100-
publicPath: '/',
101-
filename: '[name].js',
102-
chunkFilename: '[name].js'
101+
path: path.join(__dirname, "dist"),
102+
publicPath: "/",
103+
filename: "[name].js",
104+
chunkFilename: "[name].js"
103105
},
104106

105-
target: 'web',
107+
target: "web",
106108

107109
// yaml-js has a reference to `fs`, this is a workaround
108110
node: {
109-
fs: 'empty'
111+
fs: "empty"
110112
},
111113

112114
module: {
113115
rules: commonRules.concat(rules),
114116
},
115117

116118
resolveLoader: {
117-
modules: [path.join(__dirname, 'node_modules')],
119+
modules: [path.join(__dirname, "node_modules")],
118120
},
119121

120122
externals: {
121-
'buffertools': true // json-react-schema/deeper depends on buffertools, which fails.
123+
"buffertools": true // json-react-schema/deeper depends on buffertools, which fails.
122124
},
123125

124126
resolve: {
125127
modules: [
126-
path.join(__dirname, './src'),
127-
'node_modules'
128+
path.join(__dirname, "./src"),
129+
"node_modules"
128130
],
129131
extensions: [".web.js", ".js", ".jsx", ".json", ".less"],
130132
alias: {
131133
base: "getbase/src/less/base",
132134
}
133135
},
134136

135-
devtool: specialOptions.sourcemaps ? 'cheap-module-source-map' : null,
137+
devtool: specialOptions.sourcemaps ? "cheap-module-source-map" : null,
136138

137139
plugins,
138140

src/core/components/operations.jsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,21 @@ export default class Operations extends React.Component {
3333
const Collapse = getComponent("Collapse")
3434

3535
let showSummary = layoutSelectors.showSummary()
36-
let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs()
36+
let { docExpansion, displayOperationId, displayRequestDuration, maxDisplayedTags } = getConfigs()
37+
38+
let filter = layoutSelectors.currentFilter()
39+
40+
if (filter) {
41+
if (filter !== true) {
42+
taggedOps = taggedOps.filter((tagObj, tag) => {
43+
return tag.indexOf(filter) !== -1
44+
})
45+
}
46+
}
47+
48+
if (maxDisplayedTags && !isNaN(maxDisplayedTags) && maxDisplayedTags >= 0) {
49+
taggedOps = taggedOps.slice(0, maxDisplayedTags)
50+
}
3751

3852
return (
3953
<div>

src/core/index.js

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,46 @@ import ApisPreset from "core/presets/apis"
66
import * as AllPlugins from "core/plugins/all"
77
import { parseSeach, filterConfigs } from "core/utils"
88

9-
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
10-
"tagsSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
11-
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]
9+
const CONFIGS = [
10+
"url",
11+
"urls",
12+
"urls.primaryName",
13+
"spec",
14+
"validatorUrl",
15+
"onComplete",
16+
"onFailure",
17+
"authorizations",
18+
"docExpansion",
19+
"tagsSorter",
20+
"apisSorter",
21+
"maxDisplayedTags",
22+
"filter",
23+
"operationsSorter",
24+
"supportedSubmitMethods",
25+
"dom_id",
26+
"defaultModelRendering",
27+
"oauth2RedirectUrl",
28+
"showRequestHeaders",
29+
"custom",
30+
"modelPropertyMacro",
31+
"parameterMacro",
32+
"displayOperationId",
33+
"displayRequestDuration",
34+
]
1235

1336
// eslint-disable-next-line no-undef
14-
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
37+
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION, HOSTNAME, BUILD_TIME } = buildInfo
1538

1639
module.exports = function SwaggerUI(opts) {
1740

1841
win.versions = win.versions || {}
19-
win.versions.swaggerUi = `${PACKAGE_VERSION}/${GIT_COMMIT || "unknown"}${GIT_DIRTY ? "-dirty" : ""}`
42+
win.versions.swaggerUi = {
43+
version: PACKAGE_VERSION,
44+
gitRevision: GIT_COMMIT,
45+
gitDirty: GIT_DIRTY,
46+
buildTimestamp: BUILD_TIME,
47+
machine: HOSTNAME
48+
}
2049

2150
const defaults = {
2251
// Some general settings, that we floated to the top
@@ -26,6 +55,8 @@ module.exports = function SwaggerUI(opts) {
2655
urls: null,
2756
layout: "BaseLayout",
2857
docExpansion: "list",
58+
maxDisplayedTags: null,
59+
filter: null,
2960
validatorUrl: "https://online.swagger.io/validator",
3061
configs: {},
3162
custom: {},
@@ -50,7 +81,9 @@ module.exports = function SwaggerUI(opts) {
5081
store: { },
5182
}
5283

53-
const constructorConfig = deepExtend({}, defaults, opts)
84+
let queryConfig = parseSeach()
85+
86+
const constructorConfig = deepExtend({}, defaults, opts, queryConfig)
5487

5588
const storeConfigs = deepExtend({}, constructorConfig.store, {
5689
system: {
@@ -59,7 +92,8 @@ module.exports = function SwaggerUI(opts) {
5992
plugins: constructorConfig.presets,
6093
state: {
6194
layout: {
62-
layout: constructorConfig.layout
95+
layout: constructorConfig.layout,
96+
filter: constructorConfig.filter
6397
},
6498
spec: {
6599
spec: "",
@@ -80,7 +114,6 @@ module.exports = function SwaggerUI(opts) {
80114
store.register([constructorConfig.plugins, inlinePlugin])
81115

82116
var system = store.getSystem()
83-
let queryConfig = parseSeach()
84117

85118
system.initOAuth = system.authActions.configureAuth
86119

src/core/plugins/layout/actions.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { normalizeArray } from "core/utils"
22

33
export const UPDATE_LAYOUT = "layout_update_layout"
4+
export const UPDATE_FILTER = "layout_update_filter"
45
export const UPDATE_MODE = "layout_update_mode"
56
export const SHOW = "layout_show"
67

@@ -13,6 +14,13 @@ export function updateLayout(layout) {
1314
}
1415
}
1516

17+
export function updateFilter(filter) {
18+
return {
19+
type: UPDATE_FILTER,
20+
payload: filter
21+
}
22+
}
23+
1624
export function show(thing, shown=true) {
1725
thing = normalizeArray(thing)
1826
return {

src/core/plugins/layout/reducers.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
UPDATE_LAYOUT,
3+
UPDATE_FILTER,
34
UPDATE_MODE,
45
SHOW
56
} from "./actions"
@@ -8,6 +9,8 @@ export default {
89

910
[UPDATE_LAYOUT]: (state, action) => state.set("layout", action.payload),
1011

12+
[UPDATE_FILTER]: (state, action) => state.set("filter", action.payload),
13+
1114
[SHOW]: (state, action) => {
1215
let thing = action.payload.thing
1316
let shown = action.payload.shown

src/core/plugins/layout/selectors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const state = state => state
55

66
export const current = state => state.get("layout")
77

8+
export const currentFilter = state => state.get("filter")
9+
810
export const isShown = (state, thing, def) => {
911
thing = normalizeArray(thing)
1012
return Boolean(state.getIn(["shown", ...thing], def))

src/core/plugins/spec/selectors.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,14 @@ export function parametersIncludeType(parameters, typeValue="") {
284284
export function contentTypeValues(state, pathMethod) {
285285
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
286286
const parameters = op.get("parameters") || new List()
287+
287288
const requestContentType = (
288-
parametersIncludeType(parameters, "file") ? "multipart/form-data"
289-
: parametersIncludeIn(parameters, "formData") ? "application/x-www-form-urlencoded"
290-
: op.get("consumes_value")
289+
op.get("consumes_value") ? op.get("consumes_value")
290+
: parametersIncludeType(parameters, "file") ? "multipart/form-data"
291+
: parametersIncludeType(parameters, "formData") ? "application/x-www-form-urlencoded"
292+
: undefined
291293
)
292294

293-
294295
return fromJS({
295296
requestContentType,
296297
responseContentType: op.get("produces_value")

src/plugins/topbar/topbar.jsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import Logo from "./logo_small.png"
66

77
export default class Topbar extends React.Component {
88

9+
static propTypes = {
10+
layoutSelectors: PropTypes.object.isRequired,
11+
layoutActions: PropTypes.object.isRequired
12+
}
13+
914
constructor(props, context) {
1015
super(props, context)
1116
this.state = { url: props.specSelectors.url(), selectedIndex: 0 }
@@ -80,13 +85,19 @@ export default class Topbar extends React.Component {
8085
}
8186
}
8287

88+
onFilterChange =(e) => {
89+
let {target: {value}} = e
90+
this.props.layoutActions.updateFilter(value)
91+
}
92+
8393
render() {
84-
let { getComponent, specSelectors, getConfigs } = this.props
94+
let { getComponent, specSelectors, getConfigs, layoutSelectors } = this.props
8595
const Button = getComponent("Button")
8696
const Link = getComponent("Link")
8797

8898
let isLoading = specSelectors.loadingStatus() === "loading"
8999
let isFailed = specSelectors.loadingStatus() === "failed"
100+
let filter = layoutSelectors.currentFilter()
90101

91102
let inputStyle = {}
92103
if(isFailed) inputStyle.color = "red"
@@ -124,6 +135,10 @@ export default class Topbar extends React.Component {
124135
<img height="30" width="30" src={ Logo } alt="Swagger UX"/>
125136
<span>swagger</span>
126137
</Link>
138+
{
139+
filter === null || filter === false ? null :
140+
<input className="operation-filter-input" placeholder="filter..." type="text" onChange={this.onFilterChange} value={filter === true ? "" : filter} disabled={isLoading} style={inputStyle} />
141+
}
127142
<form className="download-url-wrapper" onSubmit={formOnSubmit}>
128143
{control}
129144
</form>

src/standalone/layout.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default class StandaloneLayout extends React.Component {
2929
return (
3030

3131
<Container className='swagger-ui'>
32-
{ Topbar ? <Topbar/> : null }
32+
{ Topbar ? <Topbar /> : null }
3333
{ loadingStatus === "loading" &&
3434
<div className="info">
3535
<h4 className="title">Loading...</h4>
@@ -45,7 +45,7 @@ export default class StandaloneLayout extends React.Component {
4545
<h4 className="title">Failed to load config.</h4>
4646
</div>
4747
}
48-
{ !loadingStatus || loadingStatus === "success" && <BaseLayout/> }
48+
{ !loadingStatus || loadingStatus === "success" && <BaseLayout /> }
4949
<Row>
5050
<Col>
5151
<OnlineValidatorBadge />

0 commit comments

Comments
 (0)