Merge branch 'master' into patch-1
This commit is contained in:
@@ -87,7 +87,8 @@
|
||||
"worker-loader": "^0.7.1",
|
||||
"xml": "1.0.1",
|
||||
"xml-but-prettier": "^1.0.1",
|
||||
"yaml-js": "0.2.0"
|
||||
"yaml-js": "0.2.0",
|
||||
"zenscroll": "4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "7.1.1",
|
||||
|
||||
@@ -39,7 +39,7 @@ export default class ArrayModel extends Component {
|
||||
*/
|
||||
|
||||
return <span className="model">
|
||||
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
|
||||
<ModelCollapse title={titleEl} expanded={ depth <= expandDepth } collapsedContent="[...]">
|
||||
[
|
||||
{
|
||||
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propStyle={ propStyle } />) : null
|
||||
|
||||
@@ -4,31 +4,47 @@ import PropTypes from "prop-types"
|
||||
export default class ModelCollapse extends Component {
|
||||
static propTypes = {
|
||||
collapsedContent: PropTypes.any,
|
||||
collapsed: PropTypes.bool,
|
||||
expanded: PropTypes.bool,
|
||||
children: PropTypes.any,
|
||||
title: PropTypes.element
|
||||
title: PropTypes.element,
|
||||
modelName: PropTypes.string,
|
||||
onToggle: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
collapsedContent: "{...}",
|
||||
collapsed: true,
|
||||
expanded: false,
|
||||
title: null
|
||||
}
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context)
|
||||
|
||||
let { collapsed, collapsedContent } = this.props
|
||||
let { expanded, collapsedContent } = this.props
|
||||
|
||||
this.state = {
|
||||
collapsed: collapsed !== undefined ? collapsed : ModelCollapse.defaultProps.collapsed,
|
||||
expanded : expanded,
|
||||
collapsedContent: collapsedContent || ModelCollapse.defaultProps.collapsedContent
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps){
|
||||
|
||||
if(this.props.expanded!= nextProps.expanded){
|
||||
this.setState({expanded: nextProps.expanded})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toggleCollapsed=()=>{
|
||||
|
||||
|
||||
if(this.props.onToggle){
|
||||
this.props.onToggle(this.props.modelName,!this.state.expanded)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed
|
||||
expanded: !this.state.expanded
|
||||
})
|
||||
}
|
||||
|
||||
@@ -38,10 +54,10 @@ export default class ModelCollapse extends Component {
|
||||
<span>
|
||||
{ title && <span onClick={this.toggleCollapsed} style={{ "cursor": "pointer" }}>{title}</span> }
|
||||
<span onClick={ this.toggleCollapsed } style={{ "cursor": "pointer" }}>
|
||||
<span className={ "model-toggle" + ( this.state.collapsed ? " collapsed" : "" ) }></span>
|
||||
<span className={ "model-toggle" + ( this.state.expanded ? "" : " collapsed" ) }></span>
|
||||
</span>
|
||||
{ this.state.collapsed ? this.state.collapsedContent : this.props.children }
|
||||
{ this.state.expanded ? this.props.children :this.state.collapsedContent }
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,41 @@
|
||||
import React, { Component, } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
//import layoutActions from "actions/layout"
|
||||
|
||||
|
||||
export default class ModelWrapper extends Component {
|
||||
|
||||
|
||||
export default class ModelComponent extends Component {
|
||||
static propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
expandDepth: PropTypes.number
|
||||
expandDepth: PropTypes.number,
|
||||
layoutActions: PropTypes.object,
|
||||
layoutSelectors: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
onToggle = (name,isShown) => {
|
||||
// If this prop is present, we'll have deepLinking for it
|
||||
if(this.props.layoutActions) {
|
||||
this.props.layoutActions.show(["models", name],isShown)
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
let { getComponent, getConfigs } = this.props
|
||||
const Model = getComponent("Model")
|
||||
|
||||
let expanded
|
||||
if(this.props.layoutSelectors) {
|
||||
// If this is prop is present, we'll have deepLinking for it
|
||||
expanded = this.props.layoutSelectors.isShown(["models",this.props.name])
|
||||
}
|
||||
|
||||
return <div className="model-box">
|
||||
<Model { ...this.props } getConfigs={ getConfigs } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
|
||||
<Model { ...this.props } getConfigs={ getConfigs } expanded={expanded} depth={ 1 } onToggle={ this.onToggle } expandDepth={ this.props.expandDepth || 0 }/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,17 @@ export default class Models extends Component {
|
||||
<Collapse isOpened={showModels}>
|
||||
{
|
||||
definitions.entrySeq().map( ( [ name, model ])=>{
|
||||
return <div className="model-container" key={ `models-section-${name}` }>
|
||||
|
||||
return <div id={ `model-${name}` } className="model-container" key={ `models-section-${name}` }>
|
||||
<ModelWrapper name={ name }
|
||||
expandDepth={ defaultModelExpandDepth }
|
||||
schema={ model }
|
||||
specPath={[...specPathBase, name]}
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
specSelectors={ specSelectors }/>
|
||||
specSelectors={ specSelectors }
|
||||
getConfigs = {getConfigs}
|
||||
layoutSelectors = {layoutSelectors}
|
||||
layoutActions = {layoutActions}/>
|
||||
</div>
|
||||
}).toArray()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ export default class ObjectModel extends Component {
|
||||
schema: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
expanded: PropTypes.bool,
|
||||
onToggle: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
isRef: PropTypes.bool,
|
||||
@@ -19,9 +21,8 @@ export default class ObjectModel extends Component {
|
||||
}
|
||||
|
||||
render(){
|
||||
let { schema, name, isRef, getComponent, getConfigs, depth, specPath, expandDepth, ...otherProps } = this.props
|
||||
let { specSelectors } = otherProps
|
||||
|
||||
let { schema, name, isRef, getComponent, getConfigs, depth, onToggle, expanded, specPath, ...otherProps } = this.props
|
||||
let { specSelectors,expandDepth } = otherProps
|
||||
const { isOAS3 } = specSelectors
|
||||
|
||||
if(!schema) {
|
||||
@@ -61,7 +62,13 @@ export default class ObjectModel extends Component {
|
||||
</span>
|
||||
|
||||
return <span className="model">
|
||||
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent={ collapsedContent }>
|
||||
<ModelCollapse
|
||||
modelName={name}
|
||||
title={titleEl}
|
||||
onToggle = {onToggle}
|
||||
expanded={ expanded ? true : depth <= expandDepth }
|
||||
collapsedContent={ collapsedContent }>
|
||||
|
||||
<span className="brace-open object">{ braceOpen }</span>
|
||||
{
|
||||
!isRef ? null : <JumpToPathSection />
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import scrollTo from "scroll-to-element"
|
||||
import zenscroll from "zenscroll"
|
||||
import { escapeDeepLinkPath } from "core/utils"
|
||||
|
||||
const SCROLL_OFFSET = -5
|
||||
let hasHashBeenParsed = false
|
||||
let hasHashBeenParsed = false //TODO this forces code to only run once which may prevent scrolling if page not refreshed
|
||||
|
||||
|
||||
export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args) => {
|
||||
@@ -12,7 +11,6 @@ export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args)
|
||||
if(!isDeepLinkingEnabled || isDeepLinkingEnabled === "false") {
|
||||
return
|
||||
}
|
||||
|
||||
if(window.location.hash && !hasHashBeenParsed ) {
|
||||
let hash = window.location.hash.slice(1) // # is first character
|
||||
|
||||
@@ -30,21 +28,23 @@ export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args)
|
||||
|
||||
let [tag, operationId] = hash.split("/")
|
||||
|
||||
let swaggerUI = document.querySelector(".swagger-ui")
|
||||
let myScroller = zenscroll.createScroller(swaggerUI)
|
||||
|
||||
if(tag && operationId) {
|
||||
// Pre-expand and scroll to the operation
|
||||
layoutActions.show(["operations-tag", tag], true)
|
||||
layoutActions.show(["operations", tag, operationId], true)
|
||||
|
||||
scrollTo(`#operations-${escapeDeepLinkPath(tag)}-${escapeDeepLinkPath(operationId)}`, {
|
||||
offset: SCROLL_OFFSET
|
||||
})
|
||||
let target = document.getElementById(`operations-${escapeDeepLinkPath(tag)}-${escapeDeepLinkPath(operationId)}`)
|
||||
myScroller.to(target)
|
||||
|
||||
} else if(tag) {
|
||||
// Pre-expand and scroll to the tag
|
||||
layoutActions.show(["operations-tag", tag], true)
|
||||
|
||||
scrollTo(`#operations-tag-${escapeDeepLinkPath(tag)}`, {
|
||||
offset: SCROLL_OFFSET
|
||||
})
|
||||
let target = document.getElementById(`operations-tag-${escapeDeepLinkPath(tag)}`)
|
||||
myScroller.to(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,17 +37,3 @@ export function changeMode(thing, mode="") {
|
||||
payload: {thing, mode}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// export function onlyShow(thing, shown=true) {
|
||||
// thing = normalizeArray(thing)
|
||||
// if(thing.length < 2)
|
||||
// throw new Error("layoutActions.onlyShow only works, when `thing` is an array with length > 1")
|
||||
// return {
|
||||
// type: ONLY_SHOW,
|
||||
// payload: {thing, shown}
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { fromJS } from "immutable"
|
||||
import {
|
||||
UPDATE_LAYOUT,
|
||||
UPDATE_FILTER,
|
||||
@@ -12,9 +13,14 @@ export default {
|
||||
[UPDATE_FILTER]: (state, action) => state.set("filter", action.payload),
|
||||
|
||||
[SHOW]: (state, action) => {
|
||||
let thing = action.payload.thing
|
||||
let shown = action.payload.shown
|
||||
return state.setIn(["shown"].concat(thing), shown)
|
||||
const isShown = action.payload.shown
|
||||
// This is one way to serialize an array, another (preferred) is to convert to json-pointer
|
||||
// TODO: use json-pointer serilization instead of fromJS(...), for performance
|
||||
const thingToShow = fromJS(action.payload.thing)
|
||||
// This is a map of paths to bools
|
||||
// eg: [one, two] => true
|
||||
// eg: [one] => false
|
||||
return state.update("shown", fromJS({}), a => a.set(thingToShow, isShown))
|
||||
},
|
||||
|
||||
[UPDATE_MODE]: (state, action) => {
|
||||
@@ -24,4 +30,3 @@ export default {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createSelector } from "reselect"
|
||||
import { normalizeArray } from "core/utils"
|
||||
import { fromJS } from "immutable"
|
||||
|
||||
const state = state => state
|
||||
|
||||
@@ -9,7 +10,7 @@ export const currentFilter = state => state.get("filter")
|
||||
|
||||
export const isShown = (state, thing, def) => {
|
||||
thing = normalizeArray(thing)
|
||||
return Boolean(state.getIn(["shown", ...thing], def))
|
||||
return state.get("shown", fromJS({})).get(fromJS(thing), def)
|
||||
}
|
||||
|
||||
export const whatMode = (state, thing, def="") => {
|
||||
@@ -21,4 +22,3 @@ export const showSummary = createSelector(
|
||||
state,
|
||||
state => !isShown(state, "editor")
|
||||
)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("<Models/>", function(){
|
||||
|
||||
// Then should render tabs
|
||||
expect(wrapper.find("ModelCollapse").length).toEqual(1)
|
||||
expect(wrapper.find("ModelComponent").length).toBeGreaterThan(0)
|
||||
expect(wrapper.find("ModelWrapper").length).toBeGreaterThan(0)
|
||||
wrapper.find("ModelComponent").forEach((modelWrapper) => {
|
||||
expect(modelWrapper.props().expandDepth).toBe(0)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user