ソースを参照

Merge pull request #3196 from gwynjudd/filter

Added maxRows and filter support
bubble
shockey 7年前
committed by GitHub
コミット
a5cab61d99
10個のファイルの変更91行の追加29行の削除
  1. +2
    -0
      README.md
  2. +15
    -1
      src/core/components/operations.jsx
  3. +8
    -4
      src/core/index.js
  4. +8
    -0
      src/core/plugins/layout/actions.js
  5. +3
    -0
      src/core/plugins/layout/reducers.js
  6. +2
    -0
      src/core/plugins/layout/selectors.js
  7. +16
    -1
      src/plugins/topbar/topbar.jsx
  8. +2
    -2
      src/standalone/layout.jsx
  9. +28
    -20
      src/style/_layout.scss
  10. +7
    -1
      src/style/_topbar.scss

+ 2
- 0
README.md ファイルの表示

@@ -144,6 +144,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'.
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`.
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



+ 15
- 1
src/core/components/operations.jsx ファイルの表示

@@ -33,7 +33,21 @@ export default class Operations extends React.Component {
const Collapse = getComponent("Collapse")

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 (
<div>


+ 8
- 4
src/core/index.js ファイルの表示

@@ -6,7 +6,7 @@ import ApisPreset from "core/presets/apis"
import * as AllPlugins from "core/plugins/all"
import { parseSeach, filterConfigs } from "core/utils"

const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion", "maxDisplayedTags", "filter",
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]

@@ -26,6 +26,8 @@ module.exports = function SwaggerUI(opts) {
urls: null,
layout: "BaseLayout",
docExpansion: "list",
maxDisplayedTags: null,
filter: null,
validatorUrl: "https://online.swagger.io/validator",
configs: {},
custom: {},
@@ -50,7 +52,9 @@ module.exports = function SwaggerUI(opts) {
store: { },
}

const constructorConfig = deepExtend({}, defaults, opts)
let queryConfig = parseSeach()

const constructorConfig = deepExtend({}, defaults, opts, queryConfig)

const storeConfigs = deepExtend({}, constructorConfig.store, {
system: {
@@ -59,7 +63,8 @@ module.exports = function SwaggerUI(opts) {
plugins: constructorConfig.presets,
state: {
layout: {
layout: constructorConfig.layout
layout: constructorConfig.layout,
filter: constructorConfig.filter
},
spec: {
spec: "",
@@ -80,7 +85,6 @@ module.exports = function SwaggerUI(opts) {
store.register([constructorConfig.plugins, inlinePlugin])

var system = store.getSystem()
let queryConfig = parseSeach()

system.initOAuth = system.authActions.configureAuth



+ 8
- 0
src/core/plugins/layout/actions.js ファイルの表示

@@ -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 {


+ 3
- 0
src/core/plugins/layout/reducers.js ファイルの表示

@@ -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


+ 2
- 0
src/core/plugins/layout/selectors.js ファイルの表示

@@ -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))


+ 16
- 1
src/plugins/topbar/topbar.jsx ファイルの表示

@@ -6,6 +6,11 @@ import Logo from "./logo_small.png"

export default class Topbar extends React.Component {

static propTypes = {
layoutSelectors: PropTypes.object.isRequired,
layoutActions: PropTypes.object.isRequired
}

constructor(props, context) {
super(props, context)
this.state = { url: props.specSelectors.url(), selectedIndex: 0 }
@@ -80,13 +85,19 @@ export default class Topbar extends React.Component {
}
}

onFilterChange =(e) => {
let {target: {value}} = e
this.props.layoutActions.updateFilter(value)
}

render() {
let { getComponent, specSelectors, getConfigs } = this.props
let { getComponent, specSelectors, getConfigs, layoutSelectors } = this.props
const Button = getComponent("Button")
const Link = getComponent("Link")

let isLoading = specSelectors.loadingStatus() === "loading"
let isFailed = specSelectors.loadingStatus() === "failed"
let filter = layoutSelectors.currentFilter()

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


+ 2
- 2
src/standalone/layout.jsx ファイルの表示

@@ -29,7 +29,7 @@ export default class StandaloneLayout extends React.Component {
return (

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


+ 28
- 20
src/style/_layout.scss ファイルの表示

@@ -45,6 +45,7 @@ body
.opblock-tag
{
display: flex;
align-items: center;

padding: 10px 20px 10px 10px;

@@ -53,8 +54,6 @@ body

border-bottom: 1px solid rgba(#3b4151, .3);

align-items: center;

&:hover
{
background: rgba(#000,.02);
@@ -106,9 +105,10 @@ body
font-size: 14px;
font-weight: normal;

flex: 1;

padding: 0 10px;

flex: 1;
@include text_body();
}
}
@@ -134,6 +134,8 @@ body
transition: all .5s;
}



.opblock
{
margin: 0 0 15px 0;
@@ -154,24 +156,23 @@ body
.opblock-section-header
{
display: flex;
align-items: center;

padding: 8px 20px;

background: rgba(#fff,.8);
box-shadow: 0 1px 2px rgba(#000,.1);

align-items: center;

label
{
font-size: 12px;
font-weight: bold;

display: flex;
align-items: center;

margin: 0;

align-items: center;
@include text_headline();

span
@@ -184,9 +185,10 @@ body
{
font-size: 14px;

flex: 1;

margin: 0;

flex: 1;
@include text_headline();
}
}
@@ -215,11 +217,11 @@ body
font-size: 16px;

display: flex;
align-items: center;

padding: 0 10px;

@include text_code();
align-items: center;

.view-line-link
{
@@ -258,18 +260,18 @@ body
font-size: 13px;

flex: 1;

@include text_body();
}

.opblock-summary
{
display: flex;
align-items: center;

padding: 5px;

cursor: pointer;

align-items: center;
}

&.opblock-post
@@ -316,12 +318,12 @@ body

.opblock-schemes
{
padding: 8px 20px;
padding: 8px 20px;

.schemes-title
{
padding: 0 10px 0 0;
}
.schemes-title
{
padding: 0 10px 0 0;
}
}
}

@@ -498,13 +500,11 @@ body
margin: 0;
padding: 10px;

white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
white-space: pre-wrap;


border-radius: 4px;
background: #41444e;
@@ -533,10 +533,9 @@ body
.schemes
{
display: flex;

align-items: center;

> label
> label
{
font-size: 12px;
font-weight: bold;
@@ -624,3 +623,12 @@ body
opacity: 0;
}
}


section
{
h3
{
@include text_headline();
}
}

+ 7
- 1
src/style/_topbar.scss ファイルの表示

@@ -29,6 +29,12 @@
padding: 0 10px;
}
}
.operation-filter-input
{
border: 2px solid #547f00;
border-right: none;
border-radius: 4px 0 0 4px;
}

.download-url-wrapper
{
@@ -43,7 +49,7 @@
margin: 0;

border: 2px solid #547f00;
border-radius: 4px 0 0 4px;
border-radius: 0 0 0 0;
outline: none;
}



読み込み中…
キャンセル
保存