Redesign discriminator UI

This commit is contained in:
Roman Hotsiy 2016-01-10 17:29:35 +02:00
parent a81999c90b
commit e57cda256c
4 changed files with 50 additions and 32 deletions

View File

@ -1,7 +1,7 @@
<span *ngIf="isTrivial" class="param-type param-type-trivial" [ngClass]="type">{{_displayType}}</span>
<div *ngIf="!isTrivial && !data.derived.length" class="params-wrap" [ngClass]="{'params-array': isArray}">
<div *ngIf="!isTrivial" class="params-wrap" [ngClass]="{'params-array': isArray}">
<div *ngFor="#prop of data.properties" class="param-wrap">
<div class="param">
<div class="param" [ngClass]="{'discriminator': prop.isDiscriminator}">
<div class="param-name">
<span>{{prop._name}}</span>
</div>
@ -11,6 +11,7 @@
<span *ngIf="prop.isRequired" class="param-required">Required</span>
</div>
<div class="param-description" innerHtml="{{prop.description | marked}}"></div>
<div class="discriminator-info" *ngIf="prop.isDiscriminator"> This field value determines the exact schema: </div>
</div>
</div>
<div class="param-schema" [ngClass]="{'param-array': prop._isArray}" *ngIf="prop._pointer">
@ -18,13 +19,12 @@
</json-schema>
</div>
</div>
</div>
<div *ngIf="data.derived.length">
<div class="discriminator"> Based on <strong>{{data.discriminator}}</strong> field value: </div>
<tabs>
<tab *ngFor="#derived of data.derived" tabTitle="{{derived.name}}">
<json-schema pointer="{{derived.$ref}}" [final]="derived.final" [isArray]='isArray'>
</json-schema>
</tab>
</tabs>
<div *ngIf="data.derived.length" class="param-wrap">
<tabs>
<tab *ngFor="#derived of data.derived" tabTitle="{{derived.name}}">
<json-schema pointer="{{derived.$ref}}" [final]="derived.final" [isArray]='isArray'>
</json-schema>
</tab>
</tabs>
</div>
</div>

View File

@ -38,17 +38,11 @@ export default class JsonSchema extends BaseComponent {
let normPtr = schema._pointer || this.pointer;
let derived = this.schemaMgr.findDerivedDefinitions( normPtr );
if (!this.final && derived.length) {
derived.unshift({
name: JsonPointer.baseName(normPtr),
$ref: normPtr,
final: true
});
this.data.derived = derived;
this.data.discriminator = schema.discriminator;
return;
}
this.joinAllOf(schema);
this.joinAllOf(schema, {omitParent: true});
if (schema.type !== 'object') {
this.isTrivial = true;
@ -69,11 +63,19 @@ export default class JsonSchema extends BaseComponent {
this._displayType = `${schema.type} (Custom key-value pairs)`;
return;
}
let props = Object.keys(schema.properties).map(prop => {
let discriminatorFieldIdx = -1;
let props = Object.keys(schema.properties).map((prop, idx) => {
let propData = schema.properties[prop];
this.injectPropData(prop, propData);
if (propData.isDiscriminator) discriminatorFieldIdx = idx;
return propData;
});
// Move discriminator field to the end of properties list
if (discriminatorFieldIdx > -1) {
let discrProp = props.splice(discriminatorFieldIdx, 1);
props.push(discrProp[0]);
}
this.data.properties = props;
}
@ -86,12 +88,16 @@ export default class JsonSchema extends BaseComponent {
names.forEach(el => {
el.style.minWidth = maxWidth + 'px';
});
let discrValues = this.element.querySelector('tabs ul');
if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px';
}
injectPropData(prop, propData) {
propData._name = prop;
propData.isRequired = this.requiredMap[prop];
propData._displayType = propData.type;
propData.isDiscriminator = (this.componentSchema.discriminator === prop);
if (propData.type === 'array') {
let itemType = propData.items.type;
let itemFormat = propData.items.format;

View File

@ -5,7 +5,7 @@ $cell-spacing: 25px;
$cell-padding: 10px;
$bullet-margin: 10px;
$line-border: $lines-width solid $tree-lines-color;
$line-border-erase: $lines-width solid white;
$line-border-erase: ($lines-width + 1px) solid white;
$param-name-height: 20px;
@ -113,7 +113,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin;
content: "";
display: block;
position: absolute;
left: -$lines-width;
left: -$lines-width - 1px;
border-left: $line-border-erase;
top: ($param-name-height/2) + $cell-padding + $lines-width;
background-color: white;
@ -170,25 +170,36 @@ $array-marker-line-height: 1.5;
height: ($param-name-height/2) + $cell-padding;
}
.discriminator {
margin-top: 1em;
.param.discriminator {
> div {
padding-bottom: 0;
border-bottom: 0;
}
}
.discriminator-info {
font-weight: bold;
}
:host tabs {
display: block;
border-left: 1px solid $tree-lines-color;
}
:host tabs li {
padding: 0.2em 0;
margin-right: 1em;
margin: 0.2em 0.5em 0.2em 0;
font-size: 14px;
color: green;
&:before, &:after {
content: '"';
}
border: 0;
color: white;
padding: 0 15px;
border-radius: 10px;
background-color: #8A9094;
&:last-of-type {
margin: 0;
}
&.active {
border-bottom: 2px solid $tree-lines-color;
background-color: $headers-color;
}
}

View File

@ -123,7 +123,7 @@ export class BaseComponent {
this.componentSchema = schema;
}
joinAllOf(schema = this.componentSchema) {
joinAllOf(schema = this.componentSchema, opts) {
var self = this;
function merge(into, schemas) {
if (into.required || into.properties) {
@ -134,6 +134,7 @@ export class BaseComponent {
into.required = [];
into.properties = {};
for (let subSchema of schemas) {
if (opts && opts.omitParent && subSchema.discriminator) continue;
// TODO: add support for merge array schemas
if (typeof subSchema !== 'object' || subSchema.type !== 'object') {