mirror of
https://github.com/Redocly/redoc.git
synced 2025-03-03 17:35:46 +03:00
Change the way discriminator is rendered
This commit is contained in:
parent
158bd29b9b
commit
bff4b80845
|
@ -45,9 +45,9 @@
|
||||||
<template ngSwitchCase="object">
|
<template ngSwitchCase="object">
|
||||||
<table class="params-wrap" [ngClass]="{'params-array': schema._isArray}">
|
<table class="params-wrap" [ngClass]="{'params-array': schema._isArray}">
|
||||||
<!-- <caption> {{_displayType}} </caption> -->
|
<!-- <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,
|
<tr class="param" [ngClass]="{'last': last,
|
||||||
'discriminator': prop.isDiscriminator && !activeDescendant.empty,
|
'discriminator': prop.isDiscriminator,
|
||||||
'complex': prop._pointer,
|
'complex': prop._pointer,
|
||||||
'additional': prop._additional,
|
'additional': prop._additional,
|
||||||
'expanded': subSchema.visible
|
'expanded': subSchema.visible
|
||||||
|
@ -79,8 +79,8 @@
|
||||||
<div class="discriminator-info" *ngIf="prop.isDiscriminator">
|
<div class="discriminator-info" *ngIf="prop.isDiscriminator">
|
||||||
<span>This field value determines the exact schema:</span>
|
<span>This field value determines the exact schema:</span>
|
||||||
<drop-down (change)="selectDescendant($event)">
|
<drop-down (change)="selectDescendant($event)">
|
||||||
<option *ngFor="let descendant of schema._descendants; let i=index"
|
<option *ngFor="let descendant of descendants; let i=index"
|
||||||
[value]="i">{{descendant.name}}</option>
|
[value]="i" [attr.selected]="descendant.active ? '' : null" >{{descendant.name}}</option>
|
||||||
</drop-down>
|
</drop-down>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -95,15 +95,6 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</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>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -155,16 +155,6 @@ table {
|
||||||
border-left-color: transparent;
|
border-left-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.param.discriminator {
|
|
||||||
> .param-info {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .param-name:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.discriminator-info {
|
.discriminator-info {
|
||||||
font-weight: $regular;
|
font-weight: $regular;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
|
@ -25,6 +25,7 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
||||||
_isArray: boolean;
|
_isArray: boolean;
|
||||||
normalizer: SchemaNormalizer;
|
normalizer: SchemaNormalizer;
|
||||||
autoExpand = false;
|
autoExpand = false;
|
||||||
|
descendants: any;
|
||||||
|
|
||||||
constructor(specMgr:SpecManager, private _renderer: Renderer, private _elementRef: ElementRef) {
|
constructor(specMgr:SpecManager, private _renderer: Renderer, private _elementRef: ElementRef) {
|
||||||
super(specMgr);
|
super(specMgr);
|
||||||
|
@ -36,46 +37,40 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
selectDescendant(idx) {
|
selectDescendant(idx) {
|
||||||
let activeDescendant = this.schema._descendants[idx];
|
let activeDescendant = this.descendants[idx];
|
||||||
if (!activeDescendant || activeDescendant.active) return;
|
if (!activeDescendant || activeDescendant.active) return;
|
||||||
this.schema._descendants.forEach(subSchema => {
|
this.descendants.forEach(d => {
|
||||||
subSchema.active = false;
|
d.active = false;
|
||||||
});
|
});
|
||||||
activeDescendant.active = true;
|
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() {
|
initDescendants() {
|
||||||
if (!this.schema._descendants || !this.schema._descendants.length) {
|
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer);
|
||||||
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.selectDescendant(0);
|
this.selectDescendant(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
if (!this.pointer) return;
|
if (!this.pointer) return;
|
||||||
if (this.nestOdd) {
|
|
||||||
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'nestodd', 'true');
|
|
||||||
}
|
|
||||||
this.schema = this.componentSchema;
|
this.schema = this.componentSchema;
|
||||||
if (!this.schema) {
|
if (!this.schema) {
|
||||||
throw new Error(`Can't load component schema at ${this.pointer}`);
|
throw new Error(`Can't load component schema at ${this.pointer}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.applyStyling();
|
||||||
|
|
||||||
this.schema = this.normalizer.normalize(this.schema, this.normPointer);
|
this.schema = this.normalizer.normalize(this.schema, this.normPointer);
|
||||||
|
this.initDescendants();
|
||||||
this.schema = SchemaHelper.unwrapArray(this.schema, this.normPointer);
|
this.schema = SchemaHelper.unwrapArray(this.schema, this.normPointer);
|
||||||
|
this.preprocessSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
preprocessSchema() {
|
||||||
SchemaHelper.preprocess(this.schema, this.normPointer, this.pointer);
|
SchemaHelper.preprocess(this.schema, this.normPointer, this.pointer);
|
||||||
|
|
||||||
if (!this.schema.isTrivial) {
|
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.properties = this.properties && this.properties.filter(prop => !prop.readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initDescendants();
|
|
||||||
this._hasSubSchemas = this.properties && this.properties.some(
|
this._hasSubSchemas = this.properties && this.properties.some(
|
||||||
propSchema => {
|
propSchema => {
|
||||||
if (propSchema.type === 'array') {
|
if (propSchema.type === 'array') {
|
||||||
|
@ -101,8 +95,14 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
||||||
this.autoExpand = this.properties && this.properties.length === 1;
|
this.autoExpand = this.properties && this.properties.length === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackByIdx(index: number, item: any): number {
|
applyStyling() {
|
||||||
return index;
|
if (this.nestOdd) {
|
||||||
|
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'nestodd', 'true');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trackByName(index: number, item: any): number {
|
||||||
|
return item.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
|
@ -59,7 +59,6 @@ const injectors = {
|
||||||
discriminator: {
|
discriminator: {
|
||||||
check: (propertySchema) => propertySchema.discriminator,
|
check: (propertySchema) => propertySchema.discriminator,
|
||||||
inject: (injectTo, propertySchema = injectTo, pointer) => {
|
inject: (injectTo, propertySchema = injectTo, pointer) => {
|
||||||
injectTo._descendants = SpecManager.instance().findDerivedDefinitions(pointer);
|
|
||||||
injectTo.discriminator = propertySchema.discriminator;
|
injectTo.discriminator = propertySchema.discriminator;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -215,7 +214,6 @@ export class SchemaHelper {
|
||||||
schema.required.forEach(prop => requiredMap[prop] = true);
|
schema.required.forEach(prop => requiredMap[prop] = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let discriminatorFieldIdx = -1;
|
|
||||||
let props = schema.properties && Object.keys(schema.properties).map((propName, idx) => {
|
let props = schema.properties && Object.keys(schema.properties).map((propName, idx) => {
|
||||||
let propertySchema = Object.assign({}, schema.properties[propName]);
|
let propertySchema = Object.assign({}, schema.properties[propName]);
|
||||||
let propPointer = propertySchema._pointer ||
|
let propPointer = propertySchema._pointer ||
|
||||||
|
@ -228,9 +226,6 @@ export class SchemaHelper {
|
||||||
}
|
}
|
||||||
propertySchema._required = !!requiredMap[propName];
|
propertySchema._required = !!requiredMap[propName];
|
||||||
propertySchema.isDiscriminator = (schema.discriminator === propName);
|
propertySchema.isDiscriminator = (schema.discriminator === propName);
|
||||||
if (propertySchema.isDiscriminator) {
|
|
||||||
discriminatorFieldIdx = idx;
|
|
||||||
}
|
|
||||||
return propertySchema;
|
return propertySchema;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -242,11 +237,6 @@ export class SchemaHelper {
|
||||||
props.push(propsSchema);
|
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
|
// filter readOnly props for request schemas
|
||||||
if (opts.skipReadOnly) {
|
if (opts.skipReadOnly) {
|
||||||
props = props.filter(prop => !prop.readOnly);
|
props = props.filter(prop => !prop.readOnly);
|
||||||
|
|
|
@ -102,8 +102,10 @@ class AllOfMerger {
|
||||||
AllOfMerger.mergeObject(into, subSchema, i);
|
AllOfMerger.mergeObject(into, subSchema, i);
|
||||||
}
|
}
|
||||||
// don't merge _pointer
|
// don't merge _pointer
|
||||||
|
let tmpPtr = subSchema._pointer;
|
||||||
subSchema._pointer = null;
|
subSchema._pointer = null;
|
||||||
defaults(into, subSchema);
|
defaults(into, subSchema);
|
||||||
|
subSchema._pointer = tmpPtr;
|
||||||
}
|
}
|
||||||
into.allOf = null;
|
into.allOf = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,11 +163,7 @@ export class SpecManager {
|
||||||
let idx = subTypes.findIndex(ref => ref === defPointer);
|
let idx = subTypes.findIndex(ref => ref === defPointer);
|
||||||
if (idx < 0) continue;
|
if (idx < 0) continue;
|
||||||
|
|
||||||
let empty = false;
|
res.push({name: defName, $ref: `#/definitions/${defName}`});
|
||||||
if (subTypes.length === 1) {
|
|
||||||
empty = true;
|
|
||||||
}
|
|
||||||
res.push({name: defName, $ref: `#/definitions/${defName}`, empty});
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user