Merge branch 'master' of github.com:swagger-api/swagger-ui into ft/oas3

This commit is contained in:
Kyle Shockey
2017-07-28 19:13:24 -07:00
75 changed files with 1196 additions and 1030 deletions

View File

@@ -73,7 +73,7 @@ export const authorizePassword = ( auth ) => ( { authActions } ) => {
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
let form = {
grant_type: "password",
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
scope: encodeURIComponent(auth.scopes.join(scopeSeparator))
}
let query = {}
let headers = {}

View File

@@ -0,0 +1 @@
See `docs/deep-linking.md`.

View File

@@ -0,0 +1,7 @@
export const setHash = (value) => {
if(value) {
return history.pushState(null, null, `#${value}`)
} else {
return window.location.hash = ""
}
}

View File

@@ -0,0 +1,18 @@
// import reducers from "./reducers"
// import * as actions from "./actions"
// import * as selectors from "./selectors"
import * as specWrapActions from "./spec-wrap-actions"
import * as layoutWrapActions from "./layout-wrap-actions"
export default function() {
return {
statePlugins: {
spec: {
wrapActions: specWrapActions
},
layout: {
wrapActions: layoutWrapActions
}
}
}
}

View File

@@ -0,0 +1,36 @@
import { setHash } from "./helpers"
export const show = (ori, { getConfigs }) => (...args) => {
ori(...args)
const isDeepLinkingEnabled = getConfigs().deepLinking
if(!isDeepLinkingEnabled || isDeepLinkingEnabled === "false") {
return
}
try {
let [thing, shown] = args
let [type] = thing
if(type === "operations-tag" || type === "operations") {
if(!shown) {
return setHash("/")
}
if(type === "operations") {
let [, tag, operationId] = thing
setHash(`/${tag}/${operationId}`)
}
if(type === "operations-tag") {
let [, tag] = thing
setHash(`/${tag}`)
}
}
} catch(e) {
// This functionality is not mission critical, so if something goes wrong
// we'll just move on
console.error(e)
}
}

View File

@@ -0,0 +1,51 @@
import scrollTo from "scroll-to-element"
const SCROLL_OFFSET = -5
let hasHashBeenParsed = false
export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args) => {
ori(...args)
const isDeepLinkingEnabled = getConfigs().deepLinking
if(!isDeepLinkingEnabled || isDeepLinkingEnabled === "false") {
return
}
if(window.location.hash && !hasHashBeenParsed ) {
let hash = window.location.hash.slice(1) // # is first character
if(hash[0] === "!") {
// Parse UI 2.x shebangs
hash = hash.slice(1)
}
if(hash[0] === "/") {
// "/pet/addPet" => "pet/addPet"
// makes the split result cleaner
// also handles forgotten leading slash
hash = hash.slice(1)
}
let [tag, operationId] = hash.split("/")
if(tag && operationId) {
// Pre-expand and scroll to the operation
layoutActions.show(["operations-tag", tag], true)
layoutActions.show(["operations", tag, operationId], true)
scrollTo(`#operations-${tag}-${operationId}`, {
offset: SCROLL_OFFSET
})
} else if(tag) {
// Pre-expand and scroll to the tag
layoutActions.show(["operations-tag", tag], true)
scrollTo(`#operations-tag-${tag}`, {
offset: SCROLL_OFFSET
})
}
}
hasHashBeenParsed = true
}

View File

@@ -1,6 +1,7 @@
import { normalizeArray } from "core/utils"
export const UPDATE_LAYOUT = "layout_update_layout"
export const UPDATE_FILTER = "layout_update_filter"
export const UPDATE_MODE = "layout_update_mode"
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) {
thing = normalizeArray(thing)
return {

View File

@@ -1,5 +1,6 @@
import {
UPDATE_LAYOUT,
UPDATE_FILTER,
UPDATE_MODE,
SHOW
} from "./actions"
@@ -8,6 +9,8 @@ export default {
[UPDATE_LAYOUT]: (state, action) => state.set("layout", action.payload),
[UPDATE_FILTER]: (state, action) => state.set("filter", action.payload),
[SHOW]: (state, action) => {
let thing = action.payload.thing
let shown = action.payload.shown

View File

@@ -5,6 +5,8 @@ const state = state => state
export const current = state => state.get("layout")
export const currentFilter = state => state.get("filter")
export const isShown = (state, thing, def) => {
thing = normalizeArray(thing)
return Boolean(state.getIn(["shown", ...thing], def))

View File

@@ -1,6 +1,6 @@
import { createSelector } from "reselect"
import { sorters } from "core/utils"
import { fromJS, Set, Map, List } from "immutable"
import { fromJS, Set, Map, OrderedMap, List } from "immutable"
const DEFAULT_TAG = "default"
@@ -194,25 +194,35 @@ export const tagDetails = (state, tag) => {
export const operationsWithTags = createSelector(
operationsWithRootInherited,
operations => {
tags,
(operations, tags) => {
return operations.reduce( (taggedMap, op) => {
let tags = Set(op.getIn(["operation","tags"]))
if(tags.count() < 1)
return taggedMap.update(DEFAULT_TAG, List(), ar => ar.push(op))
return tags.reduce( (res, tag) => res.update(tag, List(), (ar) => ar.push(op)), taggedMap )
}, Map())
}, tags.reduce( (taggedMap, tag) => {
return taggedMap.set(tag.get("name"), List())
} , OrderedMap()))
}
)
export const taggedOperations = ( state ) =>( { getConfigs } ) => {
let { operationsSorter }= getConfigs()
export const taggedOperations = (state) => ({ 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) => {
let sortFn = typeof operationsSorter === "function" ? operationsSorter
: sorters.operationsSorter[operationsSorter]
let operations = !sortFn ? ops : ops.sort(sortFn)
return Map({tagDetails: tagDetails(state, tag), operations: operations})})
return Map({ tagDetails: tagDetails(state, tag), operations: operations })
})
}
export const responses = createSelector(
@@ -281,12 +291,13 @@ export function parametersIncludeType(parameters, typeValue="") {
export function contentTypeValues(state, pathMethod) {
let op = spec(state).getIn(["paths", ...pathMethod], fromJS({}))
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({
requestContentType,

View File

@@ -1,7 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
import SplitPane from "react-split-pane"
import "./split-pane-mode.less"
const MODE_KEY = ["split-pane-mode"]
const MODE_LEFT = "left"

View File

@@ -1,5 +0,0 @@
.swagger-ui {
.Resizer.vertical.disabled {
display: none;
}
}

View File

@@ -1,8 +1,7 @@
import { shallowEqualKeys } from "core/utils"
import { transformPathToArray } from "core/path-translator"
export default function() {
return {
fn: { shallowEqualKeys, transformPathToArray }
fn: { shallowEqualKeys }
}
}