mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
Index and search inside discriminator
This commit is contained in:
parent
86f3a895a3
commit
6e13acbc64
|
@ -84,7 +84,7 @@
|
|||
</div>
|
||||
<div class="param-description" [innerHtml]="prop.description | marked"></div>
|
||||
<div class="discriminator-info" *ngIf="prop.isDiscriminator">
|
||||
<drop-down (change)="selectDescendant($event)">
|
||||
<drop-down (change)="selectDescendantByIdx($event)" [active]="activeDescendant.idx">
|
||||
<option *ngFor="let descendant of descendants; let i=index"
|
||||
[value]="i" [attr.selected]="descendant.active ? '' : null" >{{descendant.name}}</option>
|
||||
</drop-down>
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Component,
|
|||
|
||||
import { BaseSearchableComponent, SpecManager } from '../base';
|
||||
import { SchemaNormalizer, SchemaHelper, AppStateService } from '../../services/';
|
||||
import { JsonPointer } from '../../utils/';
|
||||
import { JsonPointer, DescendantInfo } from '../../utils/';
|
||||
import { Zippy } from '../../shared/components';
|
||||
import { JsonSchemaLazy } from './json-schema-lazy';
|
||||
|
||||
|
@ -36,10 +36,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
properties: any;
|
||||
_isArray: boolean;
|
||||
normalizer: SchemaNormalizer;
|
||||
descendants: any;
|
||||
|
||||
// @ViewChildren(Zippy) childZippies: QueryList<Zippy>;
|
||||
// @ViewChildren(forwardRef(() => JsonSchemaLazy)) childSchemas: QueryList<JsonSchemaLazy>;
|
||||
descendants: DescendantInfo[];
|
||||
|
||||
constructor(
|
||||
specMgr:SpecManager,
|
||||
|
@ -55,8 +52,11 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
return this.schema._pointer || this.pointer;
|
||||
}
|
||||
|
||||
selectDescendant(idx) {
|
||||
let activeDescendant = this.descendants[idx];
|
||||
selectDescendantByIdx(idx) {
|
||||
this.selectDescendant(this.descendants[idx]);
|
||||
}
|
||||
|
||||
selectDescendant(activeDescendant: DescendantInfo) {
|
||||
if (!activeDescendant || activeDescendant.active) return;
|
||||
this.descendants.forEach(d => {
|
||||
d.active = false;
|
||||
|
@ -69,6 +69,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
this.schema = this.normalizer.normalize(this.schema, this.normPointer,
|
||||
{resolved: true});
|
||||
this.preprocessSchema();
|
||||
this.activeDescendant = activeDescendant;
|
||||
}
|
||||
|
||||
initDescendants() {
|
||||
|
@ -91,7 +92,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
return enumOrder[a.name] > enumOrder[b.name] ? 1 : -1;
|
||||
});
|
||||
}
|
||||
this.selectDescendant(0);
|
||||
this.selectDescendantByIdx(0);
|
||||
}
|
||||
|
||||
init() {
|
||||
|
@ -154,6 +155,21 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
return idx;
|
||||
}
|
||||
|
||||
findDescendantWithField(fieldName: string): DescendantInfo {
|
||||
let res: DescendantInfo;
|
||||
for (let descendantInfo of this.descendants) {
|
||||
let schema = this.specMgr.getDescendant(descendantInfo, this.schema);
|
||||
this.normalizer.reset();
|
||||
schema = this.normalizer.normalize(schema, this.normPointer,
|
||||
{resolved: true});
|
||||
if (schema.properties && schema.properties[fieldName]) {
|
||||
res = descendantInfo;
|
||||
break;
|
||||
};
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
ensureSearchIsShown(ptr: string) {
|
||||
if (ptr.startsWith(this.absolutePointer)) {
|
||||
let props = this.properties;
|
||||
|
@ -164,8 +180,12 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
|||
propName = relative[1];
|
||||
}
|
||||
let prop = props.find(p => p._name === propName);
|
||||
if (!prop || prop.isTrivial) return;
|
||||
prop.expanded = true;
|
||||
if (!prop) {
|
||||
let d = this.findDescendantWithField(propName);
|
||||
this.selectDescendant(d);
|
||||
prop = this.properties.find(p => p._name === propName);
|
||||
}
|
||||
if (prop && !prop.isTrivial) prop.expanded = true;
|
||||
this.cdr.markForCheck();
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ export class SearchService {
|
|||
}
|
||||
|
||||
index(element: IndexElement) {
|
||||
// don't reindex same pointers (for discriminator)
|
||||
if (store[element.pointer]) return;
|
||||
index.add(element);
|
||||
store[element.pointer] = element;
|
||||
}
|
||||
|
@ -117,7 +119,8 @@ export class SearchService {
|
|||
let schema = _schema;
|
||||
let title = name;
|
||||
|
||||
schema = this.normalizer.normalize(schema, absolutePointer);
|
||||
this.normalizer.reset();
|
||||
schema = this.normalizer.normalize(schema, schema._pointer || absolutePointer);
|
||||
|
||||
let body = schema.description; // TODO: defaults, examples, etc...
|
||||
|
||||
|
@ -126,6 +129,14 @@ export class SearchService {
|
|||
return;
|
||||
}
|
||||
|
||||
if (schema.discriminator && !schema['x-derived-from']) {
|
||||
let derived = this.spec.findDerivedDefinitions(schema._pointer, schema);
|
||||
for (let defInfo of derived ) {
|
||||
let subSpec = this.spec.getDescendant(defInfo, schema);
|
||||
this.indexSchema(subSpec, '', absolutePointer, menuPointer);
|
||||
}
|
||||
}
|
||||
|
||||
this.index({
|
||||
pointer: absolutePointer,
|
||||
menuId: menuPointer,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
import { Component, EventEmitter, ElementRef, Output, AfterContentInit } from '@angular/core';
|
||||
import { Component, EventEmitter, ElementRef, Output, Input, AfterContentInit, OnChanges } from '@angular/core';
|
||||
import * as DropKick from 'dropkickjs';
|
||||
|
||||
@Component({
|
||||
|
@ -8,8 +8,9 @@ import * as DropKick from 'dropkickjs';
|
|||
templateUrl: 'drop-down.html',
|
||||
styleUrls: ['./drop-down.css']
|
||||
})
|
||||
export class DropDown implements AfterContentInit {
|
||||
export class DropDown implements AfterContentInit, OnChanges {
|
||||
@Output() change = new EventEmitter();
|
||||
@Input() active: string;
|
||||
elem: any;
|
||||
inst: any;
|
||||
constructor(elem:ElementRef) {
|
||||
|
@ -24,6 +25,12 @@ export class DropDown implements AfterContentInit {
|
|||
this.change.next(value);
|
||||
}
|
||||
|
||||
ngOnChanges(ch) {
|
||||
if (ch.active.currentValue) {
|
||||
this.inst && this.inst.select(ch.active.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.inst.dispose();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@ function getDiscriminator(obj) {
|
|||
return obj.discriminator || obj['x-extendedDiscriminator'];
|
||||
}
|
||||
|
||||
export interface DescendantInfo {
|
||||
$ref: string;
|
||||
name: string;
|
||||
active?: boolean;
|
||||
idx: number;
|
||||
}
|
||||
|
||||
export class SpecManager {
|
||||
public _schema: any = {};
|
||||
public apiUrl: string;
|
||||
|
@ -163,7 +170,7 @@ export class SpecManager {
|
|||
return tagsMap;
|
||||
}
|
||||
|
||||
findDerivedDefinitions(defPointer, schema) {
|
||||
findDerivedDefinitions(defPointer: string, schema): DescendantInfo[] {
|
||||
let definition = schema || this.byPointer(defPointer);
|
||||
if (!definition) throw new Error(`Can't load schema at ${defPointer}`);
|
||||
if (!definition.discriminator && !definition['x-extendedDiscriminator']) return [];
|
||||
|
@ -201,12 +208,12 @@ export class SpecManager {
|
|||
}
|
||||
}
|
||||
|
||||
res.push({name: derivedName, $ref: `#/definitions/${defName}`});
|
||||
res.push({name: derivedName, $ref: `#/definitions/${defName}`, idx: res.length});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
getDescendant(descendant, componentSchema) {
|
||||
getDescendant(descendant:DescendantInfo, componentSchema:any) {
|
||||
let res;
|
||||
if (!getDiscriminator(componentSchema) && componentSchema.allOf) {
|
||||
// discriminator inherited from parents
|
||||
|
|
Loading…
Reference in New Issue
Block a user