Index and search inside discriminator

This commit is contained in:
Roman Hotsiy 2017-01-26 18:21:24 +02:00
parent 86f3a895a3
commit 6e13acbc64
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
5 changed files with 62 additions and 17 deletions

View File

@ -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>

View File

@ -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();
}

View File

@ -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,

View File

@ -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();
}

View File

@ -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