diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html
index dd6441a4..7ba2f8a1 100644
--- a/lib/components/JsonSchema/json-schema.html
+++ b/lib/components/JsonSchema/json-schema.html
@@ -84,7 +84,7 @@
-
+
diff --git a/lib/components/JsonSchema/json-schema.ts b/lib/components/JsonSchema/json-schema.ts
index a4de8c8f..44b5f27b 100644
--- a/lib/components/JsonSchema/json-schema.ts
+++ b/lib/components/JsonSchema/json-schema.ts
@@ -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;
- // @ViewChildren(forwardRef(() => JsonSchemaLazy)) childSchemas: QueryList;
+ 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();
}
diff --git a/lib/services/search.service.ts b/lib/services/search.service.ts
index 9ca7c406..4888292f 100644
--- a/lib/services/search.service.ts
+++ b/lib/services/search.service.ts
@@ -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,
diff --git a/lib/shared/components/DropDown/drop-down.ts b/lib/shared/components/DropDown/drop-down.ts
index 5e3e920b..a89f3eba 100644
--- a/lib/shared/components/DropDown/drop-down.ts
+++ b/lib/shared/components/DropDown/drop-down.ts
@@ -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();
}
diff --git a/lib/utils/spec-manager.ts b/lib/utils/spec-manager.ts
index d465b026..9fea813c 100644
--- a/lib/utils/spec-manager.ts
+++ b/lib/utils/spec-manager.ts
@@ -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