mirror of
https://github.com/Redocly/redoc.git
synced 2025-05-04 15:43:46 +03:00
Redesign discriminator UI
This commit is contained in:
parent
a81999c90b
commit
e57cda256c
|
@ -1,7 +1,7 @@
|
||||||
<span *ngIf="isTrivial" class="param-type param-type-trivial" [ngClass]="type">{{_displayType}}</span>
|
<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 *ngFor="#prop of data.properties" class="param-wrap">
|
||||||
<div class="param">
|
<div class="param" [ngClass]="{'discriminator': prop.isDiscriminator}">
|
||||||
<div class="param-name">
|
<div class="param-name">
|
||||||
<span>{{prop._name}}</span>
|
<span>{{prop._name}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
<span *ngIf="prop.isRequired" class="param-required">Required</span>
|
<span *ngIf="prop.isRequired" class="param-required">Required</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="param-description" innerHtml="{{prop.description | marked}}"></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>
|
</div>
|
||||||
<div class="param-schema" [ngClass]="{'param-array': prop._isArray}" *ngIf="prop._pointer">
|
<div class="param-schema" [ngClass]="{'param-array': prop._isArray}" *ngIf="prop._pointer">
|
||||||
|
@ -18,13 +19,12 @@
|
||||||
</json-schema>
|
</json-schema>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div *ngIf="data.derived.length" class="param-wrap">
|
||||||
<div *ngIf="data.derived.length">
|
<tabs>
|
||||||
<div class="discriminator"> Based on <strong>{{data.discriminator}}</strong> field value: </div>
|
<tab *ngFor="#derived of data.derived" tabTitle="{{derived.name}}">
|
||||||
<tabs>
|
<json-schema pointer="{{derived.$ref}}" [final]="derived.final" [isArray]='isArray'>
|
||||||
<tab *ngFor="#derived of data.derived" tabTitle="{{derived.name}}">
|
</json-schema>
|
||||||
<json-schema pointer="{{derived.$ref}}" [final]="derived.final" [isArray]='isArray'>
|
</tab>
|
||||||
</json-schema>
|
</tabs>
|
||||||
</tab>
|
</div>
|
||||||
</tabs>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,17 +38,11 @@ export default class JsonSchema extends BaseComponent {
|
||||||
let normPtr = schema._pointer || this.pointer;
|
let normPtr = schema._pointer || this.pointer;
|
||||||
let derived = this.schemaMgr.findDerivedDefinitions( normPtr );
|
let derived = this.schemaMgr.findDerivedDefinitions( normPtr );
|
||||||
if (!this.final && derived.length) {
|
if (!this.final && derived.length) {
|
||||||
derived.unshift({
|
|
||||||
name: JsonPointer.baseName(normPtr),
|
|
||||||
$ref: normPtr,
|
|
||||||
final: true
|
|
||||||
});
|
|
||||||
this.data.derived = derived;
|
this.data.derived = derived;
|
||||||
this.data.discriminator = schema.discriminator;
|
this.data.discriminator = schema.discriminator;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.joinAllOf(schema);
|
this.joinAllOf(schema, {omitParent: true});
|
||||||
|
|
||||||
if (schema.type !== 'object') {
|
if (schema.type !== 'object') {
|
||||||
this.isTrivial = true;
|
this.isTrivial = true;
|
||||||
|
@ -69,11 +63,19 @@ export default class JsonSchema extends BaseComponent {
|
||||||
this._displayType = `${schema.type} (Custom key-value pairs)`;
|
this._displayType = `${schema.type} (Custom key-value pairs)`;
|
||||||
return;
|
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];
|
let propData = schema.properties[prop];
|
||||||
this.injectPropData(prop, propData);
|
this.injectPropData(prop, propData);
|
||||||
|
if (propData.isDiscriminator) discriminatorFieldIdx = idx;
|
||||||
return propData;
|
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;
|
this.data.properties = props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,12 +88,16 @@ export default class JsonSchema extends BaseComponent {
|
||||||
names.forEach(el => {
|
names.forEach(el => {
|
||||||
el.style.minWidth = maxWidth + 'px';
|
el.style.minWidth = maxWidth + 'px';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let discrValues = this.element.querySelector('tabs ul');
|
||||||
|
if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
injectPropData(prop, propData) {
|
injectPropData(prop, propData) {
|
||||||
propData._name = prop;
|
propData._name = prop;
|
||||||
propData.isRequired = this.requiredMap[prop];
|
propData.isRequired = this.requiredMap[prop];
|
||||||
propData._displayType = propData.type;
|
propData._displayType = propData.type;
|
||||||
|
propData.isDiscriminator = (this.componentSchema.discriminator === prop);
|
||||||
if (propData.type === 'array') {
|
if (propData.type === 'array') {
|
||||||
let itemType = propData.items.type;
|
let itemType = propData.items.type;
|
||||||
let itemFormat = propData.items.format;
|
let itemFormat = propData.items.format;
|
||||||
|
|
|
@ -5,7 +5,7 @@ $cell-spacing: 25px;
|
||||||
$cell-padding: 10px;
|
$cell-padding: 10px;
|
||||||
$bullet-margin: 10px;
|
$bullet-margin: 10px;
|
||||||
$line-border: $lines-width solid $tree-lines-color;
|
$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;
|
$param-name-height: 20px;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin;
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -$lines-width;
|
left: -$lines-width - 1px;
|
||||||
border-left: $line-border-erase;
|
border-left: $line-border-erase;
|
||||||
top: ($param-name-height/2) + $cell-padding + $lines-width;
|
top: ($param-name-height/2) + $cell-padding + $lines-width;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -170,25 +170,36 @@ $array-marker-line-height: 1.5;
|
||||||
height: ($param-name-height/2) + $cell-padding;
|
height: ($param-name-height/2) + $cell-padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discriminator {
|
.param.discriminator {
|
||||||
margin-top: 1em;
|
> 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 {
|
:host tabs li {
|
||||||
padding: 0.2em 0;
|
margin: 0.2em 0.5em 0.2em 0;
|
||||||
margin-right: 1em;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: green;
|
border: 0;
|
||||||
|
color: white;
|
||||||
&:before, &:after {
|
padding: 0 15px;
|
||||||
content: '"';
|
border-radius: 10px;
|
||||||
}
|
background-color: #8A9094;
|
||||||
|
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-bottom: 2px solid $tree-lines-color;
|
background-color: $headers-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ export class BaseComponent {
|
||||||
this.componentSchema = schema;
|
this.componentSchema = schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
joinAllOf(schema = this.componentSchema) {
|
joinAllOf(schema = this.componentSchema, opts) {
|
||||||
var self = this;
|
var self = this;
|
||||||
function merge(into, schemas) {
|
function merge(into, schemas) {
|
||||||
if (into.required || into.properties) {
|
if (into.required || into.properties) {
|
||||||
|
@ -134,6 +134,7 @@ export class BaseComponent {
|
||||||
into.required = [];
|
into.required = [];
|
||||||
into.properties = {};
|
into.properties = {};
|
||||||
for (let subSchema of schemas) {
|
for (let subSchema of schemas) {
|
||||||
|
if (opts && opts.omitParent && subSchema.discriminator) continue;
|
||||||
|
|
||||||
// TODO: add support for merge array schemas
|
// TODO: add support for merge array schemas
|
||||||
if (typeof subSchema !== 'object' || subSchema.type !== 'object') {
|
if (typeof subSchema !== 'object' || subSchema.type !== 'object') {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user