Change the way discriminator is rendered

This commit is contained in:
Roman Hotsiy 2016-08-30 13:51:14 +03:00
parent 158bd29b9b
commit bff4b80845
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
6 changed files with 32 additions and 63 deletions

View File

@ -45,9 +45,9 @@
<template ngSwitchCase="object">
<table class="params-wrap" [ngClass]="{'params-array': schema._isArray}">
<!-- <caption> {{_displayType}} </caption> -->
<template ngFor [ngForOf]="properties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByIdx">
<template ngFor [ngForOf]="properties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByName">
<tr class="param" [ngClass]="{'last': last,
'discriminator': prop.isDiscriminator && !activeDescendant.empty,
'discriminator': prop.isDiscriminator,
'complex': prop._pointer,
'additional': prop._additional,
'expanded': subSchema.visible
@ -79,8 +79,8 @@
<div class="discriminator-info" *ngIf="prop.isDiscriminator">
<span>This field value determines the exact schema:</span>
<drop-down (change)="selectDescendant($event)">
<option *ngFor="let descendant of schema._descendants; let i=index"
[value]="i">{{descendant.name}}</option>
<option *ngFor="let descendant of descendants; let i=index"
[value]="i" [attr.selected]="descendant.active ? '' : null" >{{descendant.name}}</option>
</drop-down>
</div>
</td>
@ -95,15 +95,6 @@
</td>
</tr>
</template>
<tr *ngIf="hasDescendants" class="param-wrap discriminator-wrap" [ngClass]="{empty:activeDescendant.empty}">
<td colspan="2">
<div class="derived-schema" *ngFor="let descendant of schema._descendants" [ngClass]="{active: descendant.active, empty: descendant.empty}">
<json-schema class="discriminator-part" *ngIf="!descendant.empty" [childFor]="pointer" [nestOdd]="nestOdd"
pointer="{{descendant.$ref}}" [final]="descendant.final" [isRequestSchema]="isRequestSchema">
</json-schema>
</div>
</td>
</tr>
</table>
</template>

View File

@ -155,16 +155,6 @@ table {
border-left-color: transparent;
}
.param.discriminator {
> .param-info {
padding-bottom: 0;
}
> .param-name:after {
display: none;
}
}
.discriminator-info {
font-weight: $regular;
margin-bottom: 10px;

View File

@ -25,6 +25,7 @@ export class JsonSchema extends BaseComponent implements OnInit {
_isArray: boolean;
normalizer: SchemaNormalizer;
autoExpand = false;
descendants: any;
constructor(specMgr:SpecManager, private _renderer: Renderer, private _elementRef: ElementRef) {
super(specMgr);
@ -36,46 +37,40 @@ export class JsonSchema extends BaseComponent implements OnInit {
}
selectDescendant(idx) {
let activeDescendant = this.schema._descendants[idx];
let activeDescendant = this.descendants[idx];
if (!activeDescendant || activeDescendant.active) return;
this.schema._descendants.forEach(subSchema => {
subSchema.active = false;
this.descendants.forEach(d => {
d.active = false;
});
activeDescendant.active = true;
this.activeDescendant = activeDescendant;
this.pointer = activeDescendant.$ref;
this.schema = this.specMgr.byPointer(this.pointer);
this.schema = this.normalizer.normalize(this.schema, this.normPointer, {omitParent: false});
this.preprocessSchema();
}
initDescendants() {
if (!this.schema._descendants || !this.schema._descendants.length) {
return;
}
this.hasDescendants = true;
let enumArr = this.schema._properties[this.schema._properties.length - 1].enum;
if (enumArr) {
let enumOrder = {};
enumArr.forEach((enumItem, idx) => {
enumOrder[enumItem.val] = idx;
});
this.schema._descendants.sort((a, b) => {
return enumOrder[a.name] > enumOrder[b.name] ? 1 : -1;
});
}
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer);
this.selectDescendant(0);
}
init() {
if (!this.pointer) return;
if (this.nestOdd) {
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'nestodd', 'true');
}
this.schema = this.componentSchema;
if (!this.schema) {
throw new Error(`Can't load component schema at ${this.pointer}`);
}
this.applyStyling();
this.schema = this.normalizer.normalize(this.schema, this.normPointer);
this.initDescendants();
this.schema = SchemaHelper.unwrapArray(this.schema, this.normPointer);
this.preprocessSchema();
}
preprocessSchema() {
SchemaHelper.preprocess(this.schema, this.normPointer, this.pointer);
if (!this.schema.isTrivial) {
@ -89,7 +84,6 @@ export class JsonSchema extends BaseComponent implements OnInit {
this.properties = this.properties && this.properties.filter(prop => !prop.readOnly);
}
this.initDescendants();
this._hasSubSchemas = this.properties && this.properties.some(
propSchema => {
if (propSchema.type === 'array') {
@ -101,8 +95,14 @@ export class JsonSchema extends BaseComponent implements OnInit {
this.autoExpand = this.properties && this.properties.length === 1;
}
trackByIdx(index: number, item: any): number {
return index;
applyStyling() {
if (this.nestOdd) {
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'nestodd', 'true');
}
}
trackByName(index: number, item: any): number {
return item.name;
}
ngOnInit() {

View File

@ -59,7 +59,6 @@ const injectors = {
discriminator: {
check: (propertySchema) => propertySchema.discriminator,
inject: (injectTo, propertySchema = injectTo, pointer) => {
injectTo._descendants = SpecManager.instance().findDerivedDefinitions(pointer);
injectTo.discriminator = propertySchema.discriminator;
}
},
@ -215,7 +214,6 @@ export class SchemaHelper {
schema.required.forEach(prop => requiredMap[prop] = true);
}
let discriminatorFieldIdx = -1;
let props = schema.properties && Object.keys(schema.properties).map((propName, idx) => {
let propertySchema = Object.assign({}, schema.properties[propName]);
let propPointer = propertySchema._pointer ||
@ -228,9 +226,6 @@ export class SchemaHelper {
}
propertySchema._required = !!requiredMap[propName];
propertySchema.isDiscriminator = (schema.discriminator === propName);
if (propertySchema.isDiscriminator) {
discriminatorFieldIdx = idx;
}
return propertySchema;
});
@ -242,11 +237,6 @@ export class SchemaHelper {
props.push(propsSchema);
}
// Move discriminator field to the end of properties list
if (discriminatorFieldIdx > -1) {
let discrProp = props.splice(discriminatorFieldIdx, 1);
props.push(discrProp[0]);
}
// filter readOnly props for request schemas
if (opts.skipReadOnly) {
props = props.filter(prop => !prop.readOnly);

View File

@ -102,8 +102,10 @@ class AllOfMerger {
AllOfMerger.mergeObject(into, subSchema, i);
}
// don't merge _pointer
let tmpPtr = subSchema._pointer;
subSchema._pointer = null;
defaults(into, subSchema);
subSchema._pointer = tmpPtr;
}
into.allOf = null;
}

View File

@ -163,11 +163,7 @@ export class SpecManager {
let idx = subTypes.findIndex(ref => ref === defPointer);
if (idx < 0) continue;
let empty = false;
if (subTypes.length === 1) {
empty = true;
}
res.push({name: defName, $ref: `#/definitions/${defName}`, empty});
res.push({name: defName, $ref: `#/definitions/${defName}`});
}
return res;
}