create own basic json-schema viewer

This commit is contained in:
Roman Hotsiy 2015-11-18 23:23:18 +02:00
parent 90381d2e9d
commit 7c8edb04e4
6 changed files with 211 additions and 45 deletions

View File

@ -0,0 +1,113 @@
h2 {
border-bottom: 1px solid #999;
font-size: 18px;
padding: 0.2em 0;
margin: 0.5em 0;
color: #253137;
}
.param-schema {
padding-left: 13px;
padding-top: 5px;
border-left: 2px solid #7D97CE;
}
.param-wrap {
position: relative;
}
.param-schema:before {
content: "";
position: absolute;
left: 15px;
top: 10px;
bottom: 0;
border-left: 2px solid #7D97CE;
}
.param-name {
/*display: table-cell;*/
padding: 0 5px;
font-weight: bold;
box-sizing: border-box;
}
.param-info {
/*display: table-cell;*/
width: 100%;
padding: 0 5px;
box-sizing: border-box;
}
.param {
display: flex;
}
.param-required {
color: red;
font-weight: bold;
font-size: 12px;
}
.param-description {
padding: 0.5em 0;
border-bottom: 1px solid #999;
}
.param-type {
text-transform: capitalize;
color: #999;
font-size: 12px;
line-height: 2;
}
.param-name {
border-left: 2px solid #7D97CE;
white-space: nowrap;
position: relative;
}
/* tree */
.param-name > span:before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background-color: #7D97CE;
margin: 0 5px;
top: -1px;
position: relative;
}
.param-name > span:after {
content: "";
position: absolute;
border-top: 2px solid #7D97CE;
width: 10px;
left: 0;
top: 10px;
}
.param-wrap:first-of-type .param-name:before {
content: "";
display: block;
position: absolute;
left: -2px;
width: 2px;
background-color: white;
height: 10px;
}
.param-wrap:last-of-type .param-name:after {
content: "";
display: block;
position: absolute;
left: -2px;
width: 2px;
top: 18px;
background-color: white;
bottom: 0;
}
.param-schema .param-wrap:first-of-type .param-name:before {
display: none !important;
}

View File

@ -0,0 +1,20 @@
<div class="params-wrap">
<div *ng-for="#prop of data.properties" class="param-wrap">
<div class="param">
<div class="param-name">
<span> {{prop._name}} </span>
</div>
<div class="param-info">
<div>
<span class="param-type" [ng-class]="prop.type">{{prop.type}} {{prop.format}}</span>
<span *ng-if="prop.isRequired" class="param-required">Required</span>
</div>
<div class="param-description" inner-html="{{prop.description | marked}}"></div>
</div>
</div>
<div class="param-schema" *ng-if="prop._pointer">
<json-schema pointer="{{prop._pointer}}">
</json-schema>
</div>
</div>
</div>

View File

@ -0,0 +1,71 @@
'use strict';
import {JsonPointer} from '../../utils/JsonPointer';
import {RedocComponent, BaseComponent} from '../base';
import {ElementRef} from 'angular2/angular2';
@RedocComponent({
selector: 'json-schema',
templateUrl: './lib/components/JsonSchema/json-schema.html',
styleUrls: ['./lib/components/JsonSchema/json-schema.css'],
directives: [JsonSchema]
})
export default class JsonSchema extends BaseComponent {
constructor(schemaMgr, elementRef) {
super(schemaMgr);
this.element = elementRef.nativeElement;
}
prepareModel() {
this.dereference();
this.requiredMap = {};
if (this.schema.required) {
this.schema.required.forEach(prop => this.requiredMap[prop] = true);
}
let schema = this.componentSchema;
this.data = {};
this.data.properties = [];
if (schema.type !== 'object') {
// TODO
return;
}
let props = Object.keys(schema.properties).map(prop => {
let propData = schema.properties[prop];
this.injectPropData(prop, propData);
return propData;
})
this.data.properties = props;
}
adjustNameColumnWidth() {
// TODO handle internal schemes differently
let names = [].slice.call(this.element.querySelectorAll('.param-name'));
let widths = names.map(el => el.offsetWidth);
let maxWidth = Math.max(...widths);
names.forEach(el => {
el.style.minWidth = maxWidth + 'px';
});
}
injectPropData(prop, propData) {
propData._name = prop;
propData.isRequired = this.requiredMap[prop];
if (propData.type === 'array') {
let itemType = propData.items.type;
if (itemType === 'object') itemType = propData.items.title || 'object';
propData.type = `array of ${itemType}`;
}
if (propData.type === 'object') {
propData.type = propData.title || 'object'
}
}
init() {
setTimeout(() => this.adjustNameColumnWidth());
}
}
JsonSchema.parameters = JsonSchema.parameters.concat([[ElementRef]]);

View File

@ -19,49 +19,7 @@
<div class="body-param-description" inner-html="{{data.bodyParam.description | marked}}"></div>
<div>
<schema class="body-schema param-type" pointer="{{data.bodyParam.pointer}}/schema">
</schema>
<json-schema pointer="{{data.bodyParam.pointer}}/schema">
</json-schema>
</div>
</div>
<!--
<table class="inline">
<!- No params ->
<tr *ng-if="data.noParams">
<td colspan="3">
<small class="no-params" > No parameters </small>
</td>
</tr>
<thead>
<tr>
<th colspan="3"> Parameters </th>
</tr>
<tr *ng-if="!data.noParams">
<th> Name </th>
<th> Description </th>
<th> Type </th>
</tr>
</thead>
<tbody>
<!- General parameters ->
<tr *ng-for="#param of data.params">
<!-<div class="param">->
<td class="param-name">{{param.name}}</td>
<td class="param-description" inner-html="{{param.description | marked}}"></td>
<td>
<span class="type" [ng-class]="param.type">{{param.type}}</span>
</td>
<!-</div>->
</tr>
<!- in-body parameter ->
<tr class="param body-param" *ng-if="data.bodyParam">
<td class="param-name">{{data.bodyParam.name}}</td>
<td class="param-description" inner-html="{{data.bodyParam.description | marked}}"></td>
<td>
<schema class="body-schema param-type" pointer="{{data.bodyParam.pointer}}/schema">
</schema>
</td>
</tr>
</tbody>
</table>
-->

View File

@ -2,12 +2,13 @@
import {RedocComponent, BaseComponent} from '../base';
import JsonSchemaView from '../JsonSchemaView/json-schema-view';
import JsonSchema from '../JsonSchema/json-schema';
@RedocComponent({
selector: 'params-list',
templateUrl: './lib/components/ParamsList/params-list.html',
styleUrls: ['./lib/components/ParamsList/params-list.css'],
directives: [JsonSchemaView]
directives: [JsonSchemaView, JsonSchema]
})
export default class ParamsList extends BaseComponent {
constructor(schemaMgr) {

View File

@ -11,10 +11,12 @@ import ResponsesSamples from './ResponsesSamples/responses-samples';
import SchemaSample from './SchemaSample/schema-sample';
import SideMenu from './SideMenu/side-menu';
import SideMenuCat from './SideMenuCat/side-menu-cat';
import JsonSchema from './JsonSchema/json-schema';
const REDOC_COMPONENTS = [
ApiInfo,
JsonSchemaView,
JsonSchema,
Method,
MethodsList,
ParamsList,
@ -29,6 +31,7 @@ const REDOC_COMPONENTS = [
export {
ApiInfo,
JsonSchemaView,
JsonSchema,
Method,
MethodsList,
ParamsList,