Compare commits

...
5 Commits
Author SHA1 Message Date
kyle 54153dd929 remove docker login email param (#4283) 2018-03-02 22:22:39 -08:00
kyle 83232dc2d8 v3.12.0 (#4282)
* Use `parameterWithMeta` to get parameter data in <ParameterRow>

* Prefer specPath when fetching resolved subtrees in OperationContainer

* Add test for OAS3 callback rendering

* Remove debugger statement

* Pass base resolution URL directly to Swagger-Client subtree resolver

* Remove accidental comment

* Migrate additional options

* Don't default to empty Map when getting subtree

* fix(validateParam): check for ImList type before using count method

* Use `replaceState` to update `urls.primaryName`

This gives us the stateful URL we want, without:
(a) refreshing the page on update
(b) creating a long, useless history for the user
(c) implying that browser history is two-way bound
    to Swagger-UI (it isn't, we don't have a router)

* Add `fn.opsFilter` docs and internal API versioning note

* restrict `x-example` functionality to Swagger 2.0

* polish Authorize + Close buttons

* add tachyons; use it for padding the new Reset button

* v3.12.0

* rebuild dist
2018-03-02 21:13:00 -08:00
russell ad43965d16 improve: add button to reset example when user modifies request body (#4185)
* Add a button to reset example when user modifys request body

* lint fixes

* Revert "lint fixes"

This reverts commit 5395005ea7.

* reapply lint fixes
2018-03-02 18:46:47 -08:00
Charles Capps 861cc65cff improve: add "Close" button to OAuth dialog, rename "Done" button elsewhere (#4212)
* Rename "Done" button to "Close", and add "Close" button OAuth dialog
* move Close button to the right
2018-03-02 18:40:54 -08:00
Davide Zipeto 4900b11079 feature: read the x-example field and use them as values (#3538)
* Read the x-example field and use them as values
Allow to show the value defined in the "x-example" field when pressing try-out. The "default" value will have the precedence over the x-example

* Use `parameterWithMeta` to get parameter data in <ParameterRow>
* Prefer specPath when fetching resolved subtrees in OperationContainer
* Add test for OAS3 callback rendering
* Remove debugger statement
* Pass base resolution URL directly to Swagger-Client subtree resolver
* Remove accidental comment
* Migrate additional options
* Don't default to empty Map when getting subtree
* make "default" and "x-example" mutually exclusive
"x-example" wins when both are present
* limit "x-example" to non-body parameters
2018-03-02 18:31:08 -08:00
20 changed files with 135 additions and 48 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ deploy:
node: '6.9' node: '6.9'
after_success: after_success:
- if [ $DOCKER_HUB_USERNAME ]; then - if [ $DOCKER_HUB_USERNAME ]; then
docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD; docker login --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD;
if [ ! -z "$TRAVIS_TAG" ]; then if [ ! -z "$TRAVIS_TAG" ]; then
DOCKER_IMAGE_TAG=$TRAVIS_TAG; DOCKER_IMAGE_TAG=$TRAVIS_TAG;
+1 -1
View File
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 5 revisions since initial creation in 20
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
------------------ | ------------ | -------------------------- | ----- ------------------ | ------------ | -------------------------- | -----
3.11.0 | 2018-02-09 | 2.0, 3.0 | [tag v3.11.0](https://github.com/swagger-api/swagger-ui/tree/v3.11.0) 3.12.0 | 2018-03-02 | 2.0, 3.0 | [tag v3.12.0](https://github.com/swagger-api/swagger-ui/tree/v3.12.0)
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21) 3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10) 2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5) 2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
+14 -20
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+43
View File
@@ -0,0 +1,43 @@
# Plug points
Swagger-UI exposes most of its internal logic through the plugin system.
Often, it is beneficial to override the core internals to achieve custom behavior.
### Note: Semantic Versioning
Swagger-UI's internal APIs are _not_ part of our public contract, which means that they can change without the major version changing.
If your custom plugins wrap, extend, override, or consume any internal core APIs, we recommend specifying a specific minor version of Swagger-UI to use in your application, because they will _not_ change between patch versions.
If you're installing Swagger-UI via NPM, for example, you can do this by using a tilde:
```js
{
"dependencies": {
"swagger-ui": "~3.11.0"
}
}
```
### `fn.opsFilter`
When using the `filter` option, tag names will be filtered by the user-provided value. If you'd like to customize this behavior, you can override the default `opsFilter` function.
For example, you can implement a multiple-phrase filter:
```js
const MultiplePhraseFilterPlugin = function() {
return {
fn: {
opsFilter: (taggedOps, phrase) => {
const phrases = phrase.split(", ")
return taggedOps.filter((val, key) => {
return phrases.some(item => key.indexOf(item) > -1)
})
}
}
}
}
```
+16
View File
@@ -2,6 +2,22 @@
A plugin is a function that returns an object - more specifically, the object may contain functions and components that augment and modify Swagger-UI's functionality. A plugin is a function that returns an object - more specifically, the object may contain functions and components that augment and modify Swagger-UI's functionality.
### Note: Semantic Versioning
Swagger-UI's internal APIs are _not_ part of our public contract, which means that they can change without the major version changing.
If your custom plugins wrap, extend, override, or consume any internal core APIs, we recommend specifying a specific minor version of Swagger-UI to use in your application, because they will _not_ change between patch versions.
If you're installing Swagger-UI via NPM, for example, you can do this by using a tilde:
```js
{
"dependencies": {
"swagger-ui": "~3.11.0"
}
}
```
### Format ### Format
A plugin return value may contain any of these keys, where `stateKey` is a name for a piece of state: A plugin return value may contain any of these keys, where `stateKey` is a name for a piece of state:
+3 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "swagger-ui", "name": "swagger-ui",
"version": "3.11.0", "version": "3.12.0",
"main": "dist/swagger-ui.js", "main": "dist/swagger-ui.js",
"repository": "git@github.com:swagger-api/swagger-ui.git", "repository": "git@github.com:swagger-api/swagger-ui.git",
"contributors": [ "contributors": [
@@ -83,7 +83,7 @@
"scroll-to-element": "^2.0.0", "scroll-to-element": "^2.0.0",
"serialize-error": "2.0.0", "serialize-error": "2.0.0",
"shallowequal": "0.2.2", "shallowequal": "0.2.2",
"swagger-client": "^3.5.0", "swagger-client": "^3.5.1",
"url-parse": "^1.1.8", "url-parse": "^1.1.8",
"whatwg-fetch": "0.11.1", "whatwg-fetch": "0.11.1",
"worker-loader": "^0.7.1", "worker-loader": "^0.7.1",
@@ -144,6 +144,7 @@
"standard": "^10.0.2", "standard": "^10.0.2",
"standard-loader": "^6.0.1", "standard-loader": "^6.0.1",
"style-loader": "0.18.2", "style-loader": "0.18.2",
"tachyons-sass": "^4.9.2",
"url-loader": "0.5.9", "url-loader": "0.5.9",
"webpack": "^2.6.1", "webpack": "^2.6.1",
"webpack-bundle-size-analyzer": "^2.5.0" "webpack-bundle-size-analyzer": "^2.5.0"
+1 -1
View File
@@ -81,11 +81,11 @@ export default class Auths extends React.Component {
}).toArray() }).toArray()
} }
<div className="auth-btn-wrapper"> <div className="auth-btn-wrapper">
<Button className="btn modal-btn auth btn-done" onClick={ this.close }>Done</Button>
{ {
nonOauthDefinitions.size === authorizedAuth.size ? <Button className="btn modal-btn auth" onClick={ this.logoutClick }>Logout</Button> nonOauthDefinitions.size === authorizedAuth.size ? <Button className="btn modal-btn auth" onClick={ this.logoutClick }>Logout</Button>
: <Button type="submit" className="btn modal-btn auth authorize">Authorize</Button> : <Button type="submit" className="btn modal-btn auth authorize">Authorize</Button>
} }
<Button className="btn modal-btn auth btn-done" onClick={ this.close }>Close</Button>
</div> </div>
</form> </form>
} }
+8
View File
@@ -39,6 +39,13 @@ export default class Oauth2 extends React.Component {
} }
} }
close = (e) => {
e.preventDefault()
let { authActions } = this.props
authActions.showDefinitions(false)
}
authorize =() => { authorize =() => {
let { authActions, errActions, getConfigs, authSelectors } = this.props let { authActions, errActions, getConfigs, authSelectors } = this.props
let configs = getConfigs() let configs = getConfigs()
@@ -231,6 +238,7 @@ export default class Oauth2 extends React.Component {
: <Button className="btn modal-btn auth authorize" onClick={ this.authorize }>Authorize</Button> : <Button className="btn modal-btn auth authorize" onClick={ this.authorize }>Authorize</Button>
) )
} }
<Button className="btn modal-btn auth btn-done" onClick={ this.close }>Close</Button>
</div> </div>
</div> </div>
+9 -2
View File
@@ -24,11 +24,18 @@ export default class ParameterRow extends Component {
let { specSelectors, pathMethod, param } = props let { specSelectors, pathMethod, param } = props
let defaultValue = param.get("default") let defaultValue = param.get("default")
let xExampleValue = param.get("x-example")
let parameter = specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in")) let parameter = specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in"))
let value = parameter ? parameter.get("value") : "" let value = parameter ? parameter.get("value") : ""
if ( defaultValue !== undefined && value === undefined ) {
this.onChangeWrapper(defaultValue) if( param.get("in") !== "body" ) {
if ( xExampleValue !== undefined && value === undefined && specSelectors.isSwagger2() ) {
this.onChangeWrapper(xExampleValue)
} else if ( defaultValue !== undefined && value === undefined ) {
this.onChangeWrapper(defaultValue)
}
} }
} }
componentWillReceiveProps(props) { componentWillReceiveProps(props) {
@@ -27,6 +27,7 @@ export default class RequestBodyEditor extends PureComponent {
this.state = { this.state = {
isEditBox: false, isEditBox: false,
userDidModify: false,
value: "" value: ""
} }
} }
@@ -59,6 +60,11 @@ export default class RequestBodyEditor extends PureComponent {
this.onChange(this.sample(explicitMediaType)) this.onChange(this.sample(explicitMediaType))
} }
resetValueToSample = (explicitMediaType) => {
this.setState({ userDidModify: false })
this.setValueToSample(explicitMediaType)
}
sample = (explicitMediaType) => { sample = (explicitMediaType) => {
let { requestBody, mediaType } = this.props let { requestBody, mediaType } = this.props
let schema = requestBody.getIn(["content", explicitMediaType || mediaType, "schema"]).toJS() let schema = requestBody.getIn(["content", explicitMediaType || mediaType, "schema"]).toJS()
@@ -78,6 +84,7 @@ export default class RequestBodyEditor extends PureComponent {
const isJson = /json/i.test(mediaType) const isJson = /json/i.test(mediaType)
const inputValue = isJson ? e.target.value.trim() : e.target.value const inputValue = isJson ? e.target.value.trim() : e.target.value
this.setState({ userDidModify: true })
this.onChange(inputValue) this.onChange(inputValue)
} }
@@ -87,13 +94,14 @@ export default class RequestBodyEditor extends PureComponent {
let { let {
isExecute, isExecute,
getComponent, getComponent,
mediaType,
} = this.props } = this.props
const Button = getComponent("Button") const Button = getComponent("Button")
const TextArea = getComponent("TextArea") const TextArea = getComponent("TextArea")
const HighlightCode = getComponent("highlightCode") const HighlightCode = getComponent("highlightCode")
let { value, isEditBox } = this.state let { value, isEditBox, userDidModify } = this.state
return ( return (
<div className="body-param"> <div className="body-param">
@@ -104,14 +112,18 @@ export default class RequestBodyEditor extends PureComponent {
value={ value }/>) value={ value }/>)
} }
<div className="body-param-options"> <div className="body-param-options">
{ <div className="body-param-edit">
!isExecute ? null {
: <div className="body-param-edit"> !isExecute ? null
<Button className={isEditBox ? "btn cancel body-param__example-edit" : "btn edit body-param__example-edit"} : <Button className={isEditBox ? "btn cancel body-param__example-edit" : "btn edit body-param__example-edit"}
onClick={this.toggleIsEditBox}>{ isEditBox ? "Cancel" : "Edit"} onClick={this.toggleIsEditBox}>{ isEditBox ? "Cancel" : "Edit"}
</Button> </Button>
</div>
} }
{ userDidModify &&
<Button className="btn ml3" onClick={() => { this.resetValueToSample(mediaType) }}>Reset</Button>
}
</div>
</div> </div>
</div> </div>
+2 -2
View File
@@ -350,7 +350,7 @@ export function extractFileNameFromContentDispositionHeader(value){
if (responseFilename !== null && responseFilename.length > 1) { if (responseFilename !== null && responseFilename.length > 1) {
return responseFilename[1] return responseFilename[1]
} }
return null return null
} }
// PascalCase, aka UpperCamelCase // PascalCase, aka UpperCamelCase
@@ -559,7 +559,7 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
} else if ( type === "array" ) { } else if ( type === "array" ) {
let itemType let itemType
if ( !value.count() ) { return errors } if ( !listCheck || !value.count() ) { return errors }
itemType = paramDetails.getIn(["items", "type"]) itemType = paramDetails.getIn(["items", "type"])
+4 -1
View File
@@ -45,7 +45,10 @@ export default class Topbar extends React.Component {
setSearch = (spec) => { setSearch = (spec) => {
let search = parseSearch() let search = parseSearch()
search["urls.primaryName"] = spec.name search["urls.primaryName"] = spec.name
window.location.search = serializeSearch(search) const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}`
if(window && window.history && window.history.pushState) {
window.history.replaceState(null, "", `${newUrl}?${serializeSearch(search)}`)
}
} }
setSelectedUrl = (selectedUrl) => { setSelectedUrl = (selectedUrl) => {
+1
View File
@@ -21,6 +21,7 @@
.authorize .authorize
{ {
padding-right: 20px; padding-right: 20px;
margin-right: 10px;
} }
} }
+1
View File
@@ -1,5 +1,6 @@
.swagger-ui .swagger-ui
{ {
@import '~tachyons-sass/tachyons.scss';
@import 'mixins'; @import 'mixins';
@import 'variables'; @import 'variables';
@import 'colors'; @import 'colors';