From 06f372d1a800eeb02eddd652a30ec68ecc7fe95b Mon Sep 17 00:00:00 2001 From: Craig Larrabee Date: Mon, 28 Aug 2017 10:52:09 -0600 Subject: [PATCH] Tied schema dropdown to request/response schema samples --- lib/components/JsonSchema/json-schema-lazy.ts | 2 + lib/components/JsonSchema/json-schema.ts | 10 ++- lib/components/Operation/operation.ts | 5 +- .../RequestSamples/request-samples.html | 4 +- .../ResponsesList/responses-list.html | 2 +- .../ResponsesSamples/responses-samples.html | 2 +- lib/components/SchemaSample/schema-sample.ts | 75 +++++++++++++------ lib/services/index.ts | 1 + lib/services/schema-changer.service.ts | 20 +++++ 9 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 lib/services/schema-changer.service.ts diff --git a/lib/components/JsonSchema/json-schema-lazy.ts b/lib/components/JsonSchema/json-schema-lazy.ts index c3a81bb1..907a1e3d 100644 --- a/lib/components/JsonSchema/json-schema-lazy.ts +++ b/lib/components/JsonSchema/json-schema-lazy.ts @@ -24,6 +24,8 @@ export class JsonSchemaLazy implements OnDestroy, OnInit, AfterViewInit { @Input() nestOdd: boolean; @Input() childFor: string; @Input() isArray: boolean; + @Input() responseCode:string; + disableLazy: boolean = false; loaded: boolean = false; constructor(private specMgr:SpecManager, private location:ViewContainerRef, private elementRef:ElementRef, diff --git a/lib/components/JsonSchema/json-schema.ts b/lib/components/JsonSchema/json-schema.ts index e514b79b..8157ff25 100644 --- a/lib/components/JsonSchema/json-schema.ts +++ b/lib/components/JsonSchema/json-schema.ts @@ -12,8 +12,7 @@ import { Component, import { BaseSearchableComponent, SpecManager } from '../base'; import { SchemaNormalizer, SchemaHelper, AppStateService, OptionsService } from '../../services/'; import { JsonPointer, DescendantInfo } from '../../utils/'; -import { Zippy } from '../../shared/components'; -import { JsonSchemaLazy } from './json-schema-lazy'; +import {SchemaChangerService} from "../../services/schema-changer.service"; @Component({ selector: 'json-schema', @@ -28,6 +27,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit { @Input() nestOdd: boolean; @Input() childFor: string; @Input() isRequestSchema: boolean; + @Input() responseCode: string; schema: any = {}; activeDescendant:any = {}; @@ -44,7 +44,8 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit { private _renderer: Renderer, private cdr: ChangeDetectorRef, private _elementRef: ElementRef, - private optionsService: OptionsService) { + private optionsService: OptionsService, + private _schemaChanger: SchemaChangerService) { super(specMgr, app); this.normalizer = new SchemaNormalizer(specMgr); } @@ -55,6 +56,9 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit { selectDescendantByIdx(idx) { this.selectDescendant(this.descendants[idx]); + if (this.descendants[idx]) { + this._schemaChanger.announceDescendantChange(idx, this.descendants[idx].name, this.isRequestSchema ? true : false, this.responseCode); + } } selectDescendant(activeDescendant: DescendantInfo) { diff --git a/lib/components/Operation/operation.ts b/lib/components/Operation/operation.ts index dc86e7e6..e21a507f 100644 --- a/lib/components/Operation/operation.ts +++ b/lib/components/Operation/operation.ts @@ -3,7 +3,7 @@ import { Input, HostBinding, Component, OnInit, ChangeDetectionStrategy, Element import JsonPointer from '../../utils/JsonPointer'; import { BaseComponent, SpecManager } from '../base'; import { SchemaHelper } from '../../services/schema-helper.service'; -import { OptionsService, MenuService } from '../../services/'; +import { OptionsService, MenuService, SchemaChangerService } from '../../services/'; import { SwaggerBodyParameter } from '../../utils/swagger-typings'; export interface OperationInfo { @@ -27,7 +27,8 @@ export interface OperationInfo { selector: 'operation', templateUrl: './operation.html', styleUrls: ['./operation.css'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [SchemaChangerService] }) export class Operation extends BaseComponent implements OnInit { @Input() pointer :string; diff --git a/lib/components/RequestSamples/request-samples.html b/lib/components/RequestSamples/request-samples.html index 8f4956cd..cd9f0608 100644 --- a/lib/components/RequestSamples/request-samples.html +++ b/lib/components/RequestSamples/request-samples.html @@ -1,8 +1,8 @@
Request samples
- + - +
diff --git a/lib/components/ResponsesList/responses-list.html b/lib/components/ResponsesList/responses-list.html index d046d43e..23a4ae1f 100644 --- a/lib/components/ResponsesList/responses-list.html +++ b/lib/components/ResponsesList/responses-list.html @@ -21,6 +21,6 @@ Response Schema + pointer="{{response.schema ? response.pointer + '/schema' : null}}" [responseCode]="response.code"> diff --git a/lib/components/ResponsesSamples/responses-samples.html b/lib/components/ResponsesSamples/responses-samples.html index 1b370272..7b56b1db 100644 --- a/lib/components/ResponsesSamples/responses-samples.html +++ b/lib/components/ResponsesSamples/responses-samples.html @@ -2,6 +2,6 @@ - + diff --git a/lib/components/SchemaSample/schema-sample.ts b/lib/components/SchemaSample/schema-sample.ts index 4bbbe4d9..e0ff92b2 100644 --- a/lib/components/SchemaSample/schema-sample.ts +++ b/lib/components/SchemaSample/schema-sample.ts @@ -1,12 +1,15 @@ 'use strict'; -import { Component, ElementRef, Input, ChangeDetectionStrategy, OnInit } from '@angular/core'; +import {Component, ElementRef, Input, ChangeDetectionStrategy, OnInit, ChangeDetectorRef} from '@angular/core'; import * as OpenAPISampler from 'openapi-sampler'; import JsonPointer from '../../utils/JsonPointer'; -import { BaseComponent, SpecManager } from '../base'; -import { SchemaNormalizer } from '../../services/schema-normalizer.service'; -import { getJsonLikeSample, getXmlLikeSample, getTextLikeSample } from '../../utils/helpers'; +import {BaseComponent, SpecManager} from '../base'; +import {SchemaNormalizer} from '../../services/schema-normalizer.service'; +import {getJsonLikeSample, getXmlLikeSample, getTextLikeSample} from '../../utils/helpers'; + +import {Subscription} from 'rxjs/Subscription'; +import {SchemaChangerService} from "../../services/schema-changer.service"; @Component({ selector: 'schema-sample', @@ -15,8 +18,11 @@ import { getJsonLikeSample, getXmlLikeSample, getTextLikeSample } from '../../ut changeDetection: ChangeDetectionStrategy.OnPush }) export class SchemaSample extends BaseComponent implements OnInit { - @Input() pointer:string; - @Input() skipReadOnly:boolean; + @Input() pointer: string; + @Input() skipReadOnly: boolean; + @Input() subscription: Subscription; + @Input() isRequestSample: boolean; + @Input() responseCode: string; element: any; sample: any; @@ -24,18 +30,36 @@ export class SchemaSample extends BaseComponent implements OnInit { textSample: string; enableButtons: boolean = false; - private _normalizer:SchemaNormalizer; + private _normalizer: SchemaNormalizer; - constructor(specMgr:SpecManager, elementRef:ElementRef) { + constructor(specMgr: SpecManager, + elementRef: ElementRef, + private _schemaChanger: SchemaChangerService, + private _cdRef: ChangeDetectorRef) { super(specMgr); this.element = elementRef.nativeElement; this._normalizer = new SchemaNormalizer(specMgr); + this.subscription = this._schemaChanger.selectedDescendantChanged$.subscribe( + descendantInfo => { + this.selectDescendant(descendantInfo.idx, descendantInfo.name, descendantInfo.isRequestSchema, descendantInfo.responseCode); + _cdRef.detectChanges(); + }); } init() { + this.selectDescendant(0, null, this.isRequestSample, this.responseCode); + } + + selectDescendant(descendantIdx, descendantName, isRequestSchema, responseCodeIn) { + this.componentSchema = this.specMgr.byPointer(this.pointer || ''); + if ((!this.componentSchema) || + (isRequestSchema !== this.isRequestSample) || + (responseCodeIn !== this.responseCode)) { + return; + } this.bindEvents(); - let base:any = this.componentSchema; + let base: any = this.componentSchema; let sample, xmlSample; // got pointer not directly to the schema but e.g. to the response obj @@ -46,8 +70,8 @@ export class SchemaSample extends BaseComponent implements OnInit { } // Support x-examples, allowing requests to specify an example. - let examplePointer:string = JsonPointer.join(JsonPointer.dirName(this.pointer), 'x-examples'); - let requestExamples:any = this.specMgr.byPointer(examplePointer); + let examplePointer: string = JsonPointer.join(JsonPointer.dirName(this.pointer), 'x-examples'); + let requestExamples: any = this.specMgr.byPointer(examplePointer); if (requestExamples) { base.examples = requestExamples; } @@ -55,6 +79,10 @@ export class SchemaSample extends BaseComponent implements OnInit { this.xmlSample = base.examples && getXmlLikeSample(base.examples); this.textSample = base.examples && getTextLikeSample(base.examples); + if (this.fromCache()) { + this.initButtons(); + return; + } let jsonLikeSample = base.examples && getJsonLikeSample(base.examples); if (jsonLikeSample) { sample = jsonLikeSample; @@ -67,22 +95,23 @@ export class SchemaSample extends BaseComponent implements OnInit { if (discriminator) { let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer, this.componentSchema); if (descendants.length) { - // TODO: sync up with dropdown - selectedDescendant = descendants[0]; - let descSchema = this.specMgr.getDescendant(selectedDescendant, this.componentSchema); - this.componentSchema = this._normalizer.normalize(Object.assign({}, descSchema), selectedDescendant.$ref, - {omitParent: false}); + selectedDescendant = descendants[descendantIdx]; + //use this block to ignore lazy loaded dropdowns for now + if (descendantName == null || + (selectedDescendant && selectedDescendant.name === descendantName)) { + let descSchema = this.specMgr.getDescendant(selectedDescendant, this.componentSchema); + this.componentSchema = this._normalizer.normalize(Object.assign({}, descSchema), selectedDescendant.$ref, + {omitParent: false}); + } else { + return; + } } } - if (this.fromCache()) { - this.initButtons(); - return; - } try { sample = OpenAPISampler.sample(this.componentSchema, { skipReadOnly: this.skipReadOnly }); - } catch(e) { + } catch (e) { // no sample available } if (selectedDescendant) { @@ -153,4 +182,8 @@ export class SchemaSample extends BaseComponent implements OnInit { ngOnInit() { this.preinit(); } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } } diff --git a/lib/services/index.ts b/lib/services/index.ts index 7e26d9eb..b29503f8 100644 --- a/lib/services/index.ts +++ b/lib/services/index.ts @@ -10,6 +10,7 @@ export * from './schema-helper.service'; export * from './warnings.service'; export * from './search.service'; +export * from './schema-changer.service'; export * from './component-parser.service'; export * from './content-projector.service'; export * from './marker.service'; diff --git a/lib/services/schema-changer.service.ts b/lib/services/schema-changer.service.ts new file mode 100644 index 00000000..3fd3172e --- /dev/null +++ b/lib/services/schema-changer.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; +import {DescendantInfo} from "../utils/spec-manager"; + + +@Injectable() +export class SchemaChangerService { + + // Observable descendant sources + private selectedDescendantSource = new Subject(); + + // Observable descendant streams + selectedDescendantChanged$ = this.selectedDescendantSource.asObservable(); + + // Service message commands + announceDescendantChange(idx: string, descendantName: string, isRequestSchema: boolean, responseCode: string) { + this.selectedDescendantSource.next({idx:idx, name:descendantName, isRequestSchema:isRequestSchema, responseCode:responseCode}); + } + +} \ No newline at end of file